1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/time.h>
36 #include <sys/socket.h>
37 #include <sys/sockio.h>
38 #include <net/if.h>
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
41 #include <netinet/ip.h>
42 #include <netinet/if_ether.h>
43 #include <arpa/inet.h>
44 #include "snoop.h"
45 #include "snoop_ospf.h"
46 #include "snoop_ospf6.h"
47
48 extern char *dlc_header;
49 static char *sum_line;
50
51 char *ospf_types[] = {
52 "umd", /* 0 */
53 "Hello", /* 1 */
54 "DD", /* 2 */
55 "LSReq", /* 3 */
56 "LSUpd", /* 4 */
57 "LSAck", /* 5 */
58 };
59
60 static char *ospf_authtypes[] = {
61 "None", /* 0 */
62 "simple", /* 1 */
63 "md5", /* 2 */
64 };
65
66 const struct bits ospf_rla_flag_bits[] = {
67 { RLA_FLAG_B, "B" },
68 { RLA_FLAG_E, "E" },
69 { RLA_FLAG_V, "V" },
70 { RLA_FLAG_W, "W" },
71 { 0, NULL }
72 };
73
74 const struct bits ospf_db_flags_bits[] = {
75 { OSPF_DB_INIT, "I" },
76 { OSPF_DB_MORE, "M" },
77 { OSPF_DB_MASTER, "MS" },
78 { 0, NULL }
79 };
80
81 const struct bits ospf_option_bits[] = {
82 { OSPF_OPTION_T, "T" },
83 { OSPF_OPTION_E, "E" },
84 { OSPF_OPTION_MC, "MC" },
85 { 0, NULL }
86 };
87
88 static int interpret_ospf_hello(int, struct ospfhdr *, int);
89 static void ospf_print_ls_type(int, uint32_t, struct in_addr, struct in_addr);
90 static void interpret_ospf_lsa_hdr(int, struct lsa_hdr *);
91 static int interpret_ospf_lsa(int flags, struct lsa *lsa, uchar_t *);
92
93 char *
ospf_print_bits(const struct bits * bp,uchar_t options)94 ospf_print_bits(const struct bits *bp, uchar_t options)
95 {
96 static char bitstring[32];
97
98 bitstring[0] = '\0';
99 do {
100 if (options & bp->bit) {
101 strcat(bitstring, bp->str);
102 strcat(bitstring, "/");
103 }
104 } while ((++bp)->bit);
105
106 /* wipe out the trailing "/" */
107 bitstring[strlen(bitstring) - 1] = '\0';
108 return (bitstring);
109 }
110
111 char *
ospf_print_lsa_age(long age)112 ospf_print_lsa_age(long age)
113 {
114 long sec, mins, hour;
115 static char lsa_age[16];
116
117 sec = age % 60;
118 mins = (age / 60) % 60;
119 hour = age / 3600;
120 if (hour != 0)
121 snprintf(lsa_age, sizeof (lsa_age), "%u:%02u:%02u",
122 hour, mins, sec);
123 else if (mins != 0)
124 snprintf(lsa_age, sizeof (lsa_age), "%u:%02u", mins, sec);
125 else
126 snprintf(lsa_age, sizeof (lsa_age), "%u", sec);
127 return (lsa_age);
128 }
129
130 static int
interpret_ospf_hello(int flags,struct ospfhdr * op,int fraglen)131 interpret_ospf_hello(int flags, struct ospfhdr *op, int fraglen)
132 {
133 struct in_addr *nbr;
134 int j;
135
136 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_HELLO_HEADER_SIZE)
137 return (-1); /* truncated packet */
138
139 if (flags & F_SUM) {
140 if (op->ospf_hello.hello_dr.s_addr != 0) {
141 (void) sprintf(sum_line, "DR=%s ",
142 inet_ntoa(op->ospf_hello.hello_dr));
143 }
144 sum_line += strlen(sum_line);
145 if (op->ospf_hello.hello_bdr.s_addr != 0) {
146 (void) sprintf(sum_line, "BDR=%s ",
147 inet_ntoa(op->ospf_hello.hello_bdr));
148 }
149 sum_line += strlen(sum_line);
150 nbr = op->ospf_hello.hello_neighbor;
151 j = 0;
152 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) {
153 if ((uchar_t *)nbr + sizeof (struct in_addr) >
154 ((uchar_t *)op + fraglen))
155 return (-1); /* truncated */
156 j++;
157 ++nbr;
158 }
159 (void) sprintf(sum_line, "%d nbrs", j);
160 sum_line += strlen(sum_line);
161
162 }
163 if (flags & F_DTAIL) {
164 show_header("OSPF HELLO: ", "Hello Packet",
165 ntohs(op->ospf_len));
166 show_space();
167 (void) snprintf(get_line(0, 0), get_line_remain(),
168 "Options = %s", ospf_print_bits(ospf_option_bits,
169 op->ospf_hello.hello_options));
170 (void) snprintf(get_line(0, 0), get_line_remain(), "Mask = %s",
171 inet_ntoa(op->ospf_hello.hello_mask));
172 (void) snprintf(get_line(0, 0), get_line_remain(),
173 "Hello interval = %d",
174 ntohs(op->ospf_hello.hello_helloint));
175 (void) snprintf(get_line(0, 0), get_line_remain(),
176 "Priority = %d", op->ospf_hello.hello_priority);
177 (void) snprintf(get_line(0, 0), get_line_remain(),
178 "Dead interval = %u", ntohl(op->ospf_hello.hello_deadint));
179 if (op->ospf_hello.hello_dr.s_addr != 0) {
180 (void) snprintf(get_line(0, 0), get_line_remain(),
181 "Designated Router = %s",
182 inet_ntoa(op->ospf_hello.hello_dr));
183 }
184 if (op->ospf_hello.hello_bdr.s_addr != 0) {
185 (void) snprintf(get_line(0, 0), get_line_remain(),
186 "Backup Designated Router = %s",
187 inet_ntoa(op->ospf_hello.hello_bdr));
188 }
189 nbr = op->ospf_hello.hello_neighbor;
190 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) {
191 if ((uchar_t *)nbr + sizeof (struct in_addr) >
192 ((uchar_t *)op + fraglen))
193 return (-1); /* truncated */
194 (void) snprintf(get_line(0, 0), get_line_remain(),
195 "Neighbor: %s", inet_ntoa(*nbr));
196 ++nbr;
197 }
198 }
199 return (fraglen);
200 }
201
202 static void
ospf_print_ls_type(int flags,uint32_t ls_type,struct in_addr ls_stateid,struct in_addr ls_router)203 ospf_print_ls_type(int flags, uint32_t ls_type, struct in_addr ls_stateid,
204 struct in_addr ls_router)
205 {
206 switch (ls_type) {
207 case LS_TYPE_ROUTER:
208 if (flags & F_SUM) {
209 sprintf(sum_line, " rtr %s ", inet_ntoa(ls_router));
210 sum_line += strlen(sum_line);
211 }
212 if (flags & F_DTAIL) {
213 (void) snprintf(get_line(0, 0), get_line_remain(),
214 "Router LSA; Router = %s ", inet_ntoa(ls_router));
215 }
216 break;
217 case LS_TYPE_NETWORK:
218 if (flags & F_SUM) {
219 sprintf(sum_line, " net dr %s ", inet_ntoa(ls_router));
220 sum_line += strlen(sum_line);
221 sprintf(sum_line, "if %s ", inet_ntoa(ls_stateid));
222 sum_line += strlen(sum_line);
223 }
224 if (flags & F_DTAIL) {
225 (void) snprintf(get_line(0, 0), get_line_remain(),
226 "Network LSA Router = %s ", inet_ntoa(ls_router));
227 (void) snprintf(get_line(0, 0), get_line_remain(),
228 " Interface = %s ",
229 inet_ntoa(ls_stateid));
230 }
231 break;
232 case LS_TYPE_SUM_IP:
233 if (flags & F_SUM) {
234 sprintf(sum_line, " sum %s ", inet_ntoa(ls_stateid));
235 sum_line += strlen(sum_line);
236 sprintf(sum_line, "abr %s ", inet_ntoa(ls_router));
237 sum_line += strlen(sum_line);
238 }
239 if (flags & F_DTAIL) {
240 (void) snprintf(get_line(0, 0), get_line_remain(),
241 "Summary LSA IP = %s ", inet_ntoa(ls_stateid));
242 (void) snprintf(get_line(0, 0), get_line_remain(),
243 " Area Border Router = %s ",
244 inet_ntoa(ls_router));
245 }
246 break;
247 case LS_TYPE_SUM_ABR:
248 if (flags & F_SUM) {
249 sprintf(sum_line, "abr %s ", inet_ntoa(ls_stateid));
250 sum_line += strlen(sum_line);
251 sprintf(sum_line, "asbr %s ", inet_ntoa(ls_router));
252 sum_line += strlen(sum_line);
253 }
254 if (flags & F_DTAIL) {
255 (void) snprintf(get_line(0, 0), get_line_remain(),
256 "ASBR Summary abr = %s ", inet_ntoa(ls_stateid));
257 (void) snprintf(get_line(0, 0), get_line_remain(),
258 " asbr = %s ", inet_ntoa(ls_router));
259 }
260 break;
261 case LS_TYPE_ASE:
262 if (flags & F_SUM) {
263 sprintf(sum_line, " ase %s", inet_ntoa(ls_stateid));
264 sum_line += strlen(sum_line);
265 sprintf(sum_line, " asbr %s", inet_ntoa(ls_router));
266 sum_line += strlen(sum_line);
267 }
268 if (flags & F_DTAIL) {
269 (void) snprintf(get_line(0, 0), get_line_remain(),
270 "AS External LSA ase = %s ", inet_ntoa(ls_stateid));
271 (void) snprintf(get_line(0, 0), get_line_remain(),
272 " asbr = %s ", inet_ntoa(ls_router));
273 }
274
275 break;
276 case LS_TYPE_GROUP:
277 if (flags & F_SUM) {
278 sprintf(sum_line, " group %s", inet_ntoa(ls_stateid));
279 sum_line += strlen(sum_line);
280 sprintf(sum_line, " rtr %s", inet_ntoa(ls_router));
281 sum_line += strlen(sum_line);
282 }
283 if (flags & F_DTAIL) {
284 (void) snprintf(get_line(0, 0), get_line_remain(),
285 "Group LSA %s ", inet_ntoa(ls_stateid));
286 (void) snprintf(get_line(0, 0), get_line_remain(),
287 " rtr = %s ", inet_ntoa(ls_router));
288 }
289 break;
290 default:
291 if (flags & F_SUM) {
292 sprintf(sum_line, " unknown LSA type %d", ls_type);
293 sum_line += strlen(sum_line);
294 }
295 if (flags & F_DTAIL) {
296 (void) snprintf(get_line(0, 0), get_line_remain(),
297 "Unknown LSA type %d", ls_type);
298 }
299 break;
300 }
301 }
302
303 static void
interpret_ospf_lsa_hdr(int flags,struct lsa_hdr * lsah)304 interpret_ospf_lsa_hdr(int flags, struct lsa_hdr *lsah)
305 {
306 if (flags & F_SUM)
307 return;
308
309 if (flags & F_DTAIL) {
310 (void) snprintf(get_line(0, 0), get_line_remain(),
311 "Options = %s",
312 ospf_print_bits(ospf_option_bits, lsah->ls_options));
313 (void) snprintf(get_line(0, 0), get_line_remain(),
314 "Sequence = %X ", ntohl(lsah->ls_seq));
315 (void) snprintf(get_line(0, 0), get_line_remain(),
316 "Age = %X ", ospf_print_lsa_age(ntohs(lsah->ls_age)));
317 }
318
319 ospf_print_ls_type(flags, lsah->ls_type, lsah->ls_stateid,
320 lsah->ls_router);
321
322 }
323
324 #define TRUNC(addr) ((uchar_t *)(addr) > fragend)
325 static int
interpret_ospf_lsa(int flags,struct lsa * lsa,uchar_t * fragend)326 interpret_ospf_lsa(int flags, struct lsa *lsa, uchar_t *fragend)
327 {
328 uchar_t *ls_end;
329 int rla_count, k;
330 struct rlalink *rl;
331 struct tos_metric *tosp;
332 struct in_addr *addr;
333 uint32_t *tosmetric;
334 struct aslametric *am;
335 uint32_t tm;
336 int tos, metric;
337
338 interpret_ospf_lsa_hdr(flags, &lsa->ls_hdr);
339
340 ls_end = (uchar_t *)lsa + ntohs(lsa->ls_hdr.ls_length);
341
342 if (TRUNC(ls_end))
343 return (-1);
344
345 switch (lsa->ls_hdr.ls_type) {
346
347 case LS_TYPE_ROUTER:
348 if (TRUNC(&lsa->lsa_un.un_rla.rla_flags))
349 return (-1);
350
351 if (flags & F_DTAIL) {
352 (void) ospf_print_bits(ospf_rla_flag_bits,
353 lsa->lsa_un.un_rla.rla_flags);
354 }
355
356 if (TRUNC(&lsa->lsa_un.un_rla.rla_count))
357 return (-1);
358 rla_count = ntohs(lsa->lsa_un.un_rla.rla_count);
359
360 rl = lsa->lsa_un.un_rla.rla_link;
361 if (TRUNC(rl))
362 return (-1);
363
364 while (rla_count-- != 0) {
365 if (TRUNC((uchar_t *)rl + sizeof (*rl)))
366 return (-1);
367 switch (rl->link_type) {
368 case RLA_TYPE_VIRTUAL:
369 if (flags & F_DTAIL) {
370 (void) snprintf(get_line(0, 0),
371 get_line_remain(), "Virtual Link");
372 }
373 /* fall through */
374 case RLA_TYPE_ROUTER:
375 if (flags & F_DTAIL) {
376 (void) snprintf(get_line(0, 0),
377 get_line_remain(), "Neighbor = %s",
378 inet_ntoa(rl->link_id));
379 (void) snprintf(get_line(0, 0),
380 get_line_remain(), "Interface = %s",
381 inet_ntoa(rl->link_data));
382 }
383 break;
384 case RLA_TYPE_TRANSIT:
385 if (flags & F_DTAIL) {
386 (void) snprintf(get_line(0, 0),
387 get_line_remain(),
388 "Designated Router = %s",
389 inet_ntoa(rl->link_id));
390 (void) snprintf(get_line(0, 0),
391 get_line_remain(), "Interface = %s",
392 inet_ntoa(rl->link_data));
393 }
394 break;
395 case RLA_TYPE_STUB:
396 if (flags & F_DTAIL) {
397 (void) snprintf(get_line(0, 0),
398 get_line_remain(), "Network = %s",
399 inet_ntoa(rl->link_id));
400 (void) snprintf(get_line(0, 0),
401 get_line_remain(), "Mask = %s",
402 inet_ntoa(rl->link_data));
403 }
404 break;
405 default:
406 if (flags & F_DTAIL) {
407 (void) snprintf(get_line(0, 0),
408 get_line_remain(),
409 "Unknown link type %d",
410 rl->link_type);
411 }
412
413 }
414 if (flags & F_DTAIL) {
415 (void) snprintf(get_line(0, 0),
416 get_line_remain(), "TOS 0 metric = %d",
417 ntohs(rl->link_tos0metric));
418 }
419 tosp = (struct tos_metric *)(
420 (uchar_t *)rl + sizeof (rl->link_tos0metric));
421 for (k = 0; k > (int)rl->link_toscount; ++k, ++tosp) {
422 if (TRUNC(tosp))
423 return (-1);
424 if (flags & F_DTAIL) {
425 (void) snprintf(get_line(0, 0),
426 get_line_remain(),
427 "TOS %d metric = %d",
428 tosp->tos_type,
429 ntohs(tosp->tos_metric));
430 }
431
432 }
433 rl = (struct rlalink *)((uchar_t *)(rl + 1) +
434 ((rl->link_toscount) * sizeof (*tosp)));
435 if (TRUNC(rl))
436 return (-1); /* truncated */
437 }
438 break;
439 case LS_TYPE_NETWORK:
440
441 if (TRUNC(&lsa->lsa_un.un_nla.nla_mask))
442 return (-1);
443
444 if (flags & F_DTAIL) {
445 snprintf(get_line(0, 0), get_line_remain(),
446 "Mask = %s",
447 inet_ntoa(lsa->lsa_un.un_nla.nla_mask));
448 snprintf(get_line(0, 0), get_line_remain(),
449 "Routers:");
450 }
451 addr = lsa->lsa_un.un_nla.nla_router;
452 while ((uchar_t *)addr < ls_end) {
453 if ((uchar_t *)addr + sizeof (struct in_addr) > ls_end)
454 return (-1); /* truncated */
455 if (flags & F_DTAIL) {
456 snprintf(get_line(0, 0), get_line_remain(),
457 "\t%s", inet_ntoa(*addr));
458 }
459 ++addr;
460 }
461 break;
462 case LS_TYPE_SUM_IP:
463
464 if (TRUNC((uchar_t *)&lsa->lsa_un.un_sla.sla_mask +
465 sizeof (struct in_addr)))
466 return (-1);
467
468 if (flags & F_DTAIL) {
469 snprintf(get_line(0, 0), get_line_remain(), "Mask = %s",
470 inet_ntoa(lsa->lsa_un.un_sla.sla_mask));
471 }
472 /* FALLTHROUGH */
473 case LS_TYPE_SUM_ABR:
474 if (TRUNC(&lsa->lsa_un.un_sla.sla_tosmetric))
475 return (-1);
476 tosmetric = lsa->lsa_un.un_sla.sla_tosmetric;
477 while ((uchar_t *)tosmetric < ls_end) {
478 if ((uchar_t *)tosmetric + sizeof (tm) > fragend)
479 return (-1); /* truncated */
480 tm = ntohl(*tosmetric);
481 tos = (tm & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
482 metric = tm & SLA_MASK_METRIC;
483 if (flags & F_DTAIL) {
484 snprintf(get_line(0, 0), get_line_remain(),
485 " tos %d metric %d", tos, metric);
486 }
487 ++tosmetric;
488 }
489 break;
490 case LS_TYPE_ASE:
491 if (TRUNC(&lsa->lsa_un.un_asla.asla_mask))
492 return (-1);
493 if (flags & F_DTAIL) {
494 snprintf(get_line(0, 0), get_line_remain(), "Mask = %s",
495 inet_ntoa(lsa->lsa_un.un_asla.asla_mask));
496 }
497 am = lsa->lsa_un.un_asla.asla_metric;
498 while ((uchar_t *)am < ls_end) {
499 if ((uchar_t *)am + sizeof (tm) > fragend)
500 return (-1); /* truncated */
501 tm = ntohl(am->asla_tosmetric);
502 tos = (tm & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS;
503 metric = tm & ASLA_MASK_METRIC;
504 if (flags & F_DTAIL) {
505 snprintf(get_line(0, 0), get_line_remain(),
506 " type %d tos %d metric %d",
507 (tm & ASLA_FLAG_EXTERNAL) ? 2 : 1,
508 tos, metric);
509 }
510 if (am->asla_forward.s_addr != 0) {
511 if (flags & F_DTAIL) {
512 snprintf(get_line(0, 0),
513 get_line_remain(), " Forward %s",
514 inet_ntoa(am->asla_forward));
515 }
516 }
517 if (am->asla_tag.s_addr != 0) {
518 if (flags & F_DTAIL) {
519 snprintf(get_line(0, 0),
520 get_line_remain(), " Tag %s",
521 inet_ntoa(am->asla_tag));
522 }
523 }
524 ++am;
525 }
526 break;
527 default:
528 if (flags & F_DTAIL) {
529 snprintf(get_line(0, 0), get_line_remain(),
530 " Unknown LSA type %d", lsa->ls_hdr.ls_type);
531
532 }
533 break;
534 }
535 return (0);
536 }
537 #undef TRUNC
538
539 int
interpret_ospf(int flags,struct ospfhdr * ospf,int iplen,int fraglen)540 interpret_ospf(int flags, struct ospfhdr *ospf, int iplen, int fraglen)
541 {
542 int nlsa, nlsah = 0;
543 struct lsa_hdr *lsah;
544 struct lsr *lsr;
545 struct lsa *lsa;
546 boolean_t trunc = B_FALSE;
547
548 if ((fraglen < OSPF_MIN_HEADER_SIZE) ||
549 (fraglen < ntohs(ospf->ospf_len)))
550 return (fraglen); /* incomplete header */
551
552 if (fraglen > ntohs(ospf->ospf_len))
553 fraglen = ntohs(ospf->ospf_len);
554
555
556 if (ospf->ospf_type > OSPF_TYPE_MAX) {
557 if (flags & F_SUM) {
558 (void) sprintf(sum_line, "Unknown OSPF TYPE %d \n",
559 ospf->ospf_type);
560 sum_line += strlen(sum_line);
561 }
562 if (flags & F_SUM) {
563 show_header("OSPF: ", "OSPF Header", fraglen);
564 show_space();
565 (void) snprintf(get_line(0, 0), get_line_remain(),
566 "Unknown OSPF Type = %d", ospf->ospf_type);
567 }
568 return (fraglen);
569 }
570
571 if (flags & F_SUM) {
572 sum_line = (char *)get_sum_line();
573 (void) sprintf(sum_line, "OSPF %s RTRID=%s ",
574 ospf_types[ospf->ospf_type],
575 inet_ntoa(ospf->ospf_routerid));
576 sum_line += strlen(sum_line);
577 (void) sprintf(sum_line, "AREA=%s LEN=%d ",
578 inet_ntoa(ospf->ospf_areaid),
579 ntohs((ushort_t)ospf->ospf_len));
580 sum_line += strlen(sum_line);
581 }
582
583 if (flags & F_DTAIL) {
584 show_header("OSPF: ", "OSPF Header", fraglen);
585 show_space();
586 (void) snprintf(get_line(0, 0), get_line_remain(),
587 "Version = %d", ospf->ospf_version);
588 (void) snprintf(get_line(0, 0), get_line_remain(),
589 "Type = %s", ospf_types[ospf->ospf_type]);
590 (void) snprintf(get_line(0, 0), get_line_remain(),
591 "Router ID = %s", inet_ntoa(ospf->ospf_routerid));
592 (void) snprintf(get_line(0, 0), get_line_remain(),
593 "Area ID = %s", inet_ntoa(ospf->ospf_areaid));
594 (void) snprintf(get_line(0, 0), get_line_remain(),
595 "Checksum = 0x%x", ospf->ospf_chksum);
596
597 if (ospf->ospf_authtype > OSPF_AUTH_TYPE_MAX) {
598 (void) snprintf(get_line(0, 0), get_line_remain(),
599 "Auth = %d (unknown auth type)",
600 ospf->ospf_authtype);
601 } else {
602 (void) snprintf(get_line(0, 0), get_line_remain(),
603 "Auth = %s", ospf_authtypes[ospf->ospf_authtype]);
604 }
605 }
606
607 if (ospf->ospf_version != 2) {
608 if (ospf->ospf_version == 3) {
609 if (flags & F_DTAIL)
610 snprintf(get_line(0, 0), get_line_remain(),
611 "ospfv3 packet in ipv4 header");
612 return (interpret_ospf6(flags, ospf, iplen, fraglen));
613 } else {
614 return (fraglen);
615 }
616 }
617
618 switch (ospf->ospf_type) {
619 case OSPF_TYPE_HELLO:
620 if (interpret_ospf_hello(flags, ospf, fraglen) < 0)
621 trunc = B_TRUE;
622 break;
623
624 case OSPF_TYPE_DB:
625 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_DB_HEADER_SIZE) {
626 trunc = B_TRUE;
627 break;
628 }
629 if (flags & F_SUM) {
630 sprintf(sum_line, " %s %s S %X", ospf_print_bits(
631 ospf_option_bits, ospf->ospf_db.db_options),
632 ospf_print_bits(ospf_db_flags_bits,
633 ospf->ospf_db.db_flags),
634 ntohl(ospf->ospf_db.db_seq));
635 sum_line += strlen(sum_line);
636 }
637 if (flags & F_DTAIL) {
638 show_header("OSPF DB: ", "Database Description Packet",
639 fraglen);
640 show_space();
641 snprintf(get_line(0, 0), get_line_remain(),
642 "Options = %s", ospf_print_bits(
643 ospf_option_bits, ospf->ospf_db.db_options));
644 snprintf(get_line(0, 0), get_line_remain(),
645 "Flags = %s", ospf_print_bits(
646 ospf_db_flags_bits, ospf->ospf_db.db_flags));
647 snprintf(get_line(0, 0), get_line_remain(),
648 "Sequence = 0x%X", ntohl(ospf->ospf_db.db_seq));
649 /* Print all the LS advs */
650 lsah = ospf->ospf_db.db_lshdr;
651 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) {
652 if ((uchar_t *)lsah + sizeof (struct lsa_hdr) >
653 ((uchar_t *)ospf + fraglen)) {
654 trunc = B_TRUE;
655 break;
656 }
657 interpret_ospf_lsa_hdr(flags, lsah);
658 ++lsah;
659 }
660 }
661 break;
662
663 case OSPF_TYPE_LSR:
664 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_LSR_HEADER_SIZE) {
665 trunc = B_TRUE;
666 break;
667 }
668 if (flags & F_DTAIL) {
669 snprintf(get_line(0, 0), get_line_remain(),
670 "Link State Request Packet");
671 }
672 lsr = ospf->ospf_lsr;
673 while ((uchar_t *)lsr < ((uchar_t *)ospf + fraglen)) {
674 if ((uchar_t *)lsr + sizeof (struct lsr) >
675 ((uchar_t *)ospf + fraglen)) {
676 trunc = B_TRUE;
677 break;
678 }
679 if (flags & F_SUM) {
680 nlsah++;
681 }
682 if (flags & F_DTAIL) {
683 ospf_print_ls_type(flags, ntohl(lsr->ls_type),
684 lsr->ls_stateid, lsr->ls_router);
685 }
686 ++lsr;
687 }
688 if (flags & F_SUM) {
689 sprintf(sum_line, " %d LSAs", nlsah);
690 sum_line += strlen(sum_line);
691 }
692 break;
693
694 case OSPF_TYPE_LSU:
695 if (fraglen < OSPF_MIN_HEADER_SIZE + OSPF_MIN_LSU_HEADER_SIZE) {
696 trunc = B_TRUE;
697 break;
698 }
699 if (flags & F_DTAIL) {
700 show_header("OSPF LSU: ", "Link State Update Packet",
701 fraglen);
702 show_space();
703 }
704 lsa = ospf->ospf_lsu.lsu_lsa;
705 nlsa = ntohl(ospf->ospf_lsu.lsu_count);
706 if (flags & F_SUM) {
707 sprintf(sum_line, "%d LSAs", nlsa);
708 sum_line += strlen(sum_line);
709 break;
710 }
711 while (nlsa-- != 0) {
712 uchar_t *fragend = (uchar_t *)ospf + fraglen;
713 if (((uchar_t *)lsa >= fragend) ||
714 ((uchar_t *)lsa + sizeof (struct lsa_hdr) >
715 fragend) ||
716 ((uchar_t *)lsa + ntohs(lsa->ls_hdr.ls_length) >
717 fragend)) {
718 trunc = B_TRUE;
719 break;
720 }
721
722 if (interpret_ospf_lsa(flags, lsa, fragend) < 0) {
723 trunc = B_TRUE;
724 break;
725 }
726 lsa = (struct lsa *)((uchar_t *)lsa +
727 ntohs(lsa->ls_hdr.ls_length));
728 }
729
730 break;
731
732 case OSPF_TYPE_LSA:
733 if (flags & F_DTAIL) {
734 show_header("OSPF LSA: ", "Link State Ack Packet",
735 fraglen);
736 show_space();
737 }
738 lsah = ospf->ospf_lsa.lsa_lshdr;
739 nlsah = 0;
740 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) {
741 if ((uchar_t *)lsah + sizeof (struct lsa_hdr) >
742 ((uchar_t *)ospf + fraglen)) {
743 trunc = B_TRUE;
744 break;
745 }
746 nlsah++;
747 if (flags & F_DTAIL)
748 interpret_ospf_lsa_hdr(flags, lsah);
749 ++lsah;
750 }
751 if (flags & F_SUM) {
752 sprintf(sum_line, "%d LSAs", nlsah);
753 sum_line += strlen(sum_line);
754 }
755 break;
756
757 default:
758 /* NOTREACHED */
759 break;
760 }
761 if (trunc) {
762 if (flags & F_SUM) {
763 sprintf(sum_line, "--truncated");
764 sum_line += strlen(sum_line);
765 }
766 if (flags & F_DTAIL)
767 snprintf(get_line(0, 0), get_line_remain(),
768 "--truncated");
769 }
770
771 return (fraglen);
772 }
773