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