You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

misc.c 3.7KB

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