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 extern const struct bits ospf_db_flags_bits[];
51 extern const struct bits ospf_rla_flag_bits[];
52 extern const struct bits ospf_option_bits[];
53
54 const struct bits ospf6_option_bits[] = {
55 { OSPF_OPTION_V6, "V6" },
56 { OSPF_OPTION_E, "E" },
57 { OSPF_OPTION_MC, "MC" },
58 { OSPF_OPTION_N, "N" },
59 { OSPF_OPTION_R, "R" },
60 { OSPF_OPTION_DC, "DC" },
61 { 0, NULL }
62 };
63
64 /*
65 * return a printable string in dotted-decimal notation
66 * for id.
67 */
68 static char *
print_ipaddr(uint32_t id)69 print_ipaddr(uint32_t id)
70 {
71 struct in_addr tmp;
72
73 tmp.s_addr = id;
74 return (inet_ntoa(tmp));
75 }
76
77 static int
interpret_ospf6_hello(int flags,struct ospf6hdr * op,int fraglen)78 interpret_ospf6_hello(int flags, struct ospf6hdr *op, int fraglen)
79 {
80 uint32_t *nbr;
81 int j;
82
83 if (fraglen < OSPF6_MIN_HEADER_SIZE + OSPF_MIN_HELLO_HEADER_SIZE)
84 return (-1); /* truncated packet */
85
86 if (flags & F_SUM) {
87 if (op->ospf6_hello.hello_dr != 0) {
88 (void) sprintf(sum_line, "DR=%s ",
89 print_ipaddr(op->ospf6_hello.hello_dr));
90 }
91 sum_line += strlen(sum_line);
92 if (op->ospf6_hello.hello_bdr != 0) {
93 (void) sprintf(sum_line, "BDR=%s ",
94 print_ipaddr(op->ospf6_hello.hello_bdr));
95 }
96 sum_line += strlen(sum_line);
97 j = 0;
98 nbr = op->ospf6_hello.hello_neighbor;
99 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) {
100 if ((uchar_t *)nbr + sizeof (struct in_addr) >
101 ((uchar_t *)op + fraglen))
102 return (-1); /* truncated */
103 ++nbr;
104 j++;
105 }
106 (void) sprintf(sum_line, "%d nbrs", j);
107 sum_line += strlen(sum_line);
108
109 }
110 if (flags & F_DTAIL) {
111 show_header("OSPF HELLO: ", "Hello Packet",
112 ntohs(op->ospf6_len));
113 show_space();
114 (void) snprintf(get_line(0, 0), get_line_remain(),
115 "Options = %s", ospf_print_bits(ospf6_option_bits,
116 op->ospf6_hello.hello6_options));
117 (void) snprintf(get_line(0, 0), get_line_remain(),
118 "Interface ID = %s",
119 print_ipaddr(op->ospf6_hello.hello_ifid));
120 (void) snprintf(get_line(0, 0), get_line_remain(),
121 "Hello interval = %d",
122 ntohs(op->ospf6_hello.hello_helloint));
123 (void) snprintf(get_line(0, 0), get_line_remain(),
124 "Priority = %d", op->ospf6_hello.hello6_priority);
125 (void) snprintf(get_line(0, 0), get_line_remain(),
126 "Dead interval = %u", ntohl(op->ospf6_hello.hello_deadint));
127 if (op->ospf6_hello.hello_dr != 0) {
128 (void) snprintf(get_line(0, 0), get_line_remain(),
129 "Designated Router = %s",
130 print_ipaddr(op->ospf6_hello.hello_dr));
131 }
132 if (op->ospf6_hello.hello_bdr != 0) {
133 (void) snprintf(get_line(0, 0), get_line_remain(),
134 "Backup Designated Router = %s",
135 print_ipaddr(op->ospf6_hello.hello_bdr));
136 }
137 nbr = op->ospf6_hello.hello_neighbor;
138 while ((uchar_t *)nbr < ((uchar_t *)op + fraglen)) {
139 if ((uchar_t *)nbr + sizeof (struct in_addr) >
140 ((uchar_t *)op + fraglen))
141 return (-1); /* truncated */
142 (void) snprintf(get_line(0, 0), get_line_remain(),
143 "Neigbor: %s", print_ipaddr(*nbr));
144 ++nbr;
145 }
146 }
147 return (fraglen);
148 }
149
150 static void
ospf6_print_ls_type(int flags,uint_t ls6_type,uint32_t ls6_stateid,uint32_t ls6_router)151 ospf6_print_ls_type(int flags, uint_t ls6_type, uint32_t ls6_stateid,
152 uint32_t ls6_router)
153 {
154 char scope[15];
155
156 if (flags & F_SUM)
157 return;
158
159 switch (ls6_type & LS6_SCOPE_MASK) {
160 case LS6_SCOPE_LINKLOCAL:
161 snprintf(scope, sizeof (scope), "linklocal");
162 break;
163 case LS6_SCOPE_AREA:
164 snprintf(scope, sizeof (scope), "area");
165 break;
166 case LS6_SCOPE_AS:
167 snprintf(scope, sizeof (scope), "AS");
168 break;
169 default:
170 snprintf(scope, sizeof (scope), "");
171 break;
172 }
173 switch (ls6_type & LS_TYPE_MASK) {
174 case LS_TYPE_ROUTER:
175 if (flags & F_DTAIL) {
176 (void) snprintf(get_line(0, 0), get_line_remain(),
177 "%s Router = %s", scope, print_ipaddr(ls6_router));
178 }
179 break;
180 case LS_TYPE_NETWORK:
181 if (flags & F_DTAIL) {
182 (void) snprintf(get_line(0, 0), get_line_remain(),
183 "%s Net DR %s IF %s", scope,
184 print_ipaddr(ls6_router),
185 print_ipaddr(ls6_stateid));
186 }
187 break;
188 case LS_TYPE_INTER_AP:
189 if (flags & F_DTAIL) {
190 (void) snprintf(get_line(0, 0), get_line_remain(),
191 "%s Inter-area-prefix = %s ABR %s", scope,
192 print_ipaddr(ls6_stateid),
193 print_ipaddr(ls6_router));
194 }
195 break;
196 case LS_TYPE_INTER_AR:
197 if (flags & F_DTAIL) {
198 (void) snprintf(get_line(0, 0), get_line_remain(),
199 "%s Inter-area-router = %s Router %s", scope,
200 print_ipaddr(ls6_router),
201 print_ipaddr(ls6_stateid));
202 }
203 break;
204 case LS_TYPE_ASE:
205 if (flags & F_DTAIL) {
206 (void) snprintf(get_line(0, 0), get_line_remain(),
207 "%s ASE = %s ASBR %s", scope,
208 print_ipaddr(ls6_stateid),
209 print_ipaddr(ls6_router));
210 }
211 break;
212 case LS_TYPE_GROUP:
213 if (flags & F_DTAIL) {
214 (void) snprintf(get_line(0, 0), get_line_remain(),
215 "%s group = %s Router %s", scope,
216 print_ipaddr(ls6_stateid),
217 print_ipaddr(ls6_router));
218 }
219 break;
220 case LS_TYPE_TYPE7:
221 if (flags & F_DTAIL) {
222 (void) snprintf(get_line(0, 0), get_line_remain(),
223 "%s Type 7 = %s Router %s", scope,
224 print_ipaddr(ls6_stateid),
225 print_ipaddr(ls6_router));
226 }
227 break;
228 case LS_TYPE_LINK:
229 if (flags & F_DTAIL) {
230 (void) snprintf(get_line(0, 0), get_line_remain(),
231 "%s link = %s Router %s", scope,
232 print_ipaddr(ls6_stateid),
233 print_ipaddr(ls6_router));
234 }
235 break;
236 case LS_TYPE_INTRA_AP:
237 if (flags & F_DTAIL) {
238 (void) snprintf(get_line(0, 0), get_line_remain(),
239 "%s Inter-area-prefix = %s Router %s", scope,
240 print_ipaddr(ls6_stateid),
241 print_ipaddr(ls6_router));
242 }
243 break;
244 default:
245 if (flags & F_DTAIL) {
246 (void) snprintf(get_line(0, 0), get_line_remain(),
247 "%s Unknown type = 0x%x", ls6_type);
248 }
249 break;
250 }
251 }
252
253 static int
ospf6_print_lsaprefix(int flags,struct lsa6_prefix * lpfx)254 ospf6_print_lsaprefix(int flags, struct lsa6_prefix *lpfx)
255 {
256 int k;
257 struct in6_addr prefix;
258 char prefixstr[INET6_ADDRSTRLEN];
259
260 k = (lpfx->lsa6_plen + 31)/32;
261 if (k * 4 > sizeof (struct in6_addr)) {
262 if (flags & F_SUM) {
263 sprintf(sum_line, "Unknown prefix len %d",
264 lpfx->lsa6_plen);
265 sum_line += strlen(sum_line);
266 }
267 if (flags & F_DTAIL) {
268 (void) snprintf(get_line(0, 0), get_line_remain(),
269 "Unknown prefix len %d", lpfx->lsa6_plen);
270 }
271 }
272 memset((void *)&prefix, 0, sizeof (prefix));
273 memcpy((void *)&prefix, lpfx->lsa6_pfx, k * 4);
274 (void) inet_ntop(AF_INET6, (char *)&prefix, prefixstr,
275 INET6_ADDRSTRLEN);
276 if (flags & F_SUM) {
277 sprintf(sum_line, "%s/%d", prefixstr, lpfx->lsa6_plen);
278 sum_line += strlen(sum_line);
279 }
280 if (flags & F_DTAIL) {
281 (void) snprintf(get_line(0, 0), get_line_remain(),
282 "%s/%d", prefixstr, lpfx->lsa6_plen);
283 }
284 if (lpfx->lsa6_popt != 0) {
285 if (flags & F_SUM) {
286 sprintf(sum_line, "(opt = %x)", lpfx->lsa6_popt);
287 sum_line += strlen(sum_line);
288 }
289 if (flags & F_DTAIL) {
290 (void) snprintf(get_line(0, 0), get_line_remain(),
291 "(opt = %x)", lpfx->lsa6_popt);
292 }
293 }
294 return (sizeof (*lpfx) - 4 + k * 4);
295 }
296
297 static void
interpret_ospf6_lsa_hdr(int flags,struct lsa6_hdr * lsah)298 interpret_ospf6_lsa_hdr(int flags, struct lsa6_hdr *lsah)
299 {
300 if (flags & F_SUM)
301 return;
302
303 if (flags & F_DTAIL) {
304 (void) snprintf(get_line(0, 0), get_line_remain(),
305 "Sequence = %X ", ntohl(lsah->ls6_seq));
306 (void) snprintf(get_line(0, 0), get_line_remain(),
307 "Age = %X ", ospf_print_lsa_age(ntohl(lsah->ls6_age)));
308 }
309
310 ospf6_print_ls_type(flags, lsah->ls6_type, lsah->ls6_stateid,
311 lsah->ls6_router);
312
313 }
314
315 #define TRUNC(addr) ((uchar_t *)(addr) > fragend)
316 static int
interpret_ospf6_lsa(int flags,struct lsa6 * lsa,uchar_t * fragend)317 interpret_ospf6_lsa(int flags, struct lsa6 *lsa, uchar_t *fragend)
318 {
319 uchar_t *ls_end;
320 int k, j;
321 struct rla6link *rl;
322 uint32_t *addr;
323 struct lsa6_prefix *lpfx;
324 struct llsa *llsa;
325 char addrstr[INET6_ADDRSTRLEN];
326
327 interpret_ospf6_lsa_hdr(flags, &lsa->ls6_hdr);
328
329 ls_end = (uchar_t *)lsa + ntohs(lsa->ls6_hdr.ls6_length);
330
331 if (TRUNC(ls_end))
332 return (-1);
333
334 switch (ntohs(lsa->ls6_hdr.ls6_type)) {
335
336 case LS_TYPE_ROUTER|LS6_SCOPE_AREA:
337 if (TRUNC(&lsa->lsa_un.un_rla.rla6_flags))
338 return (-1);
339
340 (void) ospf_print_bits(ospf_rla_flag_bits,
341 lsa->lsa_un.un_rla.rla6_flags);
342
343 if (TRUNC(&lsa->lsa_un.un_rla.rla6_options))
344 return (-1);
345 (void) ospf_print_bits(ospf_option_bits,
346 ntohl(lsa->lsa_un.un_rla.rla6_options));
347
348 rl = lsa->lsa_un.un_rla.rla_link;
349 if (TRUNC(rl))
350 return (-1);
351
352 while (rl + sizeof (*rl) <= (struct rla6link *)ls_end) {
353 if (TRUNC((uchar_t *)rl + sizeof (*rl)))
354 return (-1);
355 if (flags & F_SUM) {
356 sprintf(sum_line, "{"); /* } (ctags) */
357 sum_line += strlen(sum_line);
358 }
359 switch (rl->link_type) {
360 case RLA_TYPE_VIRTUAL:
361 if (flags & F_SUM) {
362 sprintf(sum_line, "virt ");
363 sum_line += strlen(sum_line);
364 }
365 if (flags & F_DTAIL) {
366 (void) snprintf(get_line(0, 0),
367 get_line_remain(), "Virtual Link");
368 }
369 /* FALLTHROUGH */
370 case RLA_TYPE_ROUTER:
371 if (flags & F_SUM) {
372 sprintf(sum_line, "nbrid %s",
373 print_ipaddr(rl->link_nrtid));
374 sum_line += strlen(sum_line);
375 sprintf(sum_line, " nbrif %s",
376 print_ipaddr(rl->link_nifid));
377 sum_line += strlen(sum_line);
378 sprintf(sum_line, " if %s",
379 print_ipaddr(rl->link_ifid));
380 sum_line += strlen(sum_line);
381 }
382 if (flags & F_DTAIL) {
383 (void) snprintf(get_line(0, 0),
384 get_line_remain(), "Neighbor = %s",
385 print_ipaddr(rl->link_nrtid));
386 (void) snprintf(get_line(0, 0),
387 get_line_remain(),
388 "Interface = %s id %s",
389 print_ipaddr(rl->link_nifid),
390 print_ipaddr(rl->link_ifid));
391 }
392 break;
393 case RLA_TYPE_TRANSIT:
394 if (flags & F_SUM) {
395 sprintf(sum_line, "dr %s",
396 print_ipaddr(rl->link_nrtid));
397 sum_line += strlen(sum_line);
398 sprintf(sum_line, " drif %s",
399 print_ipaddr(rl->link_nifid));
400 sum_line += strlen(sum_line);
401 sprintf(sum_line, " if %s",
402 print_ipaddr(rl->link_ifid));
403 sum_line += strlen(sum_line);
404 }
405 if (flags & F_DTAIL) {
406 (void) snprintf(get_line(0, 0),
407 get_line_remain(),
408 "Designated Router = %s",
409 print_ipaddr(rl->link_nrtid));
410 (void) snprintf(get_line(0, 0),
411 get_line_remain(),
412 "DR Interface = %s id %s",
413 print_ipaddr(rl->link_nifid),
414 print_ipaddr(rl->link_ifid));
415 }
416 break;
417 default:
418 if (flags & F_SUM) {
419 sprintf(sum_line,
420 "Unknown link type %d",
421 rl->link_type);
422 sum_line += strlen(sum_line);
423 }
424 if (flags & F_DTAIL) {
425 (void) snprintf(get_line(0, 0),
426 get_line_remain(),
427 "Unknown link type %d",
428 rl->link_type);
429 }
430
431 }
432 if (flags & F_SUM) {
433 sprintf(sum_line, " metric %d",
434 ntohs(rl->link_metric));
435 sum_line += strlen(sum_line);
436 }
437 if (flags & F_DTAIL) {
438 (void) snprintf(get_line(0, 0),
439 get_line_remain(), " metric = %d",
440 ntohs(rl->link_metric));
441 }
442 if (flags & F_SUM) { /* { (ctags) */
443 sprintf(sum_line, " }");
444 sum_line += strlen(sum_line);
445 }
446 rl++;
447 if ((uchar_t *)rl > fragend)
448 return (-1); /* truncated */
449 }
450 break;
451 case LS_TYPE_NETWORK | LS6_SCOPE_AREA:
452
453 if (TRUNC(&lsa->lsa_un.un_nla.nla_options))
454 return (-1);
455
456 (void) ospf_print_bits(ospf6_option_bits,
457 ntohl(lsa->lsa_un.un_nla.nla_options));
458
459 if (flags & F_SUM) {
460 sprintf(sum_line, " rtrs");
461 sum_line += strlen(sum_line);
462 }
463 if (flags & F_DTAIL) {
464 snprintf(get_line(0, 0), get_line_remain(),
465 "Routers:");
466 }
467 addr = lsa->lsa_un.un_nla.nla_router;
468 while ((uchar_t *)addr < ls_end) {
469 if ((uchar_t *)addr + sizeof (struct in_addr) > ls_end)
470 return (-1); /* truncated */
471 if (flags & F_SUM) {
472 sprintf(sum_line, " %s", print_ipaddr(*addr));
473 sum_line += strlen(sum_line);
474 }
475 if (flags & F_DTAIL) {
476 snprintf(get_line(0, 0), get_line_remain(),
477 "\t%s", print_ipaddr(*addr));
478 }
479 ++addr;
480 }
481 break;
482 case LS_TYPE_INTER_AP | LS6_SCOPE_AREA:
483
484 if (TRUNC(&lsa->lsa_un.un_inter_ap.inter_ap_metric))
485 return (-1);
486
487 if (flags & F_SUM) {
488 sprintf(sum_line, " metric %s",
489 ntohl(lsa->lsa_un.un_inter_ap.inter_ap_metric) &
490 SLA_MASK_METRIC);
491 sum_line += strlen(sum_line);
492 }
493 if (flags & F_DTAIL) {
494 snprintf(get_line(0, 0), get_line_remain(),
495 "Metric = %s",
496 ntohl(lsa->lsa_un.un_inter_ap.inter_ap_metric) &
497 SLA_MASK_METRIC);
498 }
499 lpfx = lsa->lsa_un.un_inter_ap.inter_ap_prefix;
500 if (lpfx > (struct lsa6_prefix *)ls_end)
501 return (-1);
502 while (lpfx + sizeof (*lpfx) <= (struct lsa6_prefix *)ls_end) {
503 k = ospf6_print_lsaprefix(flags, lpfx);
504 lpfx = (struct lsa6_prefix *)(((uchar_t *)lpfx) + k);
505 if (lpfx > (struct lsa6_prefix *)ls_end)
506 return (-1);
507 }
508 break;
509 case LS_TYPE_LINK:
510 llsa = &lsa->lsa_un.un_llsa;
511 if (TRUNC(llsa->llsa_options))
512 return (-1);
513 ospf_print_bits(ospf6_option_bits, ntohl(llsa->llsa_options));
514 if (TRUNC(llsa->llsa_nprefix))
515 return (-1);
516 (void) inet_ntop(AF_INET6, &llsa->llsa_lladdr,
517 addrstr, INET6_ADDRSTRLEN);
518 if (flags & F_SUM) {
519 sprintf(sum_line, " pri %d lladdr %s npref %d",
520 ntohl(llsa->llsa_priority), addrstr,
521 ntohl(llsa->llsa_nprefix));
522 sum_line += strlen(sum_line);
523 }
524 if (flags & F_DTAIL) {
525 snprintf(get_line(0, 0), get_line_remain(),
526 "Priority %d", ntohl(llsa->llsa_priority));
527 snprintf(get_line(0, 0), get_line_remain(),
528 "Link Local addr %d", addrstr);
529 snprintf(get_line(0, 0), get_line_remain(),
530 "npref %d", ntohl(llsa->llsa_nprefix));
531 }
532 lpfx = llsa->llsa_prefix;
533 for (j = 0; j < ntohl(llsa->llsa_nprefix); j++) {
534 if (TRUNC(lpfx))
535 return (-1);
536 k = ospf6_print_lsaprefix(flags, lpfx);
537 lpfx = (struct lsa6_prefix *)(((uchar_t *)lpfx) + k);
538 }
539 break;
540
541 case LS_TYPE_INTRA_AP | LS6_SCOPE_AREA:
542 if (TRUNC(&lsa->lsa_un.un_intra_ap.intra_ap_rtid))
543 return (-1);
544 ospf6_print_ls_type(flags,
545 ntohs(lsa->lsa_un.un_intra_ap.intra_ap_lstype),
546 lsa->lsa_un.un_intra_ap.intra_ap_lsid,
547 lsa->lsa_un.un_intra_ap.intra_ap_rtid);
548 if (TRUNC(&lsa->lsa_un.un_intra_ap.intra_ap_nprefix))
549 return (-1);
550 if (flags & F_SUM) {
551 sprintf(sum_line, " npref %d",
552 ntohs(lsa->lsa_un.un_intra_ap.intra_ap_nprefix));
553 sum_line += strlen(sum_line);
554 }
555 if (flags & F_DTAIL) {
556 snprintf(get_line(0, 0), get_line_remain(), "NPref %d",
557 ntohs(lsa->lsa_un.un_intra_ap.intra_ap_nprefix));
558 }
559
560 lpfx = lsa->lsa_un.un_intra_ap.intra_ap_prefix;
561 for (j = 0;
562 j < ntohs(lsa->lsa_un.un_intra_ap.intra_ap_nprefix); j++) {
563 if (TRUNC(lpfx))
564 return (-1);
565 k = ospf6_print_lsaprefix(flags, lpfx);
566 lpfx = (struct lsa6_prefix *)(((uchar_t *)lpfx) + k);
567 }
568 break;
569
570 default:
571 if (flags & F_SUM) {
572 sprintf(sum_line, " Unknown LSA type (%d)",
573 lsa->ls6_hdr.ls6_type);
574 sum_line += strlen(sum_line);
575 }
576 if (flags & F_DTAIL) {
577 snprintf(get_line(0, 0), get_line_remain(),
578 " Unknown LSA type %d", lsa->ls6_hdr.ls6_type);
579
580 }
581 break;
582 }
583 return (0);
584 }
585 #undef TRUNC
586 int
interpret_ospf6(int flags,struct ospf6hdr * ospf,int iplen,int fraglen)587 interpret_ospf6(int flags, struct ospf6hdr *ospf, int iplen, int fraglen)
588 {
589 boolean_t trunc = B_FALSE;
590 struct lsa6_hdr *lsah;
591 struct lsr6 *lsr;
592 struct lsa6 *lsa;
593 int nlsa, nlsah;
594
595 if ((fraglen < OSPF6_MIN_HEADER_SIZE) ||
596 (fraglen < ntohs(ospf->ospf6_len)))
597 return (fraglen); /* incomplete header */
598
599 if (ospf->ospf6_version != 3) {
600 if (ospf->ospf6_version == 2) {
601 if (flags & F_DTAIL)
602 snprintf(get_line(0, 0), get_line_remain(),
603 "ospfv2 packet in ipv6 header");
604 return (interpret_ospf(flags, ospf, iplen, fraglen));
605 } else {
606 return (fraglen);
607 }
608 }
609
610 if (fraglen > ntohs(ospf->ospf6_len))
611 fraglen = ntohs(ospf->ospf6_len);
612
613 if (ospf->ospf6_type > OSPF_TYPE_MAX) {
614 if (flags & F_SUM) {
615 (void) sprintf(sum_line, "Unknown OSPF TYPE %d \n",
616 ospf->ospf6_type);
617 sum_line += strlen(sum_line);
618 }
619 if (flags & F_SUM) {
620 show_header("OSPFv3: ", "OSPFv3 Header", fraglen);
621 show_space();
622 (void) snprintf(get_line(0, 0), get_line_remain(),
623 "Unknown OSPF Type = %d", ospf->ospf6_type);
624 }
625 return (fraglen);
626 }
627
628 if (flags & F_SUM) {
629 sum_line = (char *)get_sum_line();
630 (void) sprintf(sum_line, "OSPFv3 %s RTRID=%s ",
631 ospf_types[ospf->ospf6_type],
632 print_ipaddr(ospf->ospf6_routerid));
633 sum_line += strlen(sum_line);
634 (void) sprintf(sum_line, "AREA=%s LEN=%d instance %u ",
635 print_ipaddr(ospf->ospf6_areaid),
636 ntohs((ushort_t)ospf->ospf6_len), ospf->ospf6_instanceid);
637 sum_line += strlen(sum_line);
638 }
639
640 if (flags & F_DTAIL) {
641 show_header("OSPFv3: ", "OSPF Header", fraglen);
642 show_space();
643 (void) snprintf(get_line(0, 0), get_line_remain(),
644 "Version = %d", ospf->ospf6_version);
645 (void) snprintf(get_line(0, 0), get_line_remain(),
646 "Type = %s", ospf_types[ospf->ospf6_type]);
647 (void) snprintf(get_line(0, 0), get_line_remain(),
648 "Router ID = %s", print_ipaddr(ospf->ospf6_routerid));
649 (void) snprintf(get_line(0, 0), get_line_remain(),
650 "Area ID = %s", print_ipaddr(ospf->ospf6_areaid));
651 (void) snprintf(get_line(0, 0), get_line_remain(),
652 "Checksum = 0x%x", ospf->ospf6_chksum);
653 (void) snprintf(get_line(0, 0), get_line_remain(),
654 "Instance = %u", ospf->ospf6_instanceid);
655 }
656
657 switch (ospf->ospf6_type) {
658 case OSPF_TYPE_HELLO:
659 if (interpret_ospf6_hello(flags, ospf, fraglen) < 0)
660 trunc = B_TRUE;
661 break;
662
663 case OSPF_TYPE_DB:
664 if (fraglen < OSPF6_MIN_HEADER_SIZE +
665 OSPF6_MIN_DB_HEADER_SIZE) {
666 trunc = B_TRUE;
667 break;
668 }
669 if (flags & F_SUM) {
670 sprintf(sum_line, " %s %s mtu %u S %X", ospf_print_bits(
671 ospf6_option_bits,
672 ntohl(ospf->ospf6_db.db_options)),
673 ospf_print_bits(ospf_db_flags_bits,
674 ospf->ospf6_db.db_flags),
675 ntohs(ospf->ospf6_db.db_mtu),
676 ntohl(ospf->ospf6_db.db_seq));
677 sum_line += strlen(sum_line);
678 }
679 if (flags & F_DTAIL) {
680 show_header("OSPF DB: ", "Database Description Packet",
681 fraglen);
682 show_space();
683 snprintf(get_line(0, 0), get_line_remain(),
684 "Options = %s", ospf_print_bits(
685 ospf6_option_bits, ospf->ospf6_db.db_options));
686 snprintf(get_line(0, 0), get_line_remain(),
687 "Flags = %s", ospf_print_bits(
688 ospf_db_flags_bits, ospf->ospf6_db.db_flags));
689 snprintf(get_line(0, 0), get_line_remain(),
690 "MTU = %u", ntohl(ospf->ospf6_db.db_seq));
691 snprintf(get_line(0, 0), get_line_remain(),
692 "Sequence = 0x%X", ntohl(ospf->ospf6_db.db_seq));
693 /* Print all the LS advs */
694 lsah = ospf->ospf6_db.db_lshdr;
695 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) {
696 if ((uchar_t *)lsah + sizeof (struct lsa6_hdr) >
697 ((uchar_t *)ospf + fraglen)) {
698 trunc = B_TRUE;
699 break;
700 }
701 interpret_ospf6_lsa_hdr(flags, lsah);
702 ++lsah;
703 }
704 }
705 break;
706
707 case OSPF_TYPE_LSR:
708 if (fraglen < OSPF6_MIN_HEADER_SIZE +
709 OSPF_MIN_LSR_HEADER_SIZE) {
710 trunc = B_TRUE;
711 break;
712 }
713 if (flags & F_DTAIL) {
714 show_header("OSPF LSR: ", "Link State Request Packet",
715 fraglen);
716 show_space();
717 }
718 lsr = ospf->ospf6_lsr;
719 nlsah = 0;
720 while ((uchar_t *)lsr < ((uchar_t *)ospf + fraglen)) {
721 if ((uchar_t *)lsr + sizeof (struct lsr6) >
722 ((uchar_t *)ospf + fraglen)) {
723 trunc = B_TRUE;
724 break;
725 }
726 nlsah++;
727 if (flags & F_DTAIL) {
728 ospf6_print_ls_type(flags, ntohl(lsr->ls_type),
729 lsr->ls_stateid, lsr->ls_router);
730 }
731 ++lsr;
732 }
733 if (flags & F_SUM) {
734 sprintf(sum_line, "%d LSAs", nlsah);
735 sum_line += strlen(sum_line);
736 }
737 break;
738
739 case OSPF_TYPE_LSU:
740 if (fraglen < OSPF6_MIN_HEADER_SIZE +
741 OSPF_MIN_LSU_HEADER_SIZE) {
742 trunc = B_TRUE;
743 break;
744 }
745 if (flags & F_DTAIL) {
746 show_header("OSPF LSU: ", "Link State Update Packet",
747 fraglen);
748 show_space();
749 }
750 lsa = ospf->ospf6_lsu.lsu_lsa;
751 nlsa = ntohl(ospf->ospf6_lsu.lsu_count);
752 if (flags & F_SUM) {
753 sprintf(sum_line, "%d LSAs", nlsa);
754 sum_line += strlen(sum_line);
755 break;
756 }
757 while (nlsa-- != 0) {
758 uchar_t *fragend = (uchar_t *)ospf + fraglen;
759 if (((uchar_t *)lsa >= fragend) ||
760 ((uchar_t *)lsa + sizeof (struct lsa_hdr) >
761 fragend) ||
762 ((uchar_t *)lsa + ntohs(lsa->ls6_hdr.ls6_length) >
763 fragend)) {
764 trunc = B_TRUE;
765 break;
766 }
767
768 if (interpret_ospf6_lsa(flags, lsa, fragend) < 0) {
769 trunc = B_TRUE;
770 break;
771 }
772 lsa = (struct lsa6 *)((uchar_t *)lsa +
773 ntohs(lsa->ls6_hdr.ls6_length));
774 }
775 break;
776
777 case OSPF_TYPE_LSA:
778 if (flags & F_DTAIL) {
779 show_header("OSPF LSA: ", "Link State Ack Packet",
780 fraglen);
781 show_space();
782 }
783 lsah = ospf->ospf6_lsa.lsa_lshdr;
784 nlsah = 0;
785 while ((uchar_t *)lsah < ((uchar_t *)ospf + fraglen)) {
786 if ((uchar_t *)lsah + sizeof (struct lsa6_hdr) >
787 ((uchar_t *)ospf + fraglen)) {
788 trunc = B_TRUE;
789 break;
790 }
791 nlsah++;
792 if (flags & F_DTAIL)
793 interpret_ospf6_lsa_hdr(flags, lsah);
794 ++lsah;
795 }
796 if (flags & F_SUM) {
797 sprintf(sum_line, "%d LSAs", nlsah);
798 sum_line += strlen(sum_line);
799 }
800 break;
801
802 default:
803 /* NOTREACHED */
804 break;
805 }
806 if (trunc) {
807 if (flags & F_SUM)
808 sprintf(sum_line, "--truncated");
809 if (flags & F_DTAIL)
810 snprintf(get_line(0, 0), get_line_remain(),
811 "--truncated");
812 }
813
814 return (fraglen);
815 }
816