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