ospf.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ip.h>
  4. #include <libsec.h>
  5. #include "dat.h"
  6. #include "protos.h"
  7. /*
  8. * OSPF packets
  9. */
  10. typedef struct Ospfpkt Ospfpkt;
  11. struct Ospfpkt
  12. {
  13. uchar version;
  14. uchar type;
  15. uchar length[2];
  16. uchar router[4];
  17. uchar area[4];
  18. uchar sum[2];
  19. uchar autype[2];
  20. uchar auth[8];
  21. uchar data[1];
  22. };
  23. #define OSPF_HDRSIZE 24
  24. enum
  25. {
  26. OSPFhello= 1,
  27. OSPFdd= 2,
  28. OSPFlsrequest= 3,
  29. OSPFlsupdate= 4,
  30. OSPFlsack= 5,
  31. };
  32. char *ospftype[] = {
  33. [OSPFhello] "hello",
  34. [OSPFdd] "data definition",
  35. [OSPFlsrequest] "link state request",
  36. [OSPFlsupdate] "link state update",
  37. [OSPFlsack] "link state ack",
  38. };
  39. char*
  40. ospfpkttype(int x)
  41. {
  42. static char type[16];
  43. if(x > 0 && x <= OSPFlsack)
  44. return ospftype[x];
  45. sprint(type, "type %d", x);
  46. return type;
  47. }
  48. char*
  49. ospfauth(Ospfpkt *ospf)
  50. {
  51. static char auth[100];
  52. switch(ospf->type){
  53. case 0:
  54. return "no authentication";
  55. case 1:
  56. sprint(auth, "password(%8.8ux %8.8ux)", NetL(ospf->auth),
  57. NetL(ospf->auth+4));
  58. break;
  59. case 2:
  60. sprint(auth, "crypto(plen %d id %d dlen %d)", NetS(ospf->auth),
  61. ospf->auth[2], ospf->auth[3]);
  62. break;
  63. default:
  64. sprint(auth, "auth%d(%8.8ux %8.8ux)", NetS(ospf->autype), NetL(ospf->auth),
  65. NetL(ospf->auth+4));
  66. }
  67. return auth;
  68. }
  69. typedef struct Ospfhello Ospfhello;
  70. struct Ospfhello
  71. {
  72. uchar mask[4];
  73. uchar interval[2];
  74. uchar options;
  75. uchar pri;
  76. uchar deadint[4];
  77. uchar designated[4];
  78. uchar bdesignated[4];
  79. uchar neighbor[1];
  80. };
  81. char*
  82. seprintospfhello(char *p, char *e, void *a, int)
  83. {
  84. Ospfhello *h = a;
  85. return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux deadt %d designated %V bdesignated %V)",
  86. ospftype[OSPFhello],
  87. h->mask, NetS(h->interval), h->options, h->pri,
  88. NetL(h->deadint), h->designated, h->bdesignated);
  89. }
  90. enum
  91. {
  92. LSARouter= 1,
  93. LSANetwork= 2,
  94. LSASummN= 3,
  95. LSASummR= 4,
  96. LSAASext= 5
  97. };
  98. char *lsatype[] = {
  99. [LSARouter] "Router LSA",
  100. [LSANetwork] "Network LSA",
  101. [LSASummN] "Summary LSA (Network)",
  102. [LSASummR] "Summary LSA (Router)",
  103. [LSAASext] "LSA AS external",
  104. };
  105. char*
  106. lsapkttype(int x)
  107. {
  108. static char type[16];
  109. if(x > 0 && x <= LSAASext)
  110. return lsatype[x];
  111. sprint(type, "type %d", x);
  112. return type;
  113. }
  114. /* OSPF Link State Advertisement Header */
  115. /* rfc2178 section 12.1 */
  116. /* data of Ospfpkt point to a 4-uchar value that is the # of LSAs */
  117. struct OspfLSAhdr {
  118. uchar lsage[2];
  119. uchar options; /* 0x2=stub area, 0x1=TOS routing capable */
  120. uchar lstype; /* 1=Router-LSAs
  121. * 2=Network-LSAs
  122. * 3=Summary-LSAs (to network)
  123. * 4=Summary-LSAs (to AS boundary routers)
  124. * 5=AS-External-LSAs
  125. */
  126. uchar lsid[4];
  127. uchar advtrt[4];
  128. uchar lsseqno[4];
  129. uchar lscksum[2];
  130. uchar lsalen[2]; /* includes the 20 byte lsa header */
  131. };
  132. struct Ospfrt {
  133. uchar linkid[4];
  134. uchar linkdata[4];
  135. uchar typ;
  136. uchar numtos;
  137. uchar metric[2];
  138. };
  139. struct OspfrtLSA {
  140. struct OspfLSAhdr hdr;
  141. uchar netmask[4];
  142. };
  143. struct OspfntLSA {
  144. struct OspfLSAhdr hdr;
  145. uchar netmask[4];
  146. uchar attrt[4];
  147. };
  148. /* Summary Link State Advertisement info */
  149. struct Ospfsumm {
  150. uchar flag; /* always zero */
  151. uchar metric[3];
  152. };
  153. struct OspfsummLSA {
  154. struct OspfLSAhdr hdr;
  155. uchar netmask[4];
  156. struct Ospfsumm lsa;
  157. };
  158. /* AS external Link State Advertisement info */
  159. struct OspfASext {
  160. uchar flag; /* external */
  161. uchar metric[3];
  162. uchar fwdaddr[4];
  163. uchar exrttag[4];
  164. };
  165. struct OspfASextLSA {
  166. struct OspfLSAhdr hdr;
  167. uchar netmask[4];
  168. struct OspfASext lsa;
  169. };
  170. /* OSPF Link State Update Packet */
  171. struct OspfLSupdpkt {
  172. uchar lsacnt[4];
  173. union {
  174. uchar hdr[1];
  175. struct OspfrtLSA rt[1];
  176. struct OspfntLSA nt[1];
  177. struct OspfsummLSA sum[1];
  178. struct OspfASextLSA as[1];
  179. };
  180. };
  181. char*
  182. seprintospflsaheader(char *p, char *e, struct OspfLSAhdr *h)
  183. {
  184. return seprint(p, e, "age %d opt %ux type %ux lsid %V adv_rt %V seqno %ux c %4.4ux l %d",
  185. NetS(h->lsage), h->options&0xff, h->lstype,
  186. h->lsid, h->advtrt, NetL(h->lsseqno), NetS(h->lscksum),
  187. NetS(h->lsalen));
  188. }
  189. /* OSPF Database Description Packet */
  190. struct OspfDDpkt {
  191. uchar intMTU[2];
  192. uchar options;
  193. uchar bits;
  194. uchar DDseqno[4];
  195. struct OspfLSAhdr hdr[1]; /* LSA headers... */
  196. };
  197. char*
  198. seprintospfdatadesc(char *p, char *e, void *a, int len)
  199. {
  200. int nlsa, i;
  201. struct OspfDDpkt *g;
  202. g = (struct OspfDDpkt *)a;
  203. nlsa = len/sizeof(struct OspfLSAhdr);
  204. for (i=0; i<nlsa; i++) {
  205. p = seprint(p, e, "lsa%d(", i);
  206. p = seprintospflsaheader(p, e, &(g->hdr[i]));
  207. p = seprint(p, e, ")");
  208. }
  209. return seprint(p, e, ")");
  210. }
  211. char*
  212. seprintospflsupdate(char *p, char *e, void *a, int len)
  213. {
  214. int nlsa, i;
  215. struct OspfLSupdpkt *g;
  216. struct OspfLSAhdr *h;
  217. g = (struct OspfLSupdpkt *)a;
  218. nlsa = NetL(g->lsacnt);
  219. h = (struct OspfLSAhdr *)(g->hdr);
  220. p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsupdate));
  221. switch(h->lstype) {
  222. case LSARouter:
  223. {
  224. /* struct OspfrtLSA *h;
  225. */
  226. }
  227. break;
  228. case LSANetwork:
  229. {
  230. struct OspfntLSA *h;
  231. for (i=0; i<nlsa; i++) {
  232. h = &(g->nt[i]);
  233. p = seprint(p, e, "lsa%d(", i);
  234. p = seprintospflsaheader(p, e, &(h->hdr));
  235. p = seprint(p, e, " mask %V attrt %V)",
  236. h->netmask, h->attrt);
  237. }
  238. }
  239. break;
  240. case LSASummN:
  241. case LSASummR:
  242. {
  243. struct OspfsummLSA *h;
  244. for (i=0; i<nlsa; i++) {
  245. h = &(g->sum[i]);
  246. p = seprint(p, e, "lsa%d(", i);
  247. p = seprintospflsaheader(p, e, &(h->hdr));
  248. p = seprint(p, e, " mask %V met %d)",
  249. h->netmask, Net3(h->lsa.metric));
  250. }
  251. }
  252. break;
  253. case LSAASext:
  254. {
  255. struct OspfASextLSA *h;
  256. for (i=0; i<nlsa; i++) {
  257. h = &(g->as[i]);
  258. p = seprint(p, e, " lsa%d(", i);
  259. p = seprintospflsaheader(p, e, &(h->hdr));
  260. p = seprint(p, e, " mask %V extflg %1.1ux met %d fwdaddr %V extrtflg %ux)",
  261. h->netmask, h->lsa.flag, Net3(h->lsa.metric),
  262. h->lsa.fwdaddr, NetL(h->lsa.exrttag));
  263. }
  264. }
  265. break;
  266. default:
  267. p = seprint(p, e, "Not an LS update, lstype %d ", h->lstype);
  268. p = seprint(p, e, " %.*H", len>64?64:len, a);
  269. break;
  270. }
  271. return seprint(p, e, ")");
  272. }
  273. char*
  274. seprintospflsack(char *p, char *e, void *a, int len)
  275. {
  276. int nlsa, i;
  277. struct OspfLSAhdr *h;
  278. h = (struct OspfLSAhdr *)a;
  279. nlsa = len/sizeof(struct OspfLSAhdr);
  280. p = seprint(p, e, "%d-%s(", nlsa, ospfpkttype(OSPFlsack));
  281. for (i=0; i<nlsa; i++) {
  282. p = seprint(p, e, " lsa%d(", i);
  283. p = seprintospflsaheader(p, e, &(h[i]));
  284. p = seprint(p, e, ")");
  285. }
  286. return seprint(p, e, ")");
  287. }
  288. static void
  289. p_compile(Filter *f)
  290. {
  291. sysfatal("unknown ospf field: %s", f->s);
  292. }
  293. static int
  294. p_filter(Filter *, Msg *)
  295. {
  296. return 0;
  297. }
  298. int
  299. p_seprint(Msg *m)
  300. {
  301. Ospfpkt *ospf;
  302. int len, x;
  303. char *p, *e;
  304. len = m->pe - m->ps;
  305. if(len < OSPF_HDRSIZE)
  306. return -1;
  307. p = m->p;
  308. e = m->e;
  309. /* adjust packet size */
  310. ospf = (Ospfpkt*)m->ps;
  311. x = NetS(ospf->length);
  312. if(x < len)
  313. return -1;
  314. x -= OSPF_HDRSIZE;
  315. p = seprint(p, e, "ver=%d type=%d len=%d r=%V a=%V c=%4.4ux %s ",
  316. ospf->version, ospf->type, x,
  317. ospf->router, ospf->area, NetS(ospf->sum),
  318. ospfauth(ospf));
  319. switch (ospf->type) {
  320. case OSPFhello:
  321. p = seprintospfhello(p, e, ospf->data, x);
  322. break;
  323. case OSPFdd:
  324. p = seprintospfdatadesc(p, e, ospf->data, x);
  325. break;
  326. case OSPFlsrequest:
  327. p = seprint(p, e, " %s->", ospfpkttype(ospf->type));
  328. goto Default;
  329. case OSPFlsupdate:
  330. p = seprintospflsupdate(p, e, ospf->data, x);
  331. break;
  332. case OSPFlsack:
  333. p = seprintospflsack(p, e, ospf->data, x);
  334. break;
  335. default:
  336. Default:
  337. p = seprint(p, e, " data=%.*H", x>64?64:x, ospf->data);
  338. }
  339. m->p = p;
  340. m->pr = nil;
  341. return 0;
  342. }
  343. Proto ospf =
  344. {
  345. "ospf",
  346. p_compile,
  347. p_filter,
  348. p_seprint,
  349. nil,
  350. nil,
  351. nil,
  352. defaultframer,
  353. };