Split random number generation out into core/random.c, and create the
[people/xl0/gpxe.git] / src / core / misc.c
1 /**************************************************************************
2 MISC Support Routines
3 **************************************************************************/
4
5 #include "etherboot.h"
6 #include "console.h"
7 #include <stdlib.h>
8
9 /**************************************************************************
10 IPCHKSUM - Checksum IP Header
11 **************************************************************************/
12 uint16_t ipchksum(const void *data, unsigned long length)
13 {
14         unsigned long sum;
15         unsigned long i;
16         const uint8_t *ptr;
17
18         /* In the most straight forward way possible,
19          * compute an ip style checksum.
20          */
21         sum = 0;
22         ptr = data;
23         for(i = 0; i < length; i++) {
24                 unsigned long value;
25                 value = ptr[i];
26                 if (i & 1) {
27                         value <<= 8;
28                 }
29                 /* Add the new value */
30                 sum += value;
31                 /* Wrap around the carry */
32                 if (sum > 0xFFFF) {
33                         sum = (sum + (sum >> 16)) & 0xFFFF;
34                 }
35         }
36         return (~cpu_to_le16(sum)) & 0xFFFF;
37 }
38
39 uint16_t add_ipchksums(unsigned long offset, uint16_t sum, uint16_t new)
40 {
41         unsigned long checksum;
42         sum = ~sum & 0xFFFF;
43         new = ~new & 0xFFFF;
44         if (offset & 1) {
45                 /* byte swap the sum if it came from an odd offset 
46                  * since the computation is endian independant this
47                  * works.
48                  */
49                 new = bswap_16(new);
50         }
51         checksum = sum + new;
52         if (checksum > 0xFFFF) {
53                 checksum -= 0xFFFF;
54         }
55         return (~checksum) & 0xFFFF;
56 }
57
58 /**************************************************************************
59 SLEEP
60 **************************************************************************/
61 unsigned int sleep(unsigned int secs)
62 {
63         unsigned long tmo;
64
65         for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; ) {
66         }
67         return 0;
68 }
69
70 /**************************************************************************
71 INTERRUPTIBLE SLEEP
72 **************************************************************************/
73 void interruptible_sleep(int secs)
74 {
75         printf("<sleep>\n");
76         sleep(secs);
77 }
78
79 /**************************************************************************
80 STRCASECMP (not entirely correct, but this will do for our purposes)
81 **************************************************************************/
82 int strcasecmp(const char *a, const char *b)
83 {
84         while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
85         return((*a & ~0x20) - (*b & ~0x20));
86 }
87
88 /**************************************************************************
89 INET_ATON - Convert an ascii x.x.x.x to binary form
90 **************************************************************************/
91 int inet_aton ( const char *cp, struct in_addr *inp ) {
92         const char *p = cp;
93         const char *digits_start;
94         unsigned long ip = 0;
95         unsigned long val;
96         int j;
97         for(j = 0; j <= 3; j++) {
98                 digits_start = p;
99                 val = strtoul(p, ( char ** ) &p, 10);
100                 if ((p == digits_start) || (val > 255)) return 0;
101                 if ( ( j < 3 ) && ( *(p++) != '.' ) ) return 0;
102                 ip = (ip << 8) | val;
103         }
104         if ( *p == '\0' ) {
105                 inp->s_addr = htonl(ip);
106                 return 1;
107         }
108         return 0;
109 }
110
111 int isspace ( int c ) {
112         switch ( c ) {
113         case ' ':
114         case '\f':
115         case '\n':
116         case '\r':
117         case '\t':
118         case '\v':
119                 return 1;
120         default:
121                 return 0;
122         }
123 }
124
125 unsigned long strtoul ( const char *p, char **endp, int base ) {
126         unsigned long ret = 0;
127         unsigned int charval;
128
129         while ( isspace ( *p ) )
130                 p++;
131
132         if ( base == 0 ) {
133                 base = 10;
134                 if ( *p == '0' ) {
135                         p++;
136                         base = 8;
137                         if ( ( *p | 0x20 ) == 'x' ) {
138                                 p++;
139                                 base = 16;
140                         }
141                 }
142         }
143
144         while ( 1 ) {
145                 charval = *p;
146                 if ( charval >= 'a' ) {
147                         charval = ( charval - 'a' + 10 );
148                 } else if ( charval >= 'A' ) {
149                         charval = ( charval - 'A' + 10 );
150                 } else {
151                         charval = ( charval - '0' );
152                 }
153                 if ( charval >= ( unsigned int ) base )
154                         break;
155                 ret = ( ( ret * base ) + charval );
156                 p++;
157         }
158
159         if ( endp )
160                 *endp = ( char * ) p;
161
162         return ( ret );
163 }
164
165 /*
166  * Local variables:
167  *  c-basic-offset: 8
168  * End:
169  */