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[] = 26685295f4SBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.6 2000/09/29 04:58:45 guy 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 39b0453382SBill Fenner #include <ctype.h> 40b0453382SBill Fenner #include <stdio.h> 41b0453382SBill Fenner #include <string.h> 42b0453382SBill Fenner 43b0453382SBill Fenner #include "interface.h" 44b0453382SBill Fenner #include "addrtoname.h" 45b0453382SBill Fenner 46b0453382SBill Fenner #include "ospf6.h" 47b0453382SBill Fenner 48b0453382SBill Fenner struct bits { 49b0453382SBill Fenner u_int32_t bit; 50b0453382SBill Fenner const char *str; 51b0453382SBill Fenner }; 52b0453382SBill Fenner 53b0453382SBill Fenner static const struct bits ospf6_option_bits[] = { 54b0453382SBill Fenner { OSPF6_OPTION_V6, "V6" }, 55b0453382SBill Fenner { OSPF6_OPTION_E, "E" }, 56b0453382SBill Fenner { OSPF6_OPTION_MC, "MC" }, 57b0453382SBill Fenner { OSPF6_OPTION_N, "N" }, 58b0453382SBill Fenner { OSPF6_OPTION_R, "R" }, 59b0453382SBill Fenner { OSPF6_OPTION_DC, "DC" }, 60b0453382SBill Fenner { 0, NULL } 61b0453382SBill Fenner }; 62b0453382SBill Fenner 63b0453382SBill Fenner static const struct bits ospf6_rla_flag_bits[] = { 64b0453382SBill Fenner { RLA_FLAG_B, "B" }, 65b0453382SBill Fenner { RLA_FLAG_E, "E" }, 66b0453382SBill Fenner { RLA_FLAG_V, "V" }, 67b0453382SBill Fenner { RLA_FLAG_W, "W" }, 68b0453382SBill Fenner { 0, NULL } 69b0453382SBill Fenner }; 70b0453382SBill Fenner 71685295f4SBill Fenner static const struct bits ospf6_asla_flag_bits[] = { 72685295f4SBill Fenner { ASLA_FLAG_EXTERNAL, "E" }, 73685295f4SBill Fenner { ASLA_FLAG_FWDADDR, "F" }, 74685295f4SBill Fenner { ASLA_FLAG_ROUTETAG, "T" }, 75685295f4SBill Fenner { 0, NULL } 76685295f4SBill Fenner }; 77685295f4SBill Fenner 78b0453382SBill Fenner static struct tok type2str[] = { 79b0453382SBill Fenner { OSPF_TYPE_UMD, "umd" }, 80b0453382SBill Fenner { OSPF_TYPE_HELLO, "hello" }, 81b0453382SBill Fenner { OSPF_TYPE_DB, "dd" }, 82b0453382SBill Fenner { OSPF_TYPE_LSR, "ls_req" }, 83b0453382SBill Fenner { OSPF_TYPE_LSU, "ls_upd" }, 84b0453382SBill Fenner { OSPF_TYPE_LSA, "ls_ack" }, 85b0453382SBill Fenner { 0, NULL } 86b0453382SBill Fenner }; 87b0453382SBill Fenner 88b0453382SBill Fenner static char tstr[] = " [|ospf]"; 89b0453382SBill Fenner 90b0453382SBill Fenner /* Forwards */ 91b0453382SBill Fenner static inline void ospf6_print_seqage(u_int32_t, time_t); 92b0453382SBill Fenner static inline void ospf6_print_bits(const struct bits *, u_char); 93b0453382SBill Fenner static void ospf6_print_ls_type(u_int, const rtrid_t *, 94b0453382SBill Fenner const rtrid_t *, const char *); 95b0453382SBill Fenner static int ospf6_print_lshdr(const struct lsa_hdr *); 96b0453382SBill Fenner static int ospf6_print_lsa(const struct lsa *); 97b0453382SBill Fenner static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *); 98b0453382SBill Fenner 99b0453382SBill Fenner static inline void 100b0453382SBill Fenner ospf6_print_seqage(register u_int32_t seq, register time_t us) 101b0453382SBill Fenner { 102b0453382SBill Fenner register time_t sec = us % 60; 103b0453382SBill Fenner register time_t mins = (us / 60) % 60; 104b0453382SBill Fenner register time_t hour = us / 3600; 105b0453382SBill Fenner 106b0453382SBill Fenner printf(" S %X age ", seq); 107b0453382SBill Fenner if (hour) 108b0453382SBill Fenner printf("%u:%02u:%02u", 109b0453382SBill Fenner (u_int32_t) hour, (u_int32_t) mins, (u_int32_t) sec); 110b0453382SBill Fenner else if (mins) 111b0453382SBill Fenner printf("%u:%02u", (u_int32_t) mins, (u_int32_t) sec); 112b0453382SBill Fenner else 113b0453382SBill Fenner printf("%u", (u_int32_t) sec); 114b0453382SBill Fenner } 115b0453382SBill Fenner 116b0453382SBill Fenner 117b0453382SBill Fenner static inline void 118b0453382SBill Fenner ospf6_print_bits(register const struct bits *bp, register u_char options) 119b0453382SBill Fenner { 120b0453382SBill Fenner register char sep = ' '; 121b0453382SBill Fenner 122b0453382SBill Fenner do { 123b0453382SBill Fenner if (options & bp->bit) { 124b0453382SBill Fenner printf("%c%s", sep, bp->str); 125b0453382SBill Fenner sep = '/'; 126b0453382SBill Fenner } 127b0453382SBill Fenner } while ((++bp)->bit); 128b0453382SBill Fenner } 129b0453382SBill Fenner 130b0453382SBill Fenner static void 131b0453382SBill Fenner ospf6_print_ls_type(register u_int ls_type, 132b0453382SBill Fenner register const rtrid_t *ls_stateid, 133b0453382SBill Fenner register const rtrid_t *ls_router, register const char *fmt) 134b0453382SBill Fenner { 135b0453382SBill Fenner char *scope; 136b0453382SBill Fenner 137b0453382SBill Fenner switch (ls_type & LS_SCOPE_MASK) { 138b0453382SBill Fenner case LS_SCOPE_LINKLOCAL: 139b0453382SBill Fenner scope = "linklocal-"; 140b0453382SBill Fenner break; 141b0453382SBill Fenner case LS_SCOPE_AREA: 142b0453382SBill Fenner scope = "area-"; 143b0453382SBill Fenner break; 144b0453382SBill Fenner case LS_SCOPE_AS: 145b0453382SBill Fenner scope = "AS-"; 146b0453382SBill Fenner break; 147b0453382SBill Fenner default: 148b0453382SBill Fenner scope = ""; 149b0453382SBill Fenner break; 150b0453382SBill Fenner } 151b0453382SBill Fenner 152b0453382SBill Fenner switch (ls_type & LS_TYPE_MASK) { 153b0453382SBill Fenner case LS_TYPE_ROUTER: 154b0453382SBill Fenner printf(" %srtr %s", scope, ipaddr_string(ls_router)); 155b0453382SBill Fenner break; 156b0453382SBill Fenner 157b0453382SBill Fenner case LS_TYPE_NETWORK: 158b0453382SBill Fenner printf(" %snet dr %s if %s", scope, 159b0453382SBill Fenner ipaddr_string(ls_router), 160b0453382SBill Fenner ipaddr_string(ls_stateid)); 161b0453382SBill Fenner break; 162b0453382SBill Fenner 163b0453382SBill Fenner case LS_TYPE_INTER_AP: 164b0453382SBill Fenner printf(" %sinter-area-prefix %s abr %s", scope, 165b0453382SBill Fenner ipaddr_string(ls_stateid), 166b0453382SBill Fenner ipaddr_string(ls_router)); 167b0453382SBill Fenner break; 168b0453382SBill Fenner 169b0453382SBill Fenner case LS_TYPE_INTER_AR: 170b0453382SBill Fenner printf(" %sinter-area-router %s rtr %s", scope, 171b0453382SBill Fenner ipaddr_string(ls_router), 172b0453382SBill Fenner ipaddr_string(ls_stateid)); 173b0453382SBill Fenner break; 174b0453382SBill Fenner 175b0453382SBill Fenner case LS_TYPE_ASE: 176b0453382SBill Fenner printf(" %sase %s asbr %s", scope, 177b0453382SBill Fenner ipaddr_string(ls_stateid), 178b0453382SBill Fenner ipaddr_string(ls_router)); 179b0453382SBill Fenner break; 180b0453382SBill Fenner 181b0453382SBill Fenner case LS_TYPE_GROUP: 182b0453382SBill Fenner printf(" %sgroup %s rtr %s", scope, 183b0453382SBill Fenner ipaddr_string(ls_stateid), 184b0453382SBill Fenner ipaddr_string(ls_router)); 185b0453382SBill Fenner break; 186b0453382SBill Fenner 187b0453382SBill Fenner case LS_TYPE_TYPE7: 188b0453382SBill Fenner printf(" %stype7 %s rtr %s", scope, 189b0453382SBill Fenner ipaddr_string(ls_stateid), 190b0453382SBill Fenner ipaddr_string(ls_router)); 191b0453382SBill Fenner break; 192b0453382SBill Fenner 193b0453382SBill Fenner case LS_TYPE_LINK: 194b0453382SBill Fenner printf(" %slink %s rtr %s", scope, 195b0453382SBill Fenner ipaddr_string(ls_stateid), 196b0453382SBill Fenner ipaddr_string(ls_router)); 197b0453382SBill Fenner break; 198b0453382SBill Fenner 199b0453382SBill Fenner case LS_TYPE_INTRA_AP: 200b0453382SBill Fenner printf(" %sintra-area-prefix %s rtr %s", scope, 201b0453382SBill Fenner ipaddr_string(ls_stateid), 202b0453382SBill Fenner ipaddr_string(ls_router)); 203b0453382SBill Fenner break; 204b0453382SBill Fenner 205b0453382SBill Fenner default: 206b0453382SBill Fenner printf(" %s", scope); 207b0453382SBill Fenner printf(fmt, ls_type); 208b0453382SBill Fenner break; 209b0453382SBill Fenner } 210b0453382SBill Fenner 211b0453382SBill Fenner } 212b0453382SBill Fenner 213b0453382SBill Fenner static int 214b0453382SBill Fenner ospf6_print_lshdr(register const struct lsa_hdr *lshp) 215b0453382SBill Fenner { 216b0453382SBill Fenner 217b0453382SBill Fenner TCHECK(lshp->ls_type); 218b0453382SBill Fenner printf(" {"); /* } (ctags) */ 219b0453382SBill Fenner 220b0453382SBill Fenner TCHECK(lshp->ls_seq); 221b0453382SBill Fenner ospf6_print_seqage(ntohl(lshp->ls_seq), ntohs(lshp->ls_age)); 222b0453382SBill Fenner ospf6_print_ls_type(ntohs(lshp->ls_type), &lshp->ls_stateid, 223b0453382SBill Fenner &lshp->ls_router, "ls_type %d"); 224b0453382SBill Fenner 225b0453382SBill Fenner return (0); 226b0453382SBill Fenner trunc: 227b0453382SBill Fenner return (1); 228b0453382SBill Fenner } 229b0453382SBill Fenner 230b0453382SBill Fenner static int 231b0453382SBill Fenner ospf6_print_lsaprefix(register const struct lsa_prefix *lsapp) 232b0453382SBill Fenner { 233b0453382SBill Fenner int k; 234b0453382SBill Fenner struct in6_addr prefix; 235b0453382SBill Fenner 236b0453382SBill Fenner TCHECK(*lsapp); 237b0453382SBill Fenner k = (lsapp->lsa_p_len + 31) / 32; 238b0453382SBill Fenner if (k * 4 > sizeof(struct in6_addr)) { 239b0453382SBill Fenner printf("??prefixlen %d??", lsapp->lsa_p_len); 240b0453382SBill Fenner goto trunc; 241b0453382SBill Fenner } 242b0453382SBill Fenner memset(&prefix, 0, sizeof(prefix)); 243b0453382SBill Fenner memcpy(&prefix, lsapp->lsa_p_prefix, k * 4); 244b0453382SBill Fenner printf(" %s/%d", ip6addr_string(&prefix), 245b0453382SBill Fenner lsapp->lsa_p_len); 246b0453382SBill Fenner if (lsapp->lsa_p_opt) 247b0453382SBill Fenner printf("(opt=%x)", lsapp->lsa_p_opt); 248685295f4SBill Fenner if (lsapp->lsa_p_mbz) 249685295f4SBill Fenner printf("(mbz=%x)", ntohs(lsapp->lsa_p_mbz)); /* XXX */ 250b0453382SBill Fenner return sizeof(*lsapp) - 4 + k * 4; 251b0453382SBill Fenner 252b0453382SBill Fenner trunc: 253b0453382SBill Fenner return -1; 254b0453382SBill Fenner } 255b0453382SBill Fenner 256b0453382SBill Fenner 257b0453382SBill Fenner /* 258b0453382SBill Fenner * Print a single link state advertisement. If truncated return 1, else 0. 259b0453382SBill Fenner */ 260b0453382SBill Fenner static int 261b0453382SBill Fenner ospf6_print_lsa(register const struct lsa *lsap) 262b0453382SBill Fenner { 263685295f4SBill Fenner register const u_char *ls_end, *ls_opt; 264b0453382SBill Fenner register const struct rlalink *rlp; 265b0453382SBill Fenner #if 0 266b0453382SBill Fenner register const struct tos_metric *tosp; 267b0453382SBill Fenner #endif 268b0453382SBill Fenner register const rtrid_t *ap; 269b0453382SBill Fenner #if 0 270b0453382SBill Fenner register const struct aslametric *almp; 271b0453382SBill Fenner register const struct mcla *mcp; 272b0453382SBill Fenner #endif 273b0453382SBill Fenner register const struct llsa *llsap; 274b0453382SBill Fenner register const struct lsa_prefix *lsapp; 275b0453382SBill Fenner #if 0 276b0453382SBill Fenner register const u_int32_t *lp; 277b0453382SBill Fenner #endif 278b0453382SBill Fenner register int j, k; 279685295f4SBill Fenner u_int32_t flags32; 280b0453382SBill Fenner 281b0453382SBill Fenner if (ospf6_print_lshdr(&lsap->ls_hdr)) 282b0453382SBill Fenner return (1); 283b0453382SBill Fenner TCHECK(lsap->ls_hdr.ls_length); 284b0453382SBill Fenner ls_end = (u_char *)lsap + ntohs(lsap->ls_hdr.ls_length); 285b0453382SBill Fenner switch (ntohs(lsap->ls_hdr.ls_type)) { 286b0453382SBill Fenner case LS_TYPE_ROUTER | LS_SCOPE_AREA: 287b0453382SBill Fenner TCHECK(lsap->lsa_un.un_rla.rla_flags); 288b0453382SBill Fenner ospf6_print_bits(ospf6_rla_flag_bits, 289b0453382SBill Fenner lsap->lsa_un.un_rla.rla_flags); 290b0453382SBill Fenner TCHECK(lsap->lsa_un.un_rla.rla_options); 291b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 292b0453382SBill Fenner ntohl(lsap->lsa_un.un_rla.rla_options)); 293b0453382SBill Fenner 294b0453382SBill Fenner TCHECK(lsap->lsa_un.un_rla.rla_link); 295b0453382SBill Fenner rlp = lsap->lsa_un.un_rla.rla_link; 296b0453382SBill Fenner while (rlp + sizeof(*rlp) <= (struct rlalink *)ls_end) { 297b0453382SBill Fenner TCHECK(*rlp); 298b0453382SBill Fenner printf(" {"); /* } (ctags) */ 299b0453382SBill Fenner switch (rlp->link_type) { 300b0453382SBill Fenner 301b0453382SBill Fenner case RLA_TYPE_VIRTUAL: 302b0453382SBill Fenner printf(" virt"); 303b0453382SBill Fenner /* Fall through */ 304b0453382SBill Fenner 305b0453382SBill Fenner case RLA_TYPE_ROUTER: 306b0453382SBill Fenner printf(" nbrid %s nbrif %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 case RLA_TYPE_TRANSIT: 313b0453382SBill Fenner printf(" dr %s drif %s if %s", 314b0453382SBill Fenner ipaddr_string(&rlp->link_nrtid), 315b0453382SBill Fenner ipaddr_string(&rlp->link_nifid), 316b0453382SBill Fenner ipaddr_string(&rlp->link_ifid)); 317b0453382SBill Fenner break; 318b0453382SBill Fenner 319b0453382SBill Fenner default: 320b0453382SBill Fenner /* { (ctags) */ 321b0453382SBill Fenner printf(" ??RouterLinksType 0x%02x?? }", 322b0453382SBill Fenner rlp->link_type); 323b0453382SBill Fenner return (0); 324b0453382SBill Fenner } 325b0453382SBill Fenner printf(" metric %d", ntohs(rlp->link_metric)); 326b0453382SBill Fenner /* { (ctags) */ 327b0453382SBill Fenner printf(" }"); 328b0453382SBill Fenner rlp++; 329b0453382SBill Fenner } 330b0453382SBill Fenner break; 331b0453382SBill Fenner 332b0453382SBill Fenner case LS_TYPE_NETWORK | LS_SCOPE_AREA: 333b0453382SBill Fenner TCHECK(lsap->lsa_un.un_nla.nla_options); 334b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 335b0453382SBill Fenner ntohl(lsap->lsa_un.un_nla.nla_options)); 336b0453382SBill Fenner printf(" rtrs"); 337b0453382SBill Fenner ap = lsap->lsa_un.un_nla.nla_router; 338b0453382SBill Fenner while ((u_char *)ap < ls_end) { 339b0453382SBill Fenner TCHECK(*ap); 340b0453382SBill Fenner printf(" %s", ipaddr_string(ap)); 341b0453382SBill Fenner ++ap; 342b0453382SBill Fenner } 343b0453382SBill Fenner break; 344b0453382SBill Fenner 345b0453382SBill Fenner case LS_TYPE_INTER_AP | LS_SCOPE_AREA: 346b0453382SBill Fenner TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); 347b0453382SBill Fenner printf(" metric %u", 348b0453382SBill Fenner (u_int32_t)ntohl(lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); 349b0453382SBill Fenner lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix; 350b0453382SBill Fenner while (lsapp + sizeof(lsapp) <= (struct lsa_prefix *)ls_end) { 351b0453382SBill Fenner k = ospf6_print_lsaprefix(lsapp); 352685295f4SBill Fenner if (k) 353b0453382SBill Fenner goto trunc; 354b0453382SBill Fenner lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k); 355b0453382SBill Fenner } 356b0453382SBill Fenner break; 357685295f4SBill Fenner case LS_SCOPE_AS | LS_TYPE_ASE: 358685295f4SBill Fenner TCHECK(lsap->lsa_un.un_asla.asla_metric); 359685295f4SBill Fenner flags32 = ntohl(lsap->lsa_un.un_asla.asla_metric); 360685295f4SBill Fenner ospf6_print_bits(ospf6_asla_flag_bits, flags32); 361685295f4SBill Fenner printf(" metric %u", 362685295f4SBill Fenner ntohl(lsap->lsa_un.un_asla.asla_metric) & 363685295f4SBill Fenner ASLA_MASK_METRIC); 364685295f4SBill Fenner lsapp = lsap->lsa_un.un_asla.asla_prefix; 365685295f4SBill Fenner k = ospf6_print_lsaprefix(lsapp); 366685295f4SBill Fenner if (k < 0) 367685295f4SBill Fenner goto trunc; 368685295f4SBill Fenner if ((ls_opt = (u_char *)(((u_char *)lsapp) + k)) < ls_end) { 369685295f4SBill Fenner struct in6_addr *fwdaddr6; 370b0453382SBill Fenner 371685295f4SBill Fenner if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { 372685295f4SBill Fenner fwdaddr6 = (struct in6_addr *)ls_opt; 373685295f4SBill Fenner TCHECK(*fwdaddr6); 374685295f4SBill Fenner printf(" forward %s", 375685295f4SBill Fenner ip6addr_string(fwdaddr6)); 376685295f4SBill Fenner 377685295f4SBill Fenner ls_opt += sizeof(struct in6_addr); 378685295f4SBill Fenner } 379685295f4SBill Fenner 380685295f4SBill Fenner if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { 381685295f4SBill Fenner TCHECK(*(u_int32_t *)ls_opt); 382685295f4SBill Fenner printf(" tag %s", 383685295f4SBill Fenner ipaddr_string((u_int32_t *)ls_opt)); 384685295f4SBill Fenner 385685295f4SBill Fenner ls_opt += sizeof(u_int32_t); 386685295f4SBill Fenner } 387685295f4SBill Fenner 388685295f4SBill Fenner if (lsapp->lsa_p_mbz) { 389685295f4SBill Fenner TCHECK(*(u_int32_t *)ls_opt); 390685295f4SBill Fenner printf(" RefLSID: %s", 391685295f4SBill Fenner ipaddr_string((u_int32_t *)ls_opt)); 392685295f4SBill Fenner 393685295f4SBill Fenner ls_opt += sizeof(u_int32_t); 394685295f4SBill Fenner } 395685295f4SBill Fenner } 396685295f4SBill Fenner break; 397b0453382SBill Fenner #if 0 398b0453382SBill Fenner case LS_TYPE_SUM_ABR: 399b0453382SBill Fenner TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); 400b0453382SBill Fenner lp = lsap->lsa_un.un_sla.sla_tosmetric; 401b0453382SBill Fenner while ((u_char *)lp < ls_end) { 402b0453382SBill Fenner register u_int32_t ul; 403b0453382SBill Fenner 404b0453382SBill Fenner TCHECK(*lp); 405b0453382SBill Fenner ul = ntohl(*lp); 406b0453382SBill Fenner printf(" tos %d metric %d", 407b0453382SBill Fenner (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS, 408b0453382SBill Fenner ul & SLA_MASK_METRIC); 409b0453382SBill Fenner ++lp; 410b0453382SBill Fenner } 411b0453382SBill Fenner break; 412b0453382SBill Fenner 413b0453382SBill Fenner case LS_TYPE_GROUP: 414b0453382SBill Fenner /* Multicast extensions as of 23 July 1991 */ 415b0453382SBill Fenner mcp = lsap->lsa_un.un_mcla; 416b0453382SBill Fenner while ((u_char *)mcp < ls_end) { 417b0453382SBill Fenner TCHECK(mcp->mcla_vid); 418b0453382SBill Fenner switch (ntohl(mcp->mcla_vtype)) { 419b0453382SBill Fenner 420b0453382SBill Fenner case MCLA_VERTEX_ROUTER: 421b0453382SBill Fenner printf(" rtr rtrid %s", 422b0453382SBill Fenner ipaddr_string(&mcp->mcla_vid)); 423b0453382SBill Fenner break; 424b0453382SBill Fenner 425b0453382SBill Fenner case MCLA_VERTEX_NETWORK: 426b0453382SBill Fenner printf(" net dr %s", 427b0453382SBill Fenner ipaddr_string(&mcp->mcla_vid)); 428b0453382SBill Fenner break; 429b0453382SBill Fenner 430b0453382SBill Fenner default: 431b0453382SBill Fenner printf(" ??VertexType %u??", 432b0453382SBill Fenner (u_int32_t)ntohl(mcp->mcla_vtype)); 433b0453382SBill Fenner break; 434b0453382SBill Fenner } 435b0453382SBill Fenner ++mcp; 436b0453382SBill Fenner } 437b0453382SBill Fenner #endif 438b0453382SBill Fenner 439b0453382SBill Fenner case LS_TYPE_LINK: 440b0453382SBill Fenner /* Link LSA */ 441b0453382SBill Fenner llsap = &lsap->lsa_un.un_llsa; 442b0453382SBill Fenner TCHECK(llsap->llsa_options); 443b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, ntohl(llsap->llsa_options)); 444b0453382SBill Fenner TCHECK(llsap->llsa_nprefix); 445b0453382SBill Fenner printf(" pri %d lladdr %s npref %d", llsap->llsa_priority, 446b0453382SBill Fenner ip6addr_string(&llsap->llsa_lladdr), 447b0453382SBill Fenner (u_int32_t)ntohl(llsap->llsa_nprefix)); 448b0453382SBill Fenner lsapp = llsap->llsa_prefix; 449b0453382SBill Fenner for (j = 0; j < ntohl(llsap->llsa_nprefix); j++) { 450b0453382SBill Fenner k = ospf6_print_lsaprefix(lsapp); 451685295f4SBill Fenner if (k) 452b0453382SBill Fenner goto trunc; 453b0453382SBill Fenner lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k); 454b0453382SBill Fenner } 455b0453382SBill Fenner break; 456b0453382SBill Fenner 457b0453382SBill Fenner case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: 458b0453382SBill Fenner /* Intra-Area-Prefix LSA */ 459b0453382SBill Fenner TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); 460b0453382SBill Fenner ospf6_print_ls_type( 461b0453382SBill Fenner ntohs(lsap->lsa_un.un_intra_ap.intra_ap_lstype), 462b0453382SBill Fenner &lsap->lsa_un.un_intra_ap.intra_ap_lsid, 463b0453382SBill Fenner &lsap->lsa_un.un_intra_ap.intra_ap_rtid, 464b0453382SBill Fenner "LinkStateType %d"); 465b0453382SBill Fenner TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 466b0453382SBill Fenner printf(" npref %d", 467b0453382SBill Fenner ntohs(lsap->lsa_un.un_intra_ap.intra_ap_nprefix)); 468b0453382SBill Fenner 469b0453382SBill Fenner lsapp = lsap->lsa_un.un_intra_ap.intra_ap_prefix; 470b0453382SBill Fenner for (j = 0; 471b0453382SBill Fenner j < ntohs(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); 472b0453382SBill Fenner j++) { 473b0453382SBill Fenner k = ospf6_print_lsaprefix(lsapp); 474685295f4SBill Fenner if (k) 475b0453382SBill Fenner goto trunc; 476b0453382SBill Fenner lsapp = (struct lsa_prefix *)(((u_char *)lsapp) + k); 477b0453382SBill Fenner } 478b0453382SBill Fenner break; 479b0453382SBill Fenner 480b0453382SBill Fenner default: 481b0453382SBill Fenner printf(" ??LinkStateType 0x%04x??", 482b0453382SBill Fenner ntohs(lsap->ls_hdr.ls_type)); 483b0453382SBill Fenner } 484b0453382SBill Fenner 485b0453382SBill Fenner /* { (ctags) */ 486b0453382SBill Fenner fputs(" }", stdout); 487b0453382SBill Fenner return (0); 488b0453382SBill Fenner trunc: 489b0453382SBill Fenner fputs(" }", stdout); 490b0453382SBill Fenner return (1); 491b0453382SBill Fenner } 492b0453382SBill Fenner 493b0453382SBill Fenner static int 494b0453382SBill Fenner ospf6_decode_v3(register const struct ospf6hdr *op, 495b0453382SBill Fenner register const u_char *dataend) 496b0453382SBill Fenner { 497b0453382SBill Fenner register const rtrid_t *ap; 498b0453382SBill Fenner register const struct lsr *lsrp; 499b0453382SBill Fenner register const struct lsa_hdr *lshp; 500b0453382SBill Fenner register const struct lsa *lsap; 501b0453382SBill Fenner register char sep; 502b0453382SBill Fenner register int i; 503b0453382SBill Fenner 504b0453382SBill Fenner switch (op->ospf6_type) { 505b0453382SBill Fenner 506b0453382SBill Fenner case OSPF_TYPE_UMD: 507b0453382SBill Fenner /* 508b0453382SBill Fenner * Rob Coltun's special monitoring packets; 509b0453382SBill Fenner * do nothing 510b0453382SBill Fenner */ 511b0453382SBill Fenner break; 512b0453382SBill Fenner 513b0453382SBill Fenner case OSPF_TYPE_HELLO: 514b0453382SBill Fenner if (vflag) { 515b0453382SBill Fenner TCHECK(op->ospf6_hello.hello_deadint); 516b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 517b0453382SBill Fenner ntohl(op->ospf6_hello.hello_options)); 518b0453382SBill Fenner printf(" ifid %s pri %d int %d dead %u", 519b0453382SBill Fenner ipaddr_string(&op->ospf6_hello.hello_ifid), 520b0453382SBill Fenner op->ospf6_hello.hello_priority, 521b0453382SBill Fenner ntohs(op->ospf6_hello.hello_helloint), 522b0453382SBill Fenner ntohs(op->ospf6_hello.hello_deadint)); 523b0453382SBill Fenner } 524b0453382SBill Fenner TCHECK(op->ospf6_hello.hello_dr); 525b0453382SBill Fenner if (op->ospf6_hello.hello_dr != 0) 526b0453382SBill Fenner printf(" dr %s", 527b0453382SBill Fenner ipaddr_string(&op->ospf6_hello.hello_dr)); 528b0453382SBill Fenner TCHECK(op->ospf6_hello.hello_bdr); 529b0453382SBill Fenner if (op->ospf6_hello.hello_bdr != 0) 530b0453382SBill Fenner printf(" bdr %s", 531b0453382SBill Fenner ipaddr_string(&op->ospf6_hello.hello_bdr)); 532b0453382SBill Fenner if (vflag) { 533b0453382SBill Fenner printf(" nbrs"); 534b0453382SBill Fenner ap = op->ospf6_hello.hello_neighbor; 535b0453382SBill Fenner while ((u_char *)ap < dataend) { 536b0453382SBill Fenner TCHECK(*ap); 537b0453382SBill Fenner printf(" %s", ipaddr_string(ap)); 538b0453382SBill Fenner ++ap; 539b0453382SBill Fenner } 540b0453382SBill Fenner } 541b0453382SBill Fenner break; /* HELLO */ 542b0453382SBill Fenner 543b0453382SBill Fenner case OSPF_TYPE_DB: 544b0453382SBill Fenner TCHECK(op->ospf6_db.db_options); 545b0453382SBill Fenner ospf6_print_bits(ospf6_option_bits, 546b0453382SBill Fenner ntohl(op->ospf6_db.db_options)); 547b0453382SBill Fenner sep = ' '; 548b0453382SBill Fenner TCHECK(op->ospf6_db.db_flags); 549b0453382SBill Fenner if (op->ospf6_db.db_flags & OSPF6_DB_INIT) { 550b0453382SBill Fenner printf("%cI", sep); 551b0453382SBill Fenner sep = '/'; 552b0453382SBill Fenner } 553b0453382SBill Fenner if (op->ospf6_db.db_flags & OSPF6_DB_MORE) { 554b0453382SBill Fenner printf("%cM", sep); 555b0453382SBill Fenner sep = '/'; 556b0453382SBill Fenner } 557b0453382SBill Fenner if (op->ospf6_db.db_flags & OSPF6_DB_MASTER) { 558b0453382SBill Fenner printf("%cMS", sep); 559b0453382SBill Fenner sep = '/'; 560b0453382SBill Fenner } 561b0453382SBill Fenner TCHECK(op->ospf6_db.db_seq); 562b0453382SBill Fenner printf(" mtu %u S %X", ntohs(op->ospf6_db.db_mtu), 563b0453382SBill Fenner (u_int32_t)ntohl(op->ospf6_db.db_seq)); 564b0453382SBill Fenner 565b0453382SBill Fenner if (vflag) { 566b0453382SBill Fenner /* Print all the LS adv's */ 567b0453382SBill Fenner lshp = op->ospf6_db.db_lshdr; 568b0453382SBill Fenner 569b0453382SBill Fenner while (!ospf6_print_lshdr(lshp)) { 570b0453382SBill Fenner /* { (ctags) */ 571b0453382SBill Fenner printf(" }"); 572b0453382SBill Fenner ++lshp; 573b0453382SBill Fenner } 574b0453382SBill Fenner } 575b0453382SBill Fenner break; 576b0453382SBill Fenner 577b0453382SBill Fenner case OSPF_TYPE_LSR: 578b0453382SBill Fenner if (vflag) { 579b0453382SBill Fenner lsrp = op->ospf6_lsr; 580b0453382SBill Fenner while ((u_char *)lsrp < dataend) { 581b0453382SBill Fenner TCHECK(*lsrp); 582b0453382SBill Fenner printf(" {"); /* } (ctags) */ 583b0453382SBill Fenner ospf6_print_ls_type(ntohs(lsrp->ls_type), 584b0453382SBill Fenner &lsrp->ls_stateid, 585b0453382SBill Fenner &lsrp->ls_router, 586b0453382SBill Fenner "LinkStateType %d"); 587b0453382SBill Fenner /* { (ctags) */ 588b0453382SBill Fenner printf(" }"); 589b0453382SBill Fenner ++lsrp; 590b0453382SBill Fenner } 591b0453382SBill Fenner } 592b0453382SBill Fenner break; 593b0453382SBill Fenner 594b0453382SBill Fenner case OSPF_TYPE_LSU: 595b0453382SBill Fenner if (vflag) { 596b0453382SBill Fenner lsap = op->ospf6_lsu.lsu_lsa; 597b0453382SBill Fenner TCHECK(op->ospf6_lsu.lsu_count); 598b0453382SBill Fenner i = ntohl(op->ospf6_lsu.lsu_count); 599b0453382SBill Fenner while (i--) { 600b0453382SBill Fenner if (ospf6_print_lsa(lsap)) 601b0453382SBill Fenner goto trunc; 602b0453382SBill Fenner lsap = (struct lsa *)((u_char *)lsap + 603b0453382SBill Fenner ntohs(lsap->ls_hdr.ls_length)); 604b0453382SBill Fenner } 605b0453382SBill Fenner } 606b0453382SBill Fenner break; 607b0453382SBill Fenner 608b0453382SBill Fenner 609b0453382SBill Fenner case OSPF_TYPE_LSA: 610b0453382SBill Fenner if (vflag) { 611b0453382SBill Fenner lshp = op->ospf6_lsa.lsa_lshdr; 612b0453382SBill Fenner 613b0453382SBill Fenner while (!ospf6_print_lshdr(lshp)) { 614b0453382SBill Fenner /* { (ctags) */ 615b0453382SBill Fenner printf(" }"); 616b0453382SBill Fenner ++lshp; 617b0453382SBill Fenner } 618b0453382SBill Fenner } 619b0453382SBill Fenner break; 620b0453382SBill Fenner 621b0453382SBill Fenner default: 622b0453382SBill Fenner printf("v3 type %d", op->ospf6_type); 623b0453382SBill Fenner break; 624b0453382SBill Fenner } 625b0453382SBill Fenner return (0); 626b0453382SBill Fenner trunc: 627b0453382SBill Fenner return (1); 628b0453382SBill Fenner } 629b0453382SBill Fenner 630b0453382SBill Fenner void 631b0453382SBill Fenner ospf6_print(register const u_char *bp, register u_int length) 632b0453382SBill Fenner { 633b0453382SBill Fenner register const struct ospf6hdr *op; 634b0453382SBill Fenner register const u_char *dataend; 635b0453382SBill Fenner register const char *cp; 636b0453382SBill Fenner 637b0453382SBill Fenner op = (struct ospf6hdr *)bp; 638b0453382SBill Fenner 639b0453382SBill Fenner /* If the type is valid translate it, or just print the type */ 640b0453382SBill Fenner /* value. If it's not valid, say so and return */ 641b0453382SBill Fenner TCHECK(op->ospf6_type); 642b0453382SBill Fenner cp = tok2str(type2str, "type%d", op->ospf6_type); 643b0453382SBill Fenner printf("OSPFv%d-%s %d:", op->ospf6_version, cp, length); 644b0453382SBill Fenner if (*cp == 't') 645b0453382SBill Fenner return; 646b0453382SBill Fenner 647b0453382SBill Fenner TCHECK(op->ospf6_len); 648b0453382SBill Fenner if (length != ntohs(op->ospf6_len)) { 649b0453382SBill Fenner printf(" [len %d]", ntohs(op->ospf6_len)); 650b0453382SBill Fenner return; 651b0453382SBill Fenner } 652b0453382SBill Fenner dataend = bp + length; 653b0453382SBill Fenner 654b0453382SBill Fenner /* Print the routerid if it is not the same as the source */ 655b0453382SBill Fenner TCHECK(op->ospf6_routerid); 656b0453382SBill Fenner printf(" rtrid %s", ipaddr_string(&op->ospf6_routerid)); 657b0453382SBill Fenner 658b0453382SBill Fenner TCHECK(op->ospf6_areaid); 659b0453382SBill Fenner if (op->ospf6_areaid != 0) 660b0453382SBill Fenner printf(" area %s", ipaddr_string(&op->ospf6_areaid)); 661b0453382SBill Fenner else 662b0453382SBill Fenner printf(" backbone"); 663b0453382SBill Fenner TCHECK(op->ospf6_instanceid); 664b0453382SBill Fenner if (op->ospf6_instanceid) 665b0453382SBill Fenner printf(" instance %u", op->ospf6_instanceid); 666b0453382SBill Fenner 667b0453382SBill Fenner /* Do rest according to version. */ 668b0453382SBill Fenner switch (op->ospf6_version) { 669b0453382SBill Fenner 670b0453382SBill Fenner case 3: 671b0453382SBill Fenner /* ospf version 3 */ 672b0453382SBill Fenner if (ospf6_decode_v3(op, dataend)) 673b0453382SBill Fenner goto trunc; 674b0453382SBill Fenner break; 675b0453382SBill Fenner 676b0453382SBill Fenner default: 677b0453382SBill Fenner printf(" ospf [version %d]", op->ospf6_version); 678b0453382SBill Fenner break; 679b0453382SBill Fenner } /* end switch on version */ 680b0453382SBill Fenner 681b0453382SBill Fenner return; 682b0453382SBill Fenner trunc: 683b0453382SBill Fenner fputs(tstr, stdout); 684b0453382SBill Fenner } 685