1b0453382SBill Fenner /* 2b0453382SBill Fenner * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 3b0453382SBill Fenner * The Regents of the University of California. All rights reserved. 4b0453382SBill Fenner * 5b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without 6b0453382SBill Fenner * modification, are permitted provided that: (1) source code distributions 7b0453382SBill Fenner * retain the above copyright notice and this paragraph in its entirety, (2) 8b0453382SBill Fenner * distributions including binary code include the above copyright notice and 9b0453382SBill Fenner * this paragraph in its entirety in the documentation or other materials 10b0453382SBill Fenner * provided with the distribution, and (3) all advertising materials mentioning 11b0453382SBill Fenner * features or use of this software display the following acknowledgement: 12b0453382SBill Fenner * ``This product includes software developed by the University of California, 13b0453382SBill Fenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14b0453382SBill Fenner * the University nor the names of its contributors may be used to endorse 15b0453382SBill Fenner * or promote products derived from this software without specific prior 16b0453382SBill Fenner * written permission. 17b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18b0453382SBill Fenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19b0453382SBill Fenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20b0453382SBill Fenner * 21b0453382SBill Fenner * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) 22b0453382SBill Fenner */ 23b0453382SBill Fenner 24b0453382SBill Fenner #ifndef lint 25b0453382SBill Fenner static const char rcsid[] = 26b0453382SBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.2 1999/11/21 09:36:58 fenner Exp $ (LBL)"; 27b0453382SBill Fenner #endif 28b0453382SBill Fenner 29b0453382SBill Fenner #ifdef HAVE_CONFIG_H 30b0453382SBill Fenner #include "config.h" 31b0453382SBill Fenner #endif 32b0453382SBill Fenner 33b0453382SBill Fenner #include <sys/param.h> 34b0453382SBill Fenner #include <sys/time.h> 35b0453382SBill Fenner #include <sys/socket.h> 36b0453382SBill Fenner 37b0453382SBill Fenner #include <netinet/in.h> 38b0453382SBill Fenner #include <netinet/in_systm.h> 39b0453382SBill Fenner #include <netinet/ip.h> 40b0453382SBill Fenner #include <netinet/ip_var.h> 41b0453382SBill Fenner 42b0453382SBill Fenner #include <ctype.h> 43b0453382SBill Fenner #include <stdio.h> 44b0453382SBill Fenner #include <string.h> 45b0453382SBill Fenner 46b0453382SBill Fenner #include "interface.h" 47b0453382SBill Fenner #include "addrtoname.h" 48b0453382SBill Fenner 49b0453382SBill Fenner #include "ospf6.h" 50b0453382SBill Fenner 51b0453382SBill Fenner struct bits { 52b0453382SBill Fenner u_int32_t bit; 53b0453382SBill Fenner const char *str; 54b0453382SBill Fenner }; 55b0453382SBill Fenner 56b0453382SBill Fenner static const struct bits ospf6_option_bits[] = { 57b0453382SBill Fenner { OSPF6_OPTION_V6, "V6" }, 58b0453382SBill Fenner { OSPF6_OPTION_E, "E" }, 59b0453382SBill Fenner { OSPF6_OPTION_MC, "MC" }, 60b0453382SBill Fenner { OSPF6_OPTION_N, "N" }, 61b0453382SBill Fenner { OSPF6_OPTION_R, "R" }, 62b0453382SBill Fenner { OSPF6_OPTION_DC, "DC" }, 63b0453382SBill Fenner { 0, NULL } 64b0453382SBill Fenner }; 65b0453382SBill Fenner 66b0453382SBill Fenner static const struct bits ospf6_rla_flag_bits[] = { 67b0453382SBill Fenner { RLA_FLAG_B, "B" }, 68b0453382SBill Fenner { RLA_FLAG_E, "E" }, 69b0453382SBill Fenner { RLA_FLAG_V, "V" }, 70b0453382SBill Fenner { RLA_FLAG_W, "W" }, 71b0453382SBill Fenner { 0, NULL } 72b0453382SBill Fenner }; 73b0453382SBill Fenner 74b0453382SBill Fenner static struct tok type2str[] = { 75b0453382SBill Fenner { OSPF_TYPE_UMD, "umd" }, 76b0453382SBill Fenner { OSPF_TYPE_HELLO, "hello" }, 77b0453382SBill Fenner { OSPF_TYPE_DB, "dd" }, 78b0453382SBill Fenner { OSPF_TYPE_LSR, "ls_req" }, 79b0453382SBill Fenner { OSPF_TYPE_LSU, "ls_upd" }, 80b0453382SBill Fenner { OSPF_TYPE_LSA, "ls_ack" }, 81b0453382SBill Fenner { 0, NULL } 82b0453382SBill Fenner }; 83b0453382SBill Fenner 84b0453382SBill Fenner static char tstr[] = " [|ospf]"; 85b0453382SBill Fenner 86b0453382SBill Fenner /* Forwards */ 87b0453382SBill Fenner static inline void ospf6_print_seqage(u_int32_t, time_t); 88b0453382SBill Fenner static inline void ospf6_print_bits(const struct bits *, u_char); 89b0453382SBill Fenner static void ospf6_print_ls_type(u_int, const rtrid_t *, 90b0453382SBill Fenner const rtrid_t *, const char *); 91b0453382SBill Fenner static int ospf6_print_lshdr(const struct lsa_hdr *); 92b0453382SBill Fenner static int ospf6_print_lsa(const struct lsa *); 93b0453382SBill Fenner static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *); 94b0453382SBill Fenner 95b0453382SBill Fenner static inline void 96b0453382SBill Fenner ospf6_print_seqage(register u_int32_t seq, register time_t us) 97b0453382SBill Fenner { 98b0453382SBill Fenner register time_t sec = us % 60; 99b0453382SBill Fenner register time_t mins = (us / 60) % 60; 100b0453382SBill Fenner register time_t hour = us / 3600; 101b0453382SBill Fenner 102b0453382SBill Fenner printf(" S %X age ", seq); 103b0453382SBill Fenner if (hour) 104b0453382SBill Fenner printf("%u:%02u:%02u", 105b0453382SBill Fenner (u_int32_t) hour, (u_int32_t) mins, (u_int32_t) sec); 106b0453382SBill Fenner else if (mins) 107b0453382SBill Fenner printf("%u:%02u", (u_int32_t) mins, (u_int32_t) sec); 108b0453382SBill Fenner else 109b0453382SBill Fenner printf("%u", (u_int32_t) sec); 110b0453382SBill Fenner } 111b0453382SBill Fenner 112b0453382SBill Fenner 113b0453382SBill Fenner static inline void 114b0453382SBill Fenner ospf6_print_bits(register const struct bits *bp, register u_char options) 115b0453382SBill Fenner { 116b0453382SBill Fenner register char sep = ' '; 117b0453382SBill Fenner 118b0453382SBill Fenner do { 119b0453382SBill Fenner if (options & bp->bit) { 120b0453382SBill Fenner printf("%c%s", sep, bp->str); 121b0453382SBill Fenner sep = '/'; 122b0453382SBill Fenner } 123b0453382SBill Fenner } while ((++bp)->bit); 124b0453382SBill Fenner } 125b0453382SBill Fenner 126b0453382SBill Fenner static void 127b0453382SBill Fenner ospf6_print_ls_type(register u_int ls_type, 128b0453382SBill Fenner register const rtrid_t *ls_stateid, 129b0453382SBill Fenner register const rtrid_t *ls_router, register const char *fmt) 130b0453382SBill Fenner { 131b0453382SBill Fenner char *scope; 132b0453382SBill Fenner 133b0453382SBill Fenner switch (ls_type & LS_SCOPE_MASK) { 134b0453382SBill Fenner case LS_SCOPE_LINKLOCAL: 135b0453382SBill Fenner scope = "linklocal-"; 136b0453382SBill Fenner break; 137b0453382SBill Fenner case LS_SCOPE_AREA: 138b0453382SBill Fenner scope = "area-"; 139b0453382SBill Fenner break; 140b0453382SBill Fenner case LS_SCOPE_AS: 141b0453382SBill Fenner scope = "AS-"; 142b0453382SBill Fenner break; 143b0453382SBill Fenner default: 144b0453382SBill Fenner scope = ""; 145b0453382SBill Fenner break; 146b0453382SBill Fenner } 147b0453382SBill Fenner 148b0453382SBill Fenner switch (ls_type & LS_TYPE_MASK) { 149b0453382SBill Fenner case LS_TYPE_ROUTER: 150b0453382SBill Fenner printf(" %srtr %s", scope, ipaddr_string(ls_router)); 151b0453382SBill Fenner break; 152b0453382SBill Fenner 153b0453382SBill Fenner case LS_TYPE_NETWORK: 154b0453382SBill Fenner printf(" %snet dr %s if %s", scope, 155b0453382SBill Fenner ipaddr_string(ls_router), 156b0453382SBill Fenner ipaddr_string(ls_stateid)); 157b0453382SBill Fenner break; 158b0453382SBill Fenner 159b0453382SBill Fenner case LS_TYPE_INTER_AP: 160b0453382SBill Fenner printf(" %sinter-area-prefix %s abr %s", scope, 161b0453382SBill Fenner ipaddr_string(ls_stateid), 162b0453382SBill Fenner ipaddr_string(ls_router)); 163b0453382SBill Fenner break; 164b0453382SBill Fenner 165b0453382SBill Fenner case LS_TYPE_INTER_AR: 166b0453382SBill Fenner printf(" %sinter-area-router %s rtr %s", scope, 167b0453382SBill Fenner ipaddr_string(ls_router), 168b0453382SBill Fenner ipaddr_string(ls_stateid)); 169b0453382SBill Fenner break; 170b0453382SBill Fenner 171b0453382SBill Fenner case LS_TYPE_ASE: 172b0453382SBill Fenner printf(" %sase %s asbr %s", scope, 173b0453382SBill Fenner ipaddr_string(ls_stateid), 174b0453382SBill Fenner ipaddr_string(ls_router)); 175b0453382SBill Fenner break; 176b0453382SBill Fenner 177b0453382SBill Fenner case LS_TYPE_GROUP: 178b0453382SBill Fenner printf(" %sgroup %s rtr %s", scope, 179b0453382SBill Fenner ipaddr_string(ls_stateid), 180b0453382SBill Fenner ipaddr_string(ls_router)); 181b0453382SBill Fenner break; 182b0453382SBill Fenner 183b0453382SBill Fenner case LS_TYPE_TYPE7: 184b0453382SBill Fenner printf(" %stype7 %s rtr %s", scope, 185b0453382SBill Fenner ipaddr_string(ls_stateid), 186b0453382SBill Fenner ipaddr_string(ls_router)); 187b0453382SBill Fenner break; 188b0453382SBill Fenner 189b0453382SBill Fenner case LS_TYPE_LINK: 190b0453382SBill Fenner printf(" %slink %s rtr %s", scope, 191b0453382SBill Fenner ipaddr_string(ls_stateid), 192b0453382SBill Fenner ipaddr_string(ls_router)); 193b0453382SBill Fenner break; 194b0453382SBill Fenner 195b0453382SBill Fenner case LS_TYPE_INTRA_AP: 196b0453382SBill Fenner printf(" %sintra-area-prefix %s rtr %s", scope, 197b0453382SBill Fenner ipaddr_string(ls_stateid), 198b0453382SBill Fenner ipaddr_string(ls_router)); 199b0453382SBill Fenner break; 200b0453382SBill Fenner 201b0453382SBill Fenner default: 202b0453382SBill Fenner printf(" %s", scope); 203b0453382SBill Fenner printf(fmt, ls_type); 204b0453382SBill Fenner break; 205b0453382SBill Fenner } 206b0453382SBill Fenner 207b0453382SBill Fenner } 208b0453382SBill Fenner 209b0453382SBill Fenner static int 210b0453382SBill Fenner ospf6_print_lshdr(register const struct lsa_hdr *lshp) 211b0453382SBill Fenner { 212b0453382SBill Fenner 213b0453382SBill Fenner TCHECK(lshp->ls_type); 214b0453382SBill Fenner printf(" {"); /* } (ctags) */ 215b0453382SBill Fenner 216b0453382SBill Fenner TCHECK(lshp->ls_seq); 217b0453382SBill Fenner ospf6_print_seqage(ntohl(lshp->ls_seq), ntohs(lshp->ls_age)); 218b0453382SBill Fenner ospf6_print_ls_type(ntohs(lshp->ls_type), &lshp->ls_stateid, 219b0453382SBill Fenner &lshp->ls_router, "ls_type %d"); 220b0453382SBill Fenner 221b0453382SBill Fenner return (0); 222b0453382SBill Fenner trunc: 223b0453382SBill Fenner return (1); 224b0453382SBill Fenner } 225b0453382SBill Fenner 226b0453382SBill Fenner static int 227b0453382SBill Fenner ospf6_print_lsaprefix(register const struct lsa_prefix *lsapp) 228b0453382SBill Fenner { 229b0453382SBill Fenner int k; 230b0453382SBill Fenner struct in6_addr prefix; 231b0453382SBill Fenner 232b0453382SBill Fenner TCHECK(*lsapp); 233b0453382SBill Fenner k = (lsapp->lsa_p_len + 31) / 32; 234b0453382SBill Fenner if (k * 4 > sizeof(struct in6_addr)) { 235b0453382SBill Fenner printf("??prefixlen %d??", lsapp->lsa_p_len); 236b0453382SBill Fenner goto trunc; 237b0453382SBill Fenner } 238b0453382SBill Fenner memset(&prefix, 0, sizeof(prefix)); 239b0453382SBill Fenner memcpy(&prefix, lsapp->lsa_p_prefix, k * 4); 240b0453382SBill Fenner printf(" %s/%d", ip6addr_string(&prefix), 241b0453382SBill Fenner lsapp->lsa_p_len); 242b0453382SBill Fenner if (lsapp->lsa_p_opt) 243b0453382SBill Fenner printf("(opt=%x)", lsapp->lsa_p_opt); 244b0453382SBill Fenner return sizeof(*lsapp) - 4 + k * 4; 245b0453382SBill Fenner 246b0453382SBill Fenner trunc: 247b0453382SBill Fenner return -1; 248b0453382SBill Fenner } 249b0453382SBill Fenner 250b0453382SBill Fenner 251b0453382SBill Fenner /* 252b0453382SBill Fenner * Print a single link state advertisement. If truncated return 1, else 0. 253b0453382SBill Fenner */ 254b0453382SBill Fenner static int 255b0453382SBill Fenner ospf6_print_lsa(register const struct lsa *lsap) 256b0453382SBill Fenner { 257b0453382SBill Fenner register const u_char *ls_end; 258b0453382SBill Fenner register const struct rlalink *rlp; 259b0453382SBill Fenner #if 0 260b0453382SBill Fenner register const struct tos_metric *tosp; 261b0453382SBill Fenner #endif 262b0453382SBill Fenner register const rtrid_t *ap; 263b0453382SBill Fenner #if 0 264b0453382SBill Fenner register const struct aslametric *almp; 265b0453382SBill Fenner register const struct mcla *mcp; 266b0453382SBill Fenner #endif 267b0453382SBill Fenner register const struct llsa *llsap; 268b0453382SBill Fenner register const struct lsa_prefix *lsapp; 269b0453382SBill Fenner #if 0 270b0453382SBill Fenner register const u_int32_t *lp; 271b0453382SBill Fenner #endif 272b0453382SBill Fenner register int j, k; 273b0453382SBill Fenner 274b0453382SBill Fenner if (ospf6_print_lshdr(&lsap->ls_hdr)) 275b0453382SBill Fenner return (1); 276b0453382SBill Fenner TCHECK(lsap->ls_hdr.ls_length); 277b0453382SBill Fenner ls_end = (u_char *)lsap + ntohs(lsap->ls_hdr.ls_length); 278b0453382SBill Fenner switch (ntohs(lsap->ls_hdr.ls_type)) { 279b0453382SBill Fenner case LS_TYPE_ROUTER | LS_SCOPE_AREA: 280b0453382SBill Fenner TCHECK(lsap->lsa_un.un_rla.rla_flags); 281b0453382SBill Fenner ospf6_print_bits(ospf6_rla_flag_bits, 282b0453382SBill Fenner lsap->lsa_un.un_rla.rla_flags); 283b0453382SBill Fenner TCHECK(lsap->lsa_un.un_rla.rla_options); 284b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 285b0453382SBill Fenner ntohl(lsap->lsa_un.un_rla.rla_options)); 286b0453382SBill Fenner 287b0453382SBill Fenner TCHECK(lsap->lsa_un.un_rla.rla_link); 288b0453382SBill Fenner rlp = lsap->lsa_un.un_rla.rla_link; 289b0453382SBill Fenner while (rlp + sizeof(*rlp) <= (struct rlalink *)ls_end) { 290b0453382SBill Fenner TCHECK(*rlp); 291b0453382SBill Fenner printf(" {"); /* } (ctags) */ 292b0453382SBill Fenner switch (rlp->link_type) { 293b0453382SBill Fenner 294b0453382SBill Fenner case RLA_TYPE_VIRTUAL: 295b0453382SBill Fenner printf(" virt"); 296b0453382SBill Fenner /* Fall through */ 297b0453382SBill Fenner 298b0453382SBill Fenner case RLA_TYPE_ROUTER: 299b0453382SBill Fenner printf(" nbrid %s nbrif %s if %s", 300b0453382SBill Fenner ipaddr_string(&rlp->link_nrtid), 301b0453382SBill Fenner ipaddr_string(&rlp->link_nifid), 302b0453382SBill Fenner ipaddr_string(&rlp->link_ifid)); 303b0453382SBill Fenner break; 304b0453382SBill Fenner 305b0453382SBill Fenner case RLA_TYPE_TRANSIT: 306b0453382SBill Fenner printf(" dr %s drif %s if %s", 307b0453382SBill Fenner ipaddr_string(&rlp->link_nrtid), 308b0453382SBill Fenner ipaddr_string(&rlp->link_nifid), 309b0453382SBill Fenner ipaddr_string(&rlp->link_ifid)); 310b0453382SBill Fenner break; 311b0453382SBill Fenner 312b0453382SBill Fenner default: 313b0453382SBill Fenner /* { (ctags) */ 314b0453382SBill Fenner printf(" ??RouterLinksType 0x%02x?? }", 315b0453382SBill Fenner rlp->link_type); 316b0453382SBill Fenner return (0); 317b0453382SBill Fenner } 318b0453382SBill Fenner printf(" metric %d", ntohs(rlp->link_metric)); 319b0453382SBill Fenner /* { (ctags) */ 320b0453382SBill Fenner printf(" }"); 321b0453382SBill Fenner rlp++; 322b0453382SBill Fenner } 323b0453382SBill Fenner break; 324b0453382SBill Fenner 325b0453382SBill Fenner case LS_TYPE_NETWORK | LS_SCOPE_AREA: 326b0453382SBill Fenner TCHECK(lsap->lsa_un.un_nla.nla_options); 327b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 328b0453382SBill Fenner ntohl(lsap->lsa_un.un_nla.nla_options)); 329b0453382SBill Fenner printf(" rtrs"); 330b0453382SBill Fenner ap = lsap->lsa_un.un_nla.nla_router; 331b0453382SBill Fenner while ((u_char *)ap < ls_end) { 332b0453382SBill Fenner TCHECK(*ap); 333b0453382SBill Fenner printf(" %s", ipaddr_string(ap)); 334b0453382SBill Fenner ++ap; 335b0453382SBill Fenner } 336b0453382SBill Fenner break; 337b0453382SBill Fenner 338b0453382SBill Fenner case LS_TYPE_INTER_AP | LS_SCOPE_AREA: 339b0453382SBill Fenner TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); 340b0453382SBill Fenner printf(" metric %u", 341b0453382SBill Fenner (u_int32_t)ntohl(lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); 342b0453382SBill Fenner lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix; 343b0453382SBill Fenner while (lsapp + sizeof(lsapp) <= (struct lsa_prefix *)ls_end) { 344b0453382SBill Fenner k = ospf6_print_lsaprefix(lsapp); 345b0453382SBill Fenner if (k < 0) 346b0453382SBill Fenner goto trunc; 347b0453382SBill Fenner lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k); 348b0453382SBill Fenner } 349b0453382SBill Fenner break; 350b0453382SBill Fenner 351b0453382SBill Fenner #if 0 352b0453382SBill Fenner case LS_TYPE_SUM_ABR: 353b0453382SBill Fenner TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); 354b0453382SBill Fenner lp = lsap->lsa_un.un_sla.sla_tosmetric; 355b0453382SBill Fenner while ((u_char *)lp < ls_end) { 356b0453382SBill Fenner register u_int32_t ul; 357b0453382SBill Fenner 358b0453382SBill Fenner TCHECK(*lp); 359b0453382SBill Fenner ul = ntohl(*lp); 360b0453382SBill Fenner printf(" tos %d metric %d", 361b0453382SBill Fenner (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS, 362b0453382SBill Fenner ul & SLA_MASK_METRIC); 363b0453382SBill Fenner ++lp; 364b0453382SBill Fenner } 365b0453382SBill Fenner break; 366b0453382SBill Fenner 367b0453382SBill Fenner case LS_TYPE_ASE: 368b0453382SBill Fenner TCHECK(lsap->lsa_un.un_nla.nla_mask); 369b0453382SBill Fenner printf(" mask %s", 370b0453382SBill Fenner ipaddr_string(&lsap->lsa_un.un_asla.asla_mask)); 371b0453382SBill Fenner 372b0453382SBill Fenner TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); 373b0453382SBill Fenner almp = lsap->lsa_un.un_asla.asla_metric; 374b0453382SBill Fenner while ((u_char *)almp < ls_end) { 375b0453382SBill Fenner register u_int32_t ul; 376b0453382SBill Fenner 377b0453382SBill Fenner TCHECK(almp->asla_tosmetric); 378b0453382SBill Fenner ul = ntohl(almp->asla_tosmetric); 379b0453382SBill Fenner printf(" type %d tos %d metric %d", 380b0453382SBill Fenner (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1, 381b0453382SBill Fenner (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS, 382b0453382SBill Fenner (ul & ASLA_MASK_METRIC)); 383b0453382SBill Fenner TCHECK(almp->asla_forward); 384b0453382SBill Fenner if (almp->asla_forward.s_addr) { 385b0453382SBill Fenner printf(" forward %s", 386b0453382SBill Fenner ipaddr_string(&almp->asla_forward)); 387b0453382SBill Fenner } 388b0453382SBill Fenner TCHECK(almp->asla_tag); 389b0453382SBill Fenner if (almp->asla_tag.s_addr) { 390b0453382SBill Fenner printf(" tag %s", 391b0453382SBill Fenner ipaddr_string(&almp->asla_tag)); 392b0453382SBill Fenner } 393b0453382SBill Fenner ++almp; 394b0453382SBill Fenner } 395b0453382SBill Fenner break; 396b0453382SBill Fenner 397b0453382SBill Fenner case LS_TYPE_GROUP: 398b0453382SBill Fenner /* Multicast extensions as of 23 July 1991 */ 399b0453382SBill Fenner mcp = lsap->lsa_un.un_mcla; 400b0453382SBill Fenner while ((u_char *)mcp < ls_end) { 401b0453382SBill Fenner TCHECK(mcp->mcla_vid); 402b0453382SBill Fenner switch (ntohl(mcp->mcla_vtype)) { 403b0453382SBill Fenner 404b0453382SBill Fenner case MCLA_VERTEX_ROUTER: 405b0453382SBill Fenner printf(" rtr rtrid %s", 406b0453382SBill Fenner ipaddr_string(&mcp->mcla_vid)); 407b0453382SBill Fenner break; 408b0453382SBill Fenner 409b0453382SBill Fenner case MCLA_VERTEX_NETWORK: 410b0453382SBill Fenner printf(" net dr %s", 411b0453382SBill Fenner ipaddr_string(&mcp->mcla_vid)); 412b0453382SBill Fenner break; 413b0453382SBill Fenner 414b0453382SBill Fenner default: 415b0453382SBill Fenner printf(" ??VertexType %u??", 416b0453382SBill Fenner (u_int32_t)ntohl(mcp->mcla_vtype)); 417b0453382SBill Fenner break; 418b0453382SBill Fenner } 419b0453382SBill Fenner ++mcp; 420b0453382SBill Fenner } 421b0453382SBill Fenner #endif 422b0453382SBill Fenner 423b0453382SBill Fenner case LS_TYPE_LINK: 424b0453382SBill Fenner /* Link LSA */ 425b0453382SBill Fenner llsap = &lsap->lsa_un.un_llsa; 426b0453382SBill Fenner TCHECK(llsap->llsa_options); 427b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, ntohl(llsap->llsa_options)); 428b0453382SBill Fenner TCHECK(llsap->llsa_nprefix); 429b0453382SBill Fenner printf(" pri %d lladdr %s npref %d", llsap->llsa_priority, 430b0453382SBill Fenner ip6addr_string(&llsap->llsa_lladdr), 431b0453382SBill Fenner (u_int32_t)ntohl(llsap->llsa_nprefix)); 432b0453382SBill Fenner lsapp = llsap->llsa_prefix; 433b0453382SBill Fenner for (j = 0; j < ntohl(llsap->llsa_nprefix); j++) { 434b0453382SBill Fenner k = ospf6_print_lsaprefix(lsapp); 435b0453382SBill Fenner if (k < 0) 436b0453382SBill Fenner goto trunc; 437b0453382SBill Fenner lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k); 438b0453382SBill Fenner } 439b0453382SBill Fenner break; 440b0453382SBill Fenner 441b0453382SBill Fenner case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: 442b0453382SBill Fenner /* Intra-Area-Prefix LSA */ 443b0453382SBill Fenner TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); 444b0453382SBill Fenner ospf6_print_ls_type( 445b0453382SBill Fenner ntohs(lsap->lsa_un.un_intra_ap.intra_ap_lstype), 446b0453382SBill Fenner &lsap->lsa_un.un_intra_ap.intra_ap_lsid, 447b0453382SBill Fenner &lsap->lsa_un.un_intra_ap.intra_ap_rtid, 448b0453382SBill Fenner "LinkStateType %d"); 449b0453382SBill Fenner TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 450b0453382SBill Fenner printf(" npref %d", 451b0453382SBill Fenner ntohs(lsap->lsa_un.un_intra_ap.intra_ap_nprefix)); 452b0453382SBill Fenner 453b0453382SBill Fenner lsapp = lsap->lsa_un.un_intra_ap.intra_ap_prefix; 454b0453382SBill Fenner for (j = 0; 455b0453382SBill Fenner j < ntohs(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 456b0453382SBill Fenner j++) { 457b0453382SBill Fenner k = ospf6_print_lsaprefix(lsapp); 458b0453382SBill Fenner if (k < 0) 459b0453382SBill Fenner goto trunc; 460b0453382SBill Fenner lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k); 461b0453382SBill Fenner } 462b0453382SBill Fenner break; 463b0453382SBill Fenner 464b0453382SBill Fenner default: 465b0453382SBill Fenner printf(" ??LinkStateType 0x%04x??", 466b0453382SBill Fenner ntohs(lsap->ls_hdr.ls_type)); 467b0453382SBill Fenner } 468b0453382SBill Fenner 469b0453382SBill Fenner /* { (ctags) */ 470b0453382SBill Fenner fputs(" }", stdout); 471b0453382SBill Fenner return (0); 472b0453382SBill Fenner trunc: 473b0453382SBill Fenner fputs(" }", stdout); 474b0453382SBill Fenner return (1); 475b0453382SBill Fenner } 476b0453382SBill Fenner 477b0453382SBill Fenner static int 478b0453382SBill Fenner ospf6_decode_v3(register const struct ospf6hdr *op, 479b0453382SBill Fenner register const u_char *dataend) 480b0453382SBill Fenner { 481b0453382SBill Fenner register const rtrid_t *ap; 482b0453382SBill Fenner register const struct lsr *lsrp; 483b0453382SBill Fenner register const struct lsa_hdr *lshp; 484b0453382SBill Fenner register const struct lsa *lsap; 485b0453382SBill Fenner register char sep; 486b0453382SBill Fenner register int i; 487b0453382SBill Fenner 488b0453382SBill Fenner switch (op->ospf6_type) { 489b0453382SBill Fenner 490b0453382SBill Fenner case OSPF_TYPE_UMD: 491b0453382SBill Fenner /* 492b0453382SBill Fenner * Rob Coltun's special monitoring packets; 493b0453382SBill Fenner * do nothing 494b0453382SBill Fenner */ 495b0453382SBill Fenner break; 496b0453382SBill Fenner 497b0453382SBill Fenner case OSPF_TYPE_HELLO: 498b0453382SBill Fenner if (vflag) { 499b0453382SBill Fenner TCHECK(op->ospf6_hello.hello_deadint); 500b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 501b0453382SBill Fenner ntohl(op->ospf6_hello.hello_options)); 502b0453382SBill Fenner printf(" ifid %s pri %d int %d dead %u", 503b0453382SBill Fenner ipaddr_string(&op->ospf6_hello.hello_ifid), 504b0453382SBill Fenner op->ospf6_hello.hello_priority, 505b0453382SBill Fenner ntohs(op->ospf6_hello.hello_helloint), 506b0453382SBill Fenner ntohs(op->ospf6_hello.hello_deadint)); 507b0453382SBill Fenner } 508b0453382SBill Fenner TCHECK(op->ospf6_hello.hello_dr); 509b0453382SBill Fenner if (op->ospf6_hello.hello_dr != 0) 510b0453382SBill Fenner printf(" dr %s", 511b0453382SBill Fenner ipaddr_string(&op->ospf6_hello.hello_dr)); 512b0453382SBill Fenner TCHECK(op->ospf6_hello.hello_bdr); 513b0453382SBill Fenner if (op->ospf6_hello.hello_bdr != 0) 514b0453382SBill Fenner printf(" bdr %s", 515b0453382SBill Fenner ipaddr_string(&op->ospf6_hello.hello_bdr)); 516b0453382SBill Fenner if (vflag) { 517b0453382SBill Fenner printf(" nbrs"); 518b0453382SBill Fenner ap = op->ospf6_hello.hello_neighbor; 519b0453382SBill Fenner while ((u_char *)ap < dataend) { 520b0453382SBill Fenner TCHECK(*ap); 521b0453382SBill Fenner printf(" %s", ipaddr_string(ap)); 522b0453382SBill Fenner ++ap; 523b0453382SBill Fenner } 524b0453382SBill Fenner } 525b0453382SBill Fenner break; /* HELLO */ 526b0453382SBill Fenner 527b0453382SBill Fenner case OSPF_TYPE_DB: 528b0453382SBill Fenner TCHECK(op->ospf6_db.db_options); 529b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 530b0453382SBill Fenner ntohl(op->ospf6_db.db_options)); 531b0453382SBill Fenner sep = ' '; 532b0453382SBill Fenner TCHECK(op->ospf6_db.db_flags); 533b0453382SBill Fenner if (op->ospf6_db.db_flags & OSPF6_DB_INIT) { 534b0453382SBill Fenner printf("%cI", sep); 535b0453382SBill Fenner sep = '/'; 536b0453382SBill Fenner } 537b0453382SBill Fenner if (op->ospf6_db.db_flags & OSPF6_DB_MORE) { 538b0453382SBill Fenner printf("%cM", sep); 539b0453382SBill Fenner sep = '/'; 540b0453382SBill Fenner } 541b0453382SBill Fenner if (op->ospf6_db.db_flags & OSPF6_DB_MASTER) { 542b0453382SBill Fenner printf("%cMS", sep); 543b0453382SBill Fenner sep = '/'; 544b0453382SBill Fenner } 545b0453382SBill Fenner TCHECK(op->ospf6_db.db_seq); 546b0453382SBill Fenner printf(" mtu %u S %X", ntohs(op->ospf6_db.db_mtu), 547b0453382SBill Fenner (u_int32_t)ntohl(op->ospf6_db.db_seq)); 548b0453382SBill Fenner 549b0453382SBill Fenner if (vflag) { 550b0453382SBill Fenner /* Print all the LS adv's */ 551b0453382SBill Fenner lshp = op->ospf6_db.db_lshdr; 552b0453382SBill Fenner 553b0453382SBill Fenner while (!ospf6_print_lshdr(lshp)) { 554b0453382SBill Fenner /* { (ctags) */ 555b0453382SBill Fenner printf(" }"); 556b0453382SBill Fenner ++lshp; 557b0453382SBill Fenner } 558b0453382SBill Fenner } 559b0453382SBill Fenner break; 560b0453382SBill Fenner 561b0453382SBill Fenner case OSPF_TYPE_LSR: 562b0453382SBill Fenner if (vflag) { 563b0453382SBill Fenner lsrp = op->ospf6_lsr; 564b0453382SBill Fenner while ((u_char *)lsrp < dataend) { 565b0453382SBill Fenner TCHECK(*lsrp); 566b0453382SBill Fenner printf(" {"); /* } (ctags) */ 567b0453382SBill Fenner ospf6_print_ls_type(ntohs(lsrp->ls_type), 568b0453382SBill Fenner &lsrp->ls_stateid, 569b0453382SBill Fenner &lsrp->ls_router, 570b0453382SBill Fenner "LinkStateType %d"); 571b0453382SBill Fenner /* { (ctags) */ 572b0453382SBill Fenner printf(" }"); 573b0453382SBill Fenner ++lsrp; 574b0453382SBill Fenner } 575b0453382SBill Fenner } 576b0453382SBill Fenner break; 577b0453382SBill Fenner 578b0453382SBill Fenner case OSPF_TYPE_LSU: 579b0453382SBill Fenner if (vflag) { 580b0453382SBill Fenner lsap = op->ospf6_lsu.lsu_lsa; 581b0453382SBill Fenner TCHECK(op->ospf6_lsu.lsu_count); 582b0453382SBill Fenner i = ntohl(op->ospf6_lsu.lsu_count); 583b0453382SBill Fenner while (i--) { 584b0453382SBill Fenner if (ospf6_print_lsa(lsap)) 585b0453382SBill Fenner goto trunc; 586b0453382SBill Fenner lsap = (struct lsa *)((u_char *)lsap + 587b0453382SBill Fenner ntohs(lsap->ls_hdr.ls_length)); 588b0453382SBill Fenner } 589b0453382SBill Fenner } 590b0453382SBill Fenner break; 591b0453382SBill Fenner 592b0453382SBill Fenner 593b0453382SBill Fenner case OSPF_TYPE_LSA: 594b0453382SBill Fenner if (vflag) { 595b0453382SBill Fenner lshp = op->ospf6_lsa.lsa_lshdr; 596b0453382SBill Fenner 597b0453382SBill Fenner while (!ospf6_print_lshdr(lshp)) { 598b0453382SBill Fenner /* { (ctags) */ 599b0453382SBill Fenner printf(" }"); 600b0453382SBill Fenner ++lshp; 601b0453382SBill Fenner } 602b0453382SBill Fenner } 603b0453382SBill Fenner break; 604b0453382SBill Fenner 605b0453382SBill Fenner default: 606b0453382SBill Fenner printf("v3 type %d", op->ospf6_type); 607b0453382SBill Fenner break; 608b0453382SBill Fenner } 609b0453382SBill Fenner return (0); 610b0453382SBill Fenner trunc: 611b0453382SBill Fenner return (1); 612b0453382SBill Fenner } 613b0453382SBill Fenner 614b0453382SBill Fenner void 615b0453382SBill Fenner ospf6_print(register const u_char *bp, register u_int length) 616b0453382SBill Fenner { 617b0453382SBill Fenner register const struct ospf6hdr *op; 618b0453382SBill Fenner register const u_char *dataend; 619b0453382SBill Fenner register const char *cp; 620b0453382SBill Fenner 621b0453382SBill Fenner op = (struct ospf6hdr *)bp; 622b0453382SBill Fenner 623b0453382SBill Fenner /* If the type is valid translate it, or just print the type */ 624b0453382SBill Fenner /* value. If it's not valid, say so and return */ 625b0453382SBill Fenner TCHECK(op->ospf6_type); 626b0453382SBill Fenner cp = tok2str(type2str, "type%d", op->ospf6_type); 627b0453382SBill Fenner printf(" OSPFv%d-%s %d:", op->ospf6_version, cp, length); 628b0453382SBill Fenner if (*cp == 't') 629b0453382SBill Fenner return; 630b0453382SBill Fenner 631b0453382SBill Fenner TCHECK(op->ospf6_len); 632b0453382SBill Fenner if (length != ntohs(op->ospf6_len)) { 633b0453382SBill Fenner printf(" [len %d]", ntohs(op->ospf6_len)); 634b0453382SBill Fenner return; 635b0453382SBill Fenner } 636b0453382SBill Fenner dataend = bp + length; 637b0453382SBill Fenner 638b0453382SBill Fenner /* Print the routerid if it is not the same as the source */ 639b0453382SBill Fenner TCHECK(op->ospf6_routerid); 640b0453382SBill Fenner printf(" rtrid %s", ipaddr_string(&op->ospf6_routerid)); 641b0453382SBill Fenner 642b0453382SBill Fenner TCHECK(op->ospf6_areaid); 643b0453382SBill Fenner if (op->ospf6_areaid != 0) 644b0453382SBill Fenner printf(" area %s", ipaddr_string(&op->ospf6_areaid)); 645b0453382SBill Fenner else 646b0453382SBill Fenner printf(" backbone"); 647b0453382SBill Fenner TCHECK(op->ospf6_instanceid); 648b0453382SBill Fenner if (op->ospf6_instanceid) 649b0453382SBill Fenner printf(" instance %u", op->ospf6_instanceid); 650b0453382SBill Fenner 651b0453382SBill Fenner /* Do rest according to version. */ 652b0453382SBill Fenner switch (op->ospf6_version) { 653b0453382SBill Fenner 654b0453382SBill Fenner case 3: 655b0453382SBill Fenner /* ospf version 3 */ 656b0453382SBill Fenner if (ospf6_decode_v3(op, dataend)) 657b0453382SBill Fenner goto trunc; 658b0453382SBill Fenner break; 659b0453382SBill Fenner 660b0453382SBill Fenner default: 661b0453382SBill Fenner printf(" ospf [version %d]", op->ospf6_version); 662b0453382SBill Fenner break; 663b0453382SBill Fenner } /* end switch on version */ 664b0453382SBill Fenner 665b0453382SBill Fenner return; 666b0453382SBill Fenner trunc: 667b0453382SBill Fenner fputs(tstr, stdout); 668b0453382SBill Fenner } 669