ip.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. #include <ip.h>
  12. #include "dat.h"
  13. #include "protos.h"
  14. typedef struct Hdr Hdr;
  15. struct Hdr
  16. {
  17. uint8_t vihl; /* Version and header length */
  18. uint8_t tos; /* Type of service */
  19. uint8_t length[2]; /* packet length */
  20. uint8_t id[2]; /* ip->identification */
  21. uint8_t frag[2]; /* Fragment information */
  22. uint8_t ttl; /* Time to live */
  23. uint8_t proto; /* Protocol */
  24. uint8_t cksum[2]; /* Header checksum */
  25. uint8_t src[4]; /* IP source */
  26. uint8_t dst[4]; /* IP destination */
  27. };
  28. enum
  29. {
  30. IPHDR = 20, /* sizeof(Iphdr) */
  31. IP_VER = 0x40, /* Using IP version 4 */
  32. IP_DF = 0x4000, /* Don't fragment */
  33. IP_MF = 0x2000, /* More fragments */
  34. };
  35. static Mux p_mux[] =
  36. {
  37. { "icmp", 1, },
  38. { "igmp", 2, },
  39. { "ggp", 3, },
  40. { "ip", 4, },
  41. { "st", 5, },
  42. { "tcp", 6, },
  43. { "ucl", 7, },
  44. { "egp", 8, },
  45. { "igp", 9, },
  46. { "bbn-rcc-mon", 10, },
  47. { "nvp-ii", 11, },
  48. { "pup", 12, },
  49. { "argus", 13, },
  50. { "emcon", 14, },
  51. { "xnet", 15, },
  52. { "chaos", 16, },
  53. { "udp", 17, },
  54. { "mux", 18, },
  55. { "dcn-meas", 19, },
  56. { "hmp", 20, },
  57. { "prm", 21, },
  58. { "xns-idp", 22, },
  59. { "trunk-1", 23, },
  60. { "trunk-2", 24, },
  61. { "leaf-1", 25, },
  62. { "leaf-2", 26, },
  63. { "rdp", 27, },
  64. { "irtp", 28, },
  65. { "iso-tp4", 29, },
  66. { "netblt", 30, },
  67. { "mfe-nsp", 31, },
  68. { "merit-inp", 32, },
  69. { "sep", 33, },
  70. { "3pc", 34, },
  71. { "idpr", 35, },
  72. { "xtp", 36, },
  73. { "ddp", 37, },
  74. { "idpr-cmtp", 38, },
  75. { "tp++", 39, },
  76. { "il", 40, },
  77. { "sip", 41, },
  78. { "sdrp", 42, },
  79. { "sip-sr", 43, },
  80. { "sip-frag", 44, },
  81. { "idrp", 45, },
  82. { "rsvp", 46, },
  83. { "gre", 47, },
  84. { "mhrp", 48, },
  85. { "bna", 49, },
  86. { "sipp-esp", 50, },
  87. { "sipp-ah", 51, },
  88. { "i-nlsp", 52, },
  89. { "swipe", 53, },
  90. { "nhrp", 54, },
  91. { "any", 61, },
  92. { "cftp", 62, },
  93. { "any", 63, },
  94. { "sat-expak", 64, },
  95. { "kryptolan", 65, },
  96. { "rvd", 66, },
  97. { "ippc", 67, },
  98. { "any", 68, },
  99. { "sat-mon", 69, },
  100. { "visa", 70, },
  101. { "ipcv", 71, },
  102. { "cpnx", 72, },
  103. { "cphb", 73, },
  104. { "wsn", 74, },
  105. { "pvp", 75, },
  106. { "br-sat-mon", 76, },
  107. { "sun-nd", 77, },
  108. { "wb-mon", 78, },
  109. { "wb-expak", 79, },
  110. { "iso-ip", 80, },
  111. { "vmtp", 81, },
  112. { "secure-vmtp", 82, },
  113. { "vines", 83, },
  114. { "ttp", 84, },
  115. { "nsfnet-igp", 85, },
  116. { "dgp", 86, },
  117. { "tcf", 87, },
  118. { "igrp", 88, },
  119. { "ospf", 89, },
  120. { "sprite-rpc", 90, },
  121. { "larp", 91, },
  122. { "mtp", 92, },
  123. { "ax.25", 93, },
  124. { "ipip", 94, },
  125. { "micp", 95, },
  126. { "scc-sp", 96, },
  127. { "etherip", 97, },
  128. { "encap", 98, },
  129. { "any", 99, },
  130. { "gmtp", 100, },
  131. { "rudp", 254, },
  132. { 0 }
  133. };
  134. enum
  135. {
  136. Os, /* source */
  137. Od, /* destination */
  138. Osd, /* source or destination */
  139. Ot, /* type */
  140. };
  141. static Field p_fields[] =
  142. {
  143. {"s", Fv4ip, Os, "source address", } ,
  144. {"d", Fv4ip, Od, "destination address", } ,
  145. {"a", Fv4ip, Osd, "source|destination address",} ,
  146. {"sd", Fv4ip, Osd, "source|destination address",} ,
  147. {"t", Fnum, Ot, "sub protocol number", } ,
  148. {0}
  149. };
  150. static void
  151. p_compile(Filter *f)
  152. {
  153. Mux *m;
  154. if(f->op == '='){
  155. compile_cmp(ip.name, f, p_fields);
  156. return;
  157. }
  158. for(m = p_mux; m->name != nil; m++)
  159. if(strcmp(f->s, m->name) == 0){
  160. f->pr = m->pr;
  161. f->ulv = m->val;
  162. f->subop = Ot;
  163. return;
  164. }
  165. sysfatal("unknown ip field or protocol: %s", f->s);
  166. }
  167. static int
  168. p_filter(Filter *f, Msg *m)
  169. {
  170. Hdr *h;
  171. if(m->pe - m->ps < IPHDR)
  172. return 0;
  173. h = (Hdr*)m->ps;
  174. m->ps += (h->vihl & 0xf) << 2;
  175. switch(f->subop){
  176. case Os:
  177. return NetL(h->src) == f->ulv;
  178. case Od:
  179. return NetL(h->dst) == f->ulv;
  180. case Osd:
  181. return NetL(h->src) == f->ulv || NetL(h->dst) == f->ulv;
  182. case Ot:
  183. return h->proto == f->ulv;
  184. }
  185. return 0;
  186. }
  187. static int
  188. p_seprint(Msg *m)
  189. {
  190. int f, len, hl;
  191. uint8_t *p;
  192. Hdr *h;
  193. if(m->pe - m->ps < IPHDR)
  194. return -1;
  195. h = (Hdr*)m->ps;
  196. /* next protocol, just dump unless this is the first fragment */
  197. m->pr = &dump;
  198. f = NetS(h->frag);
  199. if((f & ~(IP_DF|IP_MF)) == 0)
  200. demux(p_mux, h->proto, h->proto, m, &dump);
  201. /* truncate the message if there's extra */
  202. len = NetS(h->length);
  203. if(len < m->pe - m->ps)
  204. m->pe = m->ps + len;
  205. /* next header */
  206. hl = (h->vihl &0xf) << 2;
  207. m->p = seprint(m->p, m->e, "s=%V d=%V id=%4.4ux frag=%4.4ux ttl=%3d pr=%d ln=%d hl=%d",
  208. h->src, h->dst, NetS(h->id), NetS(h->frag), h->ttl, h->proto,
  209. NetS(h->length),
  210. (h->vihl & 0xf) << 2);
  211. m->ps += hl;
  212. p = (uint8_t *)(h + 1);
  213. if(p < m->ps){
  214. m->p = seprint(m->p, m->e, " opts=(");
  215. while(p < m->ps)
  216. m->p = seprint(m->p, m->e, "%.2ux", *p++);
  217. m->p = seprint(m->p, m->e, ")");
  218. }
  219. return 0;
  220. }
  221. Proto ip =
  222. {
  223. "ip",
  224. p_compile,
  225. p_filter,
  226. p_seprint,
  227. p_mux,
  228. "%lu",
  229. p_fields,
  230. defaultframer,
  231. };