Mirror of :pserver:cvs@cvs.fefe.de:/cvs libowfat https://www.fefe.de/libowfat/
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.
 
 
 
 

89 lines
1.8 KiB

  1. #include "scan.h"
  2. #include "ip4.h"
  3. #include "ip6.h"
  4. /*
  5. * IPv6 addresses are really ugly to parse.
  6. * Syntax: (h = hex digit)
  7. * 1. hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh
  8. * 2. any number of 0000 may be abbreviated as "::", but only once
  9. * 3. The last two words may be written as IPv4 address
  10. */
  11. unsigned int scan_ip6(const char *s,char ip[16])
  12. {
  13. unsigned int i;
  14. unsigned int len=0;
  15. unsigned long u;
  16. char suffix[16];
  17. int prefixlen=0;
  18. int suffixlen=0;
  19. if ((i=scan_ip4(s,ip+12))) {
  20. for (len=0; len<12; ++len) ip[len]=V4mappedprefix[len];
  21. return i;
  22. }
  23. for (i=0; i<16; i++) ip[i]=0;
  24. for (;;) {
  25. if (*s == ':') {
  26. ++len;
  27. ++s;
  28. if (*s == ':') { /* Found "::", skip to part 2 */
  29. ++len;
  30. ++s;
  31. break;
  32. }
  33. }
  34. i = scan_xlong(s,&u);
  35. if (!i) return 0;
  36. if (prefixlen==12 && s[i]=='.') {
  37. /* the last 4 bytes may be written as IPv4 address */
  38. i=scan_ip4(s,ip+12);
  39. if (i)
  40. return i+len;
  41. else
  42. return 0;
  43. }
  44. ip[prefixlen++] = (u >> 8);
  45. ip[prefixlen++] = (u & 255);
  46. s += i; len += i;
  47. if (prefixlen==16)
  48. return len;
  49. }
  50. /* part 2, after "::" */
  51. for (;;) {
  52. if (*s == ':') {
  53. if (suffixlen==0)
  54. break;
  55. s++;
  56. len++;
  57. } else if (suffixlen)
  58. break;
  59. i = scan_xlong(s,&u);
  60. if (!i) {
  61. if (suffixlen)
  62. --len;
  63. break;
  64. }
  65. if (suffixlen+prefixlen<=12 && s[i]=='.') {
  66. int j=scan_ip4(s,suffix+suffixlen);
  67. if (j) {
  68. suffixlen+=4;
  69. len+=j;
  70. break;
  71. } else
  72. prefixlen=12-suffixlen; /* make end-of-loop test true */
  73. }
  74. suffix[suffixlen++] = (u >> 8);
  75. suffix[suffixlen++] = (u & 255);
  76. s += i; len += i;
  77. if (prefixlen+suffixlen==16)
  78. break;
  79. }
  80. for (i=0; i<suffixlen; i++)
  81. ip[16-suffixlen+i] = suffix[i];
  82. return len;
  83. }