eipconvtest.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. enum
  12. {
  13. Isprefix= 16,
  14. };
  15. uint8_t prefixvals[256] =
  16. {
  17. [0x00] 0 | Isprefix,
  18. [0x80] 1 | Isprefix,
  19. [0xC0] 2 | Isprefix,
  20. [0xE0] 3 | Isprefix,
  21. [0xF0] 4 | Isprefix,
  22. [0xF8] 5 | Isprefix,
  23. [0xFC] 6 | Isprefix,
  24. [0xFE] 7 | Isprefix,
  25. [0xFF] 8 | Isprefix,
  26. };
  27. uint8_t v4prefix[16] = {
  28. 0, 0, 0, 0,
  29. 0, 0, 0, 0,
  30. 0, 0, 0xff, 0xff,
  31. 0, 0, 0, 0
  32. };
  33. void
  34. hnputl(void *p, uint32_t v)
  35. {
  36. uint8_t *a;
  37. a = p;
  38. a[0] = v>>24;
  39. a[1] = v>>16;
  40. a[2] = v>>8;
  41. a[3] = v;
  42. }
  43. int
  44. eipconv(va_list *arg, Fconv *f)
  45. {
  46. char buf[8*5];
  47. static char *efmt = "%.2lux%.2lux%.2lux%.2lux%.2lux%.2lux";
  48. static char *ifmt = "%d.%d.%d.%d";
  49. uint8_t *p, ip[16];
  50. uint32_t *lp;
  51. uint16_t s;
  52. int i, j, n, eln, eli;
  53. switch(f->chr) {
  54. case 'E': /* Ethernet address */
  55. p = va_arg(*arg, uint8_t*);
  56. sprint(buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
  57. break;
  58. case 'I': /* Ip address */
  59. p = va_arg(*arg, uint8_t*);
  60. common:
  61. if(memcmp(p, v4prefix, 12) == 0)
  62. sprint(buf, ifmt, p[12], p[13], p[14], p[15]);
  63. else {
  64. /* find longest elision */
  65. eln = eli = -1;
  66. for(i = 0; i < 16; i += 2){
  67. for(j = i; j < 16; j += 2)
  68. if(p[j] != 0 || p[j+1] != 0)
  69. break;
  70. if(j > i && j - i > eln){
  71. eli = i;
  72. eln = j - i;
  73. }
  74. }
  75. /* print with possible elision */
  76. n = 0;
  77. for(i = 0; i < 16; i += 2){
  78. if(i == eli){
  79. n += sprint(buf+n, "::");
  80. i += eln;
  81. if(i >= 16)
  82. break;
  83. } else if(i != 0)
  84. n += sprint(buf+n, ":");
  85. s = (p[i]<<8) + p[i+1];
  86. n += sprint(buf+n, "%x", s);
  87. }
  88. }
  89. break;
  90. case 'i': /* v6 address as 4 longs */
  91. lp = va_arg(*arg, uint32_t*);
  92. for(i = 0; i < 4; i++)
  93. hnputl(ip+4*i, *lp++);
  94. p = ip;
  95. goto common;
  96. case 'V': /* v4 ip address */
  97. p = va_arg(*arg, uint8_t*);
  98. sprint(buf, ifmt, p[0], p[1], p[2], p[3]);
  99. break;
  100. case 'M': /* ip mask */
  101. p = va_arg(*arg, uint8_t*);
  102. /* look for a prefix mask */
  103. for(i = 0; i < 16; i++)
  104. if(p[i] != 0xff)
  105. break;
  106. if(i < 16){
  107. if((prefixvals[p[i]] & Isprefix) == 0)
  108. goto common;
  109. for(j = i+1; j < 16; j++)
  110. if(p[j] != 0)
  111. goto common;
  112. n = 8*i + (prefixvals[p[i]] & ~Isprefix);
  113. } else
  114. n = 8*16;
  115. /* got one, use /xx format */
  116. sprint(buf, "/%d", n);
  117. break;
  118. default:
  119. strcpy(buf, "(eipconv)");
  120. }
  121. strconv(buf, f);
  122. return sizeof(uint8_t*);
  123. }
  124. uint8_t testvec[11][16] =
  125. {
  126. { 0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 1,3,4,5, },
  127. { 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, },
  128. { 0xff,0xff,0x80,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, },
  129. { 0xff,0xff,0xff,0xc0, 0,0,0,0, 0,0,0,0, 0,0,0,0, },
  130. { 0xff,0xff,0xff,0xff, 0xe0,0,0,0, 0,0,0,0, 0,0,0,0, },
  131. { 0xff,0xff,0xff,0xff, 0xff,0xf0,0,0, 0,0,0,0, 0,0,0,0, },
  132. { 0xff,0xff,0xff,0xff, 0xff,0xff,0xf8,0, 0,0,0,0, 0,0,0,0, },
  133. { 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, },
  134. { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, },
  135. { 0,0,0,0, 0,0x11,0,0, 0,0,0,0, 0,0,0,0, },
  136. { 0,0,0,0x11, 0,0,0,0, 0,0,0,0, 0,0,0,0x12, },
  137. };
  138. void
  139. main(void)
  140. {
  141. int i;
  142. fmtinstall('I', eipconv);
  143. fmtinstall('M', eipconv);
  144. for(i = 0; i < 11; i++)
  145. print("%I\n%M\n", testvec[i], testvec[i]);
  146. exits(0);
  147. }