| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 |
| 3 | * The Regents of the University of California. All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that: (1) source code distributions |
| 7 | * retain the above copyright notice and this paragraph in its entirety, (2) |
| 8 | * distributions including binary code include the above copyright notice and |
| 9 | * this paragraph in its entirety in the documentation or other materials |
| 10 | * provided with the distribution, and (3) all advertising materials mentioning |
| 11 | * features or use of this software display the following acknowledgement: |
| 12 | * ``This product includes software developed by the University of California, |
| 13 | * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of |
| 14 | * the University nor the names of its contributors may be used to endorse |
| 15 | * or promote products derived from this software without specific prior |
| 16 | * written permission. |
| 17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
| 18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
| 19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
| 20 | * |
| 21 | * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) |
| 22 | */ |
| 23 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 24 | #define NETDISSECT_REWORKED |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 25 | #ifdef HAVE_CONFIG_H |
| 26 | #include "config.h" |
| 27 | #endif |
| 28 | |
| 29 | #include <tcpdump-stdinc.h> |
| 30 | |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 31 | #include <string.h> |
| 32 | |
| 33 | #include "interface.h" |
| 34 | #include "addrtoname.h" |
| 35 | #include "extract.h" |
| 36 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 37 | #include "ospf.h" |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 38 | |
| 39 | #define OSPF_TYPE_HELLO 1 /* Hello */ |
| 40 | #define OSPF_TYPE_DD 2 /* Database Description */ |
| 41 | #define OSPF_TYPE_LS_REQ 3 /* Link State Request */ |
| 42 | #define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */ |
| 43 | #define OSPF_TYPE_LS_ACK 5 /* Link State Ack */ |
| 44 | |
| 45 | /* Options *_options */ |
| 46 | #define OSPF6_OPTION_V6 0x01 /* V6 bit: A bit for peeping tom */ |
| 47 | #define OSPF6_OPTION_E 0x02 /* E bit: External routes advertised */ |
| 48 | #define OSPF6_OPTION_MC 0x04 /* MC bit: Multicast capable */ |
| 49 | #define OSPF6_OPTION_N 0x08 /* N bit: For type-7 LSA */ |
| 50 | #define OSPF6_OPTION_R 0x10 /* R bit: Router bit */ |
| 51 | #define OSPF6_OPTION_DC 0x20 /* DC bit: Demand circuits */ |
| 52 | /* The field is actually 24-bit (RFC5340 Section A.2). */ |
| 53 | #define OSPF6_OPTION_AF 0x0100 /* AF bit: Multiple address families */ |
| 54 | #define OSPF6_OPTION_L 0x0200 /* L bit: Link-local signaling (LLS) */ |
| 55 | #define OSPF6_OPTION_AT 0x0400 /* AT bit: Authentication trailer */ |
| 56 | |
| 57 | |
| 58 | /* db_flags */ |
| 59 | #define OSPF6_DB_INIT 0x04 /* */ |
| 60 | #define OSPF6_DB_MORE 0x02 |
| 61 | #define OSPF6_DB_MASTER 0x01 |
| 62 | #define OSPF6_DB_M6 0x10 /* IPv6 MTU */ |
| 63 | |
| 64 | /* ls_type */ |
| 65 | #define LS_TYPE_ROUTER 1 /* router link */ |
| 66 | #define LS_TYPE_NETWORK 2 /* network link */ |
| 67 | #define LS_TYPE_INTER_AP 3 /* Inter-Area-Prefix */ |
| 68 | #define LS_TYPE_INTER_AR 4 /* Inter-Area-Router */ |
| 69 | #define LS_TYPE_ASE 5 /* ASE */ |
| 70 | #define LS_TYPE_GROUP 6 /* Group membership */ |
| 71 | #define LS_TYPE_NSSA 7 /* NSSA */ |
| 72 | #define LS_TYPE_LINK 8 /* Link LSA */ |
| 73 | #define LS_TYPE_INTRA_AP 9 /* Intra-Area-Prefix */ |
| 74 | #define LS_TYPE_INTRA_ATE 10 /* Intra-Area-TE */ |
| 75 | #define LS_TYPE_GRACE 11 /* Grace LSA */ |
| 76 | #define LS_TYPE_RI 12 /* Router information */ |
| 77 | #define LS_TYPE_INTER_ASTE 13 /* Inter-AS-TE */ |
| 78 | #define LS_TYPE_L1VPN 14 /* L1VPN */ |
| 79 | #define LS_TYPE_MASK 0x1fff |
| 80 | |
| 81 | #define LS_SCOPE_LINKLOCAL 0x0000 |
| 82 | #define LS_SCOPE_AREA 0x2000 |
| 83 | #define LS_SCOPE_AS 0x4000 |
| 84 | #define LS_SCOPE_MASK 0x6000 |
| 85 | #define LS_SCOPE_U 0x8000 |
| 86 | |
| 87 | /* rla_link.link_type */ |
| 88 | #define RLA_TYPE_ROUTER 1 /* point-to-point to another router */ |
| 89 | #define RLA_TYPE_TRANSIT 2 /* connection to transit network */ |
| 90 | #define RLA_TYPE_VIRTUAL 4 /* virtual link */ |
| 91 | |
| 92 | /* rla_flags */ |
| 93 | #define RLA_FLAG_B 0x01 |
| 94 | #define RLA_FLAG_E 0x02 |
| 95 | #define RLA_FLAG_V 0x04 |
| 96 | #define RLA_FLAG_W 0x08 |
| 97 | #define RLA_FLAG_N 0x10 |
| 98 | |
| 99 | /* lsa_prefix options */ |
| 100 | #define LSA_PREFIX_OPT_NU 0x01 |
| 101 | #define LSA_PREFIX_OPT_LA 0x02 |
| 102 | #define LSA_PREFIX_OPT_MC 0x04 |
| 103 | #define LSA_PREFIX_OPT_P 0x08 |
| 104 | #define LSA_PREFIX_OPT_DN 0x10 |
| 105 | |
| 106 | /* sla_tosmetric breakdown */ |
| 107 | #define SLA_MASK_TOS 0x7f000000 |
| 108 | #define SLA_MASK_METRIC 0x00ffffff |
| 109 | #define SLA_SHIFT_TOS 24 |
| 110 | |
| 111 | /* asla_metric */ |
| 112 | #define ASLA_FLAG_FWDADDR 0x02000000 |
| 113 | #define ASLA_FLAG_ROUTETAG 0x01000000 |
| 114 | #define ASLA_MASK_METRIC 0x00ffffff |
| 115 | |
| 116 | /* RFC6506 Section 4.1 */ |
| 117 | #define OSPF6_AT_HDRLEN 16U |
| 118 | #define OSPF6_AUTH_TYPE_HMAC 0x0001 |
| 119 | |
| 120 | typedef uint32_t rtrid_t; |
| 121 | |
| 122 | /* link state advertisement header */ |
| 123 | struct lsa6_hdr { |
| 124 | uint16_t ls_age; |
| 125 | uint16_t ls_type; |
| 126 | rtrid_t ls_stateid; |
| 127 | rtrid_t ls_router; |
| 128 | uint32_t ls_seq; |
| 129 | uint16_t ls_chksum; |
| 130 | uint16_t ls_length; |
| 131 | }; |
| 132 | |
| 133 | /* Length of an IPv6 address, in bytes. */ |
| 134 | #define IPV6_ADDR_LEN_BYTES (128/8) |
| 135 | |
| 136 | struct lsa6_prefix { |
| 137 | uint8_t lsa_p_len; |
| 138 | uint8_t lsa_p_opt; |
| 139 | uint16_t lsa_p_metric; |
| 140 | uint8_t lsa_p_prefix[IPV6_ADDR_LEN_BYTES]; /* maximum length */ |
| 141 | }; |
| 142 | |
| 143 | /* link state advertisement */ |
| 144 | struct lsa6 { |
| 145 | struct lsa6_hdr ls_hdr; |
| 146 | |
| 147 | /* Link state types */ |
| 148 | union { |
| 149 | /* Router links advertisements */ |
| 150 | struct { |
| 151 | union { |
| 152 | uint8_t flg; |
| 153 | uint32_t opt; |
| 154 | } rla_flgandopt; |
| 155 | #define rla_flags rla_flgandopt.flg |
| 156 | #define rla_options rla_flgandopt.opt |
| 157 | struct rlalink6 { |
| 158 | uint8_t link_type; |
| 159 | uint8_t link_zero[1]; |
| 160 | uint16_t link_metric; |
| 161 | uint32_t link_ifid; |
| 162 | uint32_t link_nifid; |
| 163 | rtrid_t link_nrtid; |
| 164 | } rla_link[1]; /* may repeat */ |
| 165 | } un_rla; |
| 166 | |
| 167 | /* Network links advertisements */ |
| 168 | struct { |
| 169 | uint32_t nla_options; |
| 170 | rtrid_t nla_router[1]; /* may repeat */ |
| 171 | } un_nla; |
| 172 | |
| 173 | /* Inter Area Prefix LSA */ |
| 174 | struct { |
| 175 | uint32_t inter_ap_metric; |
| 176 | struct lsa6_prefix inter_ap_prefix[1]; |
| 177 | } un_inter_ap; |
| 178 | |
| 179 | /* AS external links advertisements */ |
| 180 | struct { |
| 181 | uint32_t asla_metric; |
| 182 | struct lsa6_prefix asla_prefix[1]; |
| 183 | /* some optional fields follow */ |
| 184 | } un_asla; |
| 185 | |
| 186 | #if 0 |
| 187 | /* Summary links advertisements */ |
| 188 | struct { |
| 189 | struct in_addr sla_mask; |
| 190 | uint32_t sla_tosmetric[1]; /* may repeat */ |
| 191 | } un_sla; |
| 192 | |
| 193 | /* Multicast group membership */ |
| 194 | struct mcla { |
| 195 | uint32_t mcla_vtype; |
| 196 | struct in_addr mcla_vid; |
| 197 | } un_mcla[1]; |
| 198 | #endif |
| 199 | |
| 200 | /* Type 7 LSA */ |
| 201 | |
| 202 | /* Link LSA */ |
| 203 | struct llsa { |
| 204 | union { |
| 205 | uint8_t pri; |
| 206 | uint32_t opt; |
| 207 | } llsa_priandopt; |
| 208 | #define llsa_priority llsa_priandopt.pri |
| 209 | #define llsa_options llsa_priandopt.opt |
| 210 | struct in6_addr llsa_lladdr; |
| 211 | uint32_t llsa_nprefix; |
| 212 | struct lsa6_prefix llsa_prefix[1]; |
| 213 | } un_llsa; |
| 214 | |
| 215 | /* Intra-Area-Prefix */ |
| 216 | struct { |
| 217 | uint16_t intra_ap_nprefix; |
| 218 | uint16_t intra_ap_lstype; |
| 219 | rtrid_t intra_ap_lsid; |
| 220 | rtrid_t intra_ap_rtid; |
| 221 | struct lsa6_prefix intra_ap_prefix[1]; |
| 222 | } un_intra_ap; |
| 223 | } lsa_un; |
| 224 | }; |
| 225 | |
| 226 | /* |
| 227 | * the main header |
| 228 | */ |
| 229 | struct ospf6hdr { |
| 230 | uint8_t ospf6_version; |
| 231 | uint8_t ospf6_type; |
| 232 | uint16_t ospf6_len; |
| 233 | rtrid_t ospf6_routerid; |
| 234 | rtrid_t ospf6_areaid; |
| 235 | uint16_t ospf6_chksum; |
| 236 | uint8_t ospf6_instanceid; |
| 237 | uint8_t ospf6_rsvd; |
| 238 | }; |
| 239 | |
| 240 | /* |
| 241 | * The OSPF6 header length is 16 bytes, regardless of how your compiler |
| 242 | * might choose to pad the above structure. |
| 243 | */ |
| 244 | #define OSPF6HDR_LEN 16 |
| 245 | |
| 246 | /* Hello packet */ |
| 247 | struct hello6 { |
| 248 | uint32_t hello_ifid; |
| 249 | union { |
| 250 | uint8_t pri; |
| 251 | uint32_t opt; |
| 252 | } hello_priandopt; |
| 253 | #define hello_priority hello_priandopt.pri |
| 254 | #define hello_options hello_priandopt.opt |
| 255 | uint16_t hello_helloint; |
| 256 | uint16_t hello_deadint; |
| 257 | rtrid_t hello_dr; |
| 258 | rtrid_t hello_bdr; |
| 259 | rtrid_t hello_neighbor[1]; /* may repeat */ |
| 260 | }; |
| 261 | |
| 262 | /* Database Description packet */ |
| 263 | struct dd6 { |
| 264 | uint32_t db_options; |
| 265 | uint16_t db_mtu; |
| 266 | uint8_t db_mbz; |
| 267 | uint8_t db_flags; |
| 268 | uint32_t db_seq; |
| 269 | struct lsa6_hdr db_lshdr[1]; /* may repeat */ |
| 270 | }; |
| 271 | |
| 272 | /* Link State Request */ |
| 273 | struct lsr6 { |
| 274 | uint16_t ls_mbz; |
| 275 | uint16_t ls_type; |
| 276 | rtrid_t ls_stateid; |
| 277 | rtrid_t ls_router; |
| 278 | }; |
| 279 | |
| 280 | /* Link State Update */ |
| 281 | struct lsu6 { |
| 282 | uint32_t lsu_count; |
| 283 | struct lsa6 lsu_lsa[1]; /* may repeat */ |
| 284 | }; |
| 285 | |
| 286 | static const char tstr[] = " [|ospf3]"; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 287 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 288 | static const struct tok ospf6_option_values[] = { |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 289 | { OSPF6_OPTION_V6, "V6" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 290 | { OSPF6_OPTION_E, "External" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 291 | { OSPF6_OPTION_MC, "Deprecated" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 292 | { OSPF6_OPTION_N, "NSSA" }, |
| 293 | { OSPF6_OPTION_R, "Router" }, |
| 294 | { OSPF6_OPTION_DC, "Demand Circuit" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 295 | { OSPF6_OPTION_AF, "AFs Support" }, |
| 296 | { OSPF6_OPTION_L, "LLS" }, |
| 297 | { OSPF6_OPTION_AT, "Authentication Trailer" }, |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 298 | { 0, NULL } |
| 299 | }; |
| 300 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 301 | static const struct tok ospf6_rla_flag_values[] = { |
| 302 | { RLA_FLAG_B, "ABR" }, |
| 303 | { RLA_FLAG_E, "External" }, |
| 304 | { RLA_FLAG_V, "Virtual-Link Endpoint" }, |
| 305 | { RLA_FLAG_W, "Wildcard Receiver" }, |
| 306 | { RLA_FLAG_N, "NSSA Translator" }, |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 307 | { 0, NULL } |
| 308 | }; |
| 309 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 310 | static const struct tok ospf6_asla_flag_values[] = { |
| 311 | { ASLA_FLAG_EXTERNAL, "External Type 2" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 312 | { ASLA_FLAG_FWDADDR, "Forwarding" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 313 | { ASLA_FLAG_ROUTETAG, "Tag" }, |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 314 | { 0, NULL } |
| 315 | }; |
| 316 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 317 | static const struct tok ospf6_type_values[] = { |
| 318 | { OSPF_TYPE_HELLO, "Hello" }, |
| 319 | { OSPF_TYPE_DD, "Database Description" }, |
| 320 | { OSPF_TYPE_LS_REQ, "LS-Request" }, |
| 321 | { OSPF_TYPE_LS_UPDATE, "LS-Update" }, |
| 322 | { OSPF_TYPE_LS_ACK, "LS-Ack" }, |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 323 | { 0, NULL } |
| 324 | }; |
| 325 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 326 | static const struct tok ospf6_lsa_values[] = { |
| 327 | { LS_TYPE_ROUTER, "Router" }, |
| 328 | { LS_TYPE_NETWORK, "Network" }, |
| 329 | { LS_TYPE_INTER_AP, "Inter-Area Prefix" }, |
| 330 | { LS_TYPE_INTER_AR, "Inter-Area Router" }, |
| 331 | { LS_TYPE_ASE, "External" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 332 | { LS_TYPE_GROUP, "Deprecated" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 333 | { LS_TYPE_NSSA, "NSSA" }, |
| 334 | { LS_TYPE_LINK, "Link" }, |
| 335 | { LS_TYPE_INTRA_AP, "Intra-Area Prefix" }, |
| 336 | { LS_TYPE_INTRA_ATE, "Intra-Area TE" }, |
| 337 | { LS_TYPE_GRACE, "Grace" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 338 | { LS_TYPE_RI, "Router Information" }, |
| 339 | { LS_TYPE_INTER_ASTE, "Inter-AS-TE" }, |
| 340 | { LS_TYPE_L1VPN, "Layer 1 VPN" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 341 | { 0, NULL } |
| 342 | }; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 343 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 344 | static const struct tok ospf6_ls_scope_values[] = { |
| 345 | { LS_SCOPE_LINKLOCAL, "Link Local" }, |
| 346 | { LS_SCOPE_AREA, "Area Local" }, |
| 347 | { LS_SCOPE_AS, "Domain Wide" }, |
| 348 | { 0, NULL } |
| 349 | }; |
| 350 | |
| 351 | static const struct tok ospf6_dd_flag_values[] = { |
| 352 | { OSPF6_DB_INIT, "Init" }, |
| 353 | { OSPF6_DB_MORE, "More" }, |
| 354 | { OSPF6_DB_MASTER, "Master" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 355 | { OSPF6_DB_M6, "IPv6 MTU" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 356 | { 0, NULL } |
| 357 | }; |
| 358 | |
| 359 | static const struct tok ospf6_lsa_prefix_option_values[] = { |
| 360 | { LSA_PREFIX_OPT_NU, "No Unicast" }, |
| 361 | { LSA_PREFIX_OPT_LA, "Local address" }, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 362 | { LSA_PREFIX_OPT_MC, "Deprecated" }, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 363 | { LSA_PREFIX_OPT_P, "Propagate" }, |
| 364 | { LSA_PREFIX_OPT_DN, "Down" }, |
| 365 | { 0, NULL } |
| 366 | }; |
| 367 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 368 | static const struct tok ospf6_auth_type_str[] = { |
| 369 | { OSPF6_AUTH_TYPE_HMAC, "HMAC" }, |
| 370 | { 0, NULL } |
| 371 | }; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 372 | |
| 373 | static void |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 374 | ospf6_print_ls_type(netdissect_options *ndo, |
| 375 | register u_int ls_type, register const rtrid_t *ls_stateid) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 376 | { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 377 | ND_PRINT((ndo, "\n\t %s LSA (%d), %s Scope%s, LSA-ID %s", |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 378 | tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK), |
| 379 | ls_type & LS_TYPE_MASK, |
| 380 | tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK), |
| 381 | ls_type &0x8000 ? ", transitive" : "", /* U-bit */ |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 382 | ipaddr_string(ndo, ls_stateid))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 383 | } |
| 384 | |
| 385 | static int |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 386 | ospf6_print_lshdr(netdissect_options *ndo, |
| 387 | register const struct lsa6_hdr *lshp, const u_char *dataend) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 388 | { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 389 | if ((u_char *)(lshp + 1) > dataend) |
| 390 | goto trunc; |
| 391 | ND_TCHECK(lshp->ls_type); |
| 392 | ND_TCHECK(lshp->ls_seq); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 393 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 394 | ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", |
| 395 | ipaddr_string(ndo, &lshp->ls_router), |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 396 | EXTRACT_32BITS(&lshp->ls_seq), |
| 397 | EXTRACT_16BITS(&lshp->ls_age), |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 398 | EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 399 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 400 | ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 401 | |
| 402 | return (0); |
| 403 | trunc: |
| 404 | return (1); |
| 405 | } |
| 406 | |
| 407 | static int |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 408 | ospf6_print_lsaprefix(netdissect_options *ndo, |
| 409 | const uint8_t *tptr, u_int lsa_length) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 410 | { |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 411 | const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr; |
| 412 | u_int wordlen; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 413 | struct in6_addr prefix; |
| 414 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 415 | if (lsa_length < sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES) |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 416 | goto trunc; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 417 | lsa_length -= sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES; |
| 418 | ND_TCHECK2(*lsapp, sizeof (*lsapp) - IPV6_ADDR_LEN_BYTES); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 419 | wordlen = (lsapp->lsa_p_len + 31) / 32; |
| 420 | if (wordlen * 4 > sizeof(struct in6_addr)) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 421 | ND_PRINT((ndo, " bogus prefixlen /%d", lsapp->lsa_p_len)); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 422 | goto trunc; |
| 423 | } |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 424 | if (lsa_length < wordlen * 4) |
| 425 | goto trunc; |
| 426 | lsa_length -= wordlen * 4; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 427 | ND_TCHECK2(lsapp->lsa_p_prefix, wordlen * 4); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 428 | memset(&prefix, 0, sizeof(prefix)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 429 | memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 430 | ND_PRINT((ndo, "\n\t\t%s/%d", ip6addr_string(ndo, &prefix), |
| 431 | lsapp->lsa_p_len)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 432 | if (lsapp->lsa_p_opt) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 433 | ND_PRINT((ndo, ", Options [%s]", |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 434 | bittok2str(ospf6_lsa_prefix_option_values, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 435 | "none", lsapp->lsa_p_opt))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 436 | } |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 437 | ND_PRINT((ndo, ", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric))); |
| 438 | return sizeof(*lsapp) - IPV6_ADDR_LEN_BYTES + wordlen * 4; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 439 | |
| 440 | trunc: |
| 441 | return -1; |
| 442 | } |
| 443 | |
| 444 | |
| 445 | /* |
| 446 | * Print a single link state advertisement. If truncated return 1, else 0. |
| 447 | */ |
| 448 | static int |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 449 | ospf6_print_lsa(netdissect_options *ndo, |
| 450 | register const struct lsa6 *lsap, const u_char *dataend) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 451 | { |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 452 | register const struct rlalink6 *rlp; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 453 | #if 0 |
| 454 | register const struct tos_metric *tosp; |
| 455 | #endif |
| 456 | register const rtrid_t *ap; |
| 457 | #if 0 |
| 458 | register const struct aslametric *almp; |
| 459 | register const struct mcla *mcp; |
| 460 | #endif |
| 461 | register const struct llsa *llsap; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 462 | register const struct lsa6_prefix *lsapp; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 463 | #if 0 |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 464 | register const uint32_t *lp; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 465 | #endif |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 466 | register u_int prefixes; |
| 467 | register int bytelen; |
| 468 | register u_int length, lsa_length; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 469 | uint32_t flags32; |
| 470 | const uint8_t *tptr; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 471 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 472 | if (ospf6_print_lshdr(ndo, &lsap->ls_hdr, dataend)) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 473 | return (1); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 474 | ND_TCHECK(lsap->ls_hdr.ls_length); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 475 | length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); |
| 476 | |
| 477 | /* |
| 478 | * The LSA length includes the length of the header; |
| 479 | * it must have a value that's at least that length. |
| 480 | * If it does, find the length of what follows the |
| 481 | * header. |
| 482 | */ |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 483 | if (length < sizeof(struct lsa6_hdr) || (u_char *)lsap + length > dataend) |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 484 | return (1); |
| 485 | lsa_length = length - sizeof(struct lsa6_hdr); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 486 | tptr = (uint8_t *)lsap+sizeof(struct lsa6_hdr); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 487 | |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 488 | switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { |
| 489 | case LS_TYPE_ROUTER | LS_SCOPE_AREA: |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 490 | if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) |
| 491 | return (1); |
| 492 | lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 493 | ND_TCHECK(lsap->lsa_un.un_rla.rla_options); |
| 494 | ND_PRINT((ndo, "\n\t Options [%s]", |
| 495 | bittok2str(ospf6_option_values, "none", |
| 496 | EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)))); |
| 497 | ND_PRINT((ndo, ", RLA-Flags [%s]", |
| 498 | bittok2str(ospf6_rla_flag_values, "none", |
| 499 | lsap->lsa_un.un_rla.rla_flags))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 500 | |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 501 | rlp = lsap->lsa_un.un_rla.rla_link; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 502 | while (lsa_length != 0) { |
| 503 | if (lsa_length < sizeof (*rlp)) |
| 504 | return (1); |
| 505 | lsa_length -= sizeof (*rlp); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 506 | ND_TCHECK(*rlp); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 507 | switch (rlp->link_type) { |
| 508 | |
| 509 | case RLA_TYPE_VIRTUAL: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 510 | ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID %s" |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 511 | "\n\t Neighbor Interface-ID %s, Interface %s", |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 512 | ipaddr_string(ndo, &rlp->link_nrtid), |
| 513 | ipaddr_string(ndo, &rlp->link_nifid), |
| 514 | ipaddr_string(ndo, &rlp->link_ifid))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 515 | break; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 516 | |
| 517 | case RLA_TYPE_ROUTER: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 518 | ND_PRINT((ndo, "\n\t Neighbor Router-ID %s" |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 519 | "\n\t Neighbor Interface-ID %s, Interface %s", |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 520 | ipaddr_string(ndo, &rlp->link_nrtid), |
| 521 | ipaddr_string(ndo, &rlp->link_nifid), |
| 522 | ipaddr_string(ndo, &rlp->link_ifid))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 523 | break; |
| 524 | |
| 525 | case RLA_TYPE_TRANSIT: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 526 | ND_PRINT((ndo, "\n\t Neighbor Network-ID %s" |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 527 | "\n\t Neighbor Interface-ID %s, Interface %s", |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 528 | ipaddr_string(ndo, &rlp->link_nrtid), |
| 529 | ipaddr_string(ndo, &rlp->link_nifid), |
| 530 | ipaddr_string(ndo, &rlp->link_ifid))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 531 | break; |
| 532 | |
| 533 | default: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 534 | ND_PRINT((ndo, "\n\t Unknown Router Links Type 0x%02x", |
| 535 | rlp->link_type)); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 536 | return (0); |
| 537 | } |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 538 | ND_PRINT((ndo, ", metric %d", EXTRACT_16BITS(&rlp->link_metric))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 539 | rlp++; |
| 540 | } |
| 541 | break; |
| 542 | |
| 543 | case LS_TYPE_NETWORK | LS_SCOPE_AREA: |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 544 | if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) |
| 545 | return (1); |
| 546 | lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 547 | ND_TCHECK(lsap->lsa_un.un_nla.nla_options); |
| 548 | ND_PRINT((ndo, "\n\t Options [%s]", |
| 549 | bittok2str(ospf6_option_values, "none", |
| 550 | EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 551 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 552 | ND_PRINT((ndo, "\n\t Connected Routers:")); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 553 | ap = lsap->lsa_un.un_nla.nla_router; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 554 | while (lsa_length != 0) { |
| 555 | if (lsa_length < sizeof (*ap)) |
| 556 | return (1); |
| 557 | lsa_length -= sizeof (*ap); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 558 | ND_TCHECK(*ap); |
| 559 | ND_PRINT((ndo, "\n\t\t%s", ipaddr_string(ndo, ap))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 560 | ++ap; |
| 561 | } |
| 562 | break; |
| 563 | |
| 564 | case LS_TYPE_INTER_AP | LS_SCOPE_AREA: |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 565 | if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) |
| 566 | return (1); |
| 567 | lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 568 | ND_TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); |
| 569 | ND_PRINT((ndo, ", metric %u", |
| 570 | EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 571 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 572 | tptr = (uint8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 573 | while (lsa_length != 0) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 574 | bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 575 | if (bytelen < 0) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 576 | goto trunc; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 577 | lsa_length -= bytelen; |
| 578 | tptr += bytelen; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 579 | } |
| 580 | break; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 581 | |
| 582 | case LS_TYPE_ASE | LS_SCOPE_AS: |
| 583 | if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) |
| 584 | return (1); |
| 585 | lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 586 | ND_TCHECK(lsap->lsa_un.un_asla.asla_metric); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 587 | flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 588 | ND_PRINT((ndo, "\n\t Flags [%s]", |
| 589 | bittok2str(ospf6_asla_flag_values, "none", flags32))); |
| 590 | ND_PRINT((ndo, " metric %u", |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 591 | EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 592 | ASLA_MASK_METRIC)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 593 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 594 | tptr = (uint8_t *)lsap->lsa_un.un_asla.asla_prefix; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 595 | lsapp = (struct lsa6_prefix *)tptr; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 596 | bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 597 | if (bytelen < 0) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 598 | goto trunc; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 599 | lsa_length -= bytelen; |
| 600 | tptr += bytelen; |
| 601 | |
| 602 | if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 603 | struct in6_addr *fwdaddr6; |
| 604 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 605 | fwdaddr6 = (struct in6_addr *)tptr; |
| 606 | if (lsa_length < sizeof (*fwdaddr6)) |
| 607 | return (1); |
| 608 | lsa_length -= sizeof (*fwdaddr6); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 609 | ND_TCHECK(*fwdaddr6); |
| 610 | ND_PRINT((ndo, " forward %s", |
| 611 | ip6addr_string(ndo, fwdaddr6))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 612 | tptr += sizeof(*fwdaddr6); |
| 613 | } |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 614 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 615 | if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 616 | if (lsa_length < sizeof (uint32_t)) |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 617 | return (1); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 618 | lsa_length -= sizeof (uint32_t); |
| 619 | ND_TCHECK(*(uint32_t *)tptr); |
| 620 | ND_PRINT((ndo, " tag %s", |
| 621 | ipaddr_string(ndo, (uint32_t *)tptr))); |
| 622 | tptr += sizeof(uint32_t); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 623 | } |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 624 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 625 | if (lsapp->lsa_p_metric) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 626 | if (lsa_length < sizeof (uint32_t)) |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 627 | return (1); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 628 | lsa_length -= sizeof (uint32_t); |
| 629 | ND_TCHECK(*(uint32_t *)tptr); |
| 630 | ND_PRINT((ndo, " RefLSID: %s", |
| 631 | ipaddr_string(ndo, (uint32_t *)tptr))); |
| 632 | tptr += sizeof(uint32_t); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 633 | } |
| 634 | break; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 635 | |
| 636 | case LS_TYPE_LINK: |
| 637 | /* Link LSA */ |
| 638 | llsap = &lsap->lsa_un.un_llsa; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 639 | if (lsa_length < sizeof (llsap->llsa_priandopt)) |
| 640 | return (1); |
| 641 | lsa_length -= sizeof (llsap->llsa_priandopt); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 642 | ND_TCHECK(llsap->llsa_priandopt); |
| 643 | ND_PRINT((ndo, "\n\t Options [%s]", |
| 644 | bittok2str(ospf6_option_values, "none", |
| 645 | EXTRACT_32BITS(&llsap->llsa_options)))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 646 | |
| 647 | if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) |
| 648 | return (1); |
| 649 | lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); |
| 650 | prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 651 | ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:", |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 652 | llsap->llsa_priority, |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 653 | ip6addr_string(ndo, &llsap->llsa_lladdr), |
| 654 | prefixes)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 655 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 656 | tptr = (uint8_t *)llsap->llsa_prefix; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 657 | while (prefixes > 0) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 658 | bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 659 | if (bytelen < 0) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 660 | goto trunc; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 661 | prefixes--; |
| 662 | lsa_length -= bytelen; |
| 663 | tptr += bytelen; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 664 | } |
| 665 | break; |
| 666 | |
| 667 | case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: |
| 668 | /* Intra-Area-Prefix LSA */ |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 669 | if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) |
| 670 | return (1); |
| 671 | lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 672 | ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); |
| 673 | ospf6_print_ls_type(ndo, |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 674 | EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 675 | &lsap->lsa_un.un_intra_ap.intra_ap_lsid); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 676 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 677 | if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) |
| 678 | return (1); |
| 679 | lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 680 | ND_TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 681 | prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 682 | ND_PRINT((ndo, "\n\t Prefixes %d:", prefixes)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 683 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 684 | tptr = (uint8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 685 | while (prefixes > 0) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 686 | bytelen = ospf6_print_lsaprefix(ndo, tptr, lsa_length); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 687 | if (bytelen < 0) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 688 | goto trunc; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 689 | prefixes--; |
| 690 | lsa_length -= bytelen; |
| 691 | tptr += bytelen; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 692 | } |
| 693 | break; |
| 694 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 695 | case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 696 | if (ospf_print_grace_lsa(ndo, tptr, lsa_length) == -1) { |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 697 | return 1; |
| 698 | } |
| 699 | break; |
| 700 | |
| 701 | case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 702 | if (ospf_print_te_lsa(ndo, tptr, lsa_length) == -1) { |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 703 | return 1; |
| 704 | } |
| 705 | break; |
| 706 | |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 707 | default: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 708 | if(!print_unknown_data(ndo,tptr, |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 709 | "\n\t ", |
| 710 | lsa_length)) { |
| 711 | return (1); |
| 712 | } |
| 713 | break; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 714 | } |
| 715 | |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 716 | return (0); |
| 717 | trunc: |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 718 | return (1); |
| 719 | } |
| 720 | |
| 721 | static int |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 722 | ospf6_decode_v3(netdissect_options *ndo, |
| 723 | register const struct ospf6hdr *op, |
| 724 | register const u_char *dataend) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 725 | { |
| 726 | register const rtrid_t *ap; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 727 | register const struct lsr6 *lsrp; |
| 728 | register const struct lsa6_hdr *lshp; |
| 729 | register const struct lsa6 *lsap; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 730 | register int i; |
| 731 | |
| 732 | switch (op->ospf6_type) { |
| 733 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 734 | case OSPF_TYPE_HELLO: { |
| 735 | register const struct hello6 *hellop = (const struct hello6 *)((uint8_t *)op + OSPF6HDR_LEN); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 736 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 737 | ND_PRINT((ndo, "\n\tOptions [%s]", |
| 738 | bittok2str(ospf6_option_values, "none", |
| 739 | EXTRACT_32BITS(&hellop->hello_options)))); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 740 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 741 | ND_TCHECK(hellop->hello_deadint); |
| 742 | ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", |
| 743 | EXTRACT_16BITS(&hellop->hello_helloint), |
| 744 | EXTRACT_16BITS(&hellop->hello_deadint), |
| 745 | ipaddr_string(ndo, &hellop->hello_ifid), |
| 746 | hellop->hello_priority)); |
| 747 | |
| 748 | ND_TCHECK(hellop->hello_dr); |
| 749 | if (EXTRACT_32BITS(&hellop->hello_dr) != 0) |
| 750 | ND_PRINT((ndo, "\n\t Designated Router %s", |
| 751 | ipaddr_string(ndo, &hellop->hello_dr))); |
| 752 | ND_TCHECK(hellop->hello_bdr); |
| 753 | if (EXTRACT_32BITS(&hellop->hello_bdr) != 0) |
| 754 | ND_PRINT((ndo, ", Backup Designated Router %s", |
| 755 | ipaddr_string(ndo, &hellop->hello_bdr))); |
| 756 | if (ndo->ndo_vflag > 1) { |
| 757 | ND_PRINT((ndo, "\n\t Neighbor List:")); |
| 758 | ap = hellop->hello_neighbor; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 759 | while ((u_char *)ap < dataend) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 760 | ND_TCHECK(*ap); |
| 761 | ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 762 | ++ap; |
| 763 | } |
| 764 | } |
| 765 | break; /* HELLO */ |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 766 | } |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 767 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 768 | case OSPF_TYPE_DD: { |
| 769 | register const struct dd6 *ddp = (const struct dd6 *)((uint8_t *)op + OSPF6HDR_LEN); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 770 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 771 | ND_TCHECK(ddp->db_options); |
| 772 | ND_PRINT((ndo, "\n\tOptions [%s]", |
| 773 | bittok2str(ospf6_option_values, "none", |
| 774 | EXTRACT_32BITS(&ddp->db_options)))); |
| 775 | ND_TCHECK(ddp->db_flags); |
| 776 | ND_PRINT((ndo, ", DD Flags [%s]", |
| 777 | bittok2str(ospf6_dd_flag_values,"none",ddp->db_flags))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 778 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 779 | ND_TCHECK(ddp->db_seq); |
| 780 | ND_PRINT((ndo, ", MTU %u, DD-Sequence 0x%08x", |
| 781 | EXTRACT_16BITS(&ddp->db_mtu), |
| 782 | EXTRACT_32BITS(&ddp->db_seq))); |
| 783 | if (ndo->ndo_vflag > 1) { |
| 784 | /* Print all the LS adv's */ |
| 785 | lshp = ddp->db_lshdr; |
| 786 | while ((u_char *)lshp < dataend) { |
| 787 | if (ospf6_print_lshdr(ndo, lshp++, dataend)) |
| 788 | goto trunc; |
| 789 | } |
| 790 | } |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 791 | break; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 792 | } |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 793 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 794 | case OSPF_TYPE_LS_REQ: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 795 | if (ndo->ndo_vflag > 1) { |
| 796 | lsrp = (const struct lsr6 *)((uint8_t *)op + OSPF6HDR_LEN); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 797 | while ((u_char *)lsrp < dataend) { |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 798 | ND_TCHECK(*lsrp); |
| 799 | ND_PRINT((ndo, "\n\t Advertising Router %s", |
| 800 | ipaddr_string(ndo, &lsrp->ls_router))); |
| 801 | ospf6_print_ls_type(ndo, EXTRACT_16BITS(&lsrp->ls_type), |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 802 | &lsrp->ls_stateid); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 803 | ++lsrp; |
| 804 | } |
| 805 | } |
| 806 | break; |
| 807 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 808 | case OSPF_TYPE_LS_UPDATE: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 809 | if (ndo->ndo_vflag > 1) { |
| 810 | register const struct lsu6 *lsup = (const struct lsu6 *)((uint8_t *)op + OSPF6HDR_LEN); |
| 811 | |
| 812 | ND_TCHECK(lsup->lsu_count); |
| 813 | i = EXTRACT_32BITS(&lsup->lsu_count); |
| 814 | lsap = lsup->lsu_lsa; |
| 815 | while ((u_char *)lsap < dataend && i--) { |
| 816 | if (ospf6_print_lsa(ndo, lsap, dataend)) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 817 | goto trunc; |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 818 | lsap = (struct lsa6 *)((u_char *)lsap + |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 819 | EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); |
| 820 | } |
| 821 | } |
| 822 | break; |
| 823 | |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 824 | case OSPF_TYPE_LS_ACK: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 825 | if (ndo->ndo_vflag > 1) { |
| 826 | lshp = (const struct lsa6_hdr *)((uint8_t *)op + OSPF6HDR_LEN); |
| 827 | while ((u_char *)lshp < dataend) { |
| 828 | if (ospf6_print_lshdr(ndo, lshp++, dataend)) |
| 829 | goto trunc; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 830 | } |
| 831 | } |
| 832 | break; |
| 833 | |
| 834 | default: |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 835 | break; |
| 836 | } |
| 837 | return (0); |
| 838 | trunc: |
| 839 | return (1); |
| 840 | } |
| 841 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 842 | /* RFC5613 Section 2.2 (w/o the TLVs) */ |
| 843 | static int |
| 844 | ospf6_print_lls(netdissect_options *ndo, |
| 845 | const u_char *cp, const u_int len) |
| 846 | { |
| 847 | uint16_t llsdatalen; |
| 848 | |
| 849 | if (len == 0) |
| 850 | return 0; |
| 851 | if (len < OSPF_LLS_HDRLEN) |
| 852 | goto trunc; |
| 853 | /* Checksum */ |
| 854 | ND_TCHECK2(*cp, 2); |
| 855 | ND_PRINT((ndo, "\n\tLLS Checksum 0x%04x", EXTRACT_16BITS(cp))); |
| 856 | cp += 2; |
| 857 | /* LLS Data Length */ |
| 858 | ND_TCHECK2(*cp, 2); |
| 859 | llsdatalen = EXTRACT_16BITS(cp); |
| 860 | ND_PRINT((ndo, ", Data Length %u", llsdatalen)); |
| 861 | if (llsdatalen < OSPF_LLS_HDRLEN || llsdatalen > len) |
| 862 | goto trunc; |
| 863 | cp += 2; |
| 864 | /* LLS TLVs */ |
| 865 | ND_TCHECK2(*cp, llsdatalen - OSPF_LLS_HDRLEN); |
| 866 | /* FIXME: code in print-ospf.c can be reused to decode the TLVs */ |
| 867 | |
| 868 | return llsdatalen; |
| 869 | trunc: |
| 870 | return -1; |
| 871 | } |
| 872 | |
| 873 | /* RFC6506 Section 4.1 */ |
| 874 | static int |
| 875 | ospf6_decode_at(netdissect_options *ndo, |
| 876 | const u_char *cp, const u_int len) |
| 877 | { |
| 878 | uint16_t authdatalen; |
| 879 | |
| 880 | if (len == 0) |
| 881 | return 0; |
| 882 | if (len < OSPF6_AT_HDRLEN) |
| 883 | goto trunc; |
| 884 | /* Authentication Type */ |
| 885 | ND_TCHECK2(*cp, 2); |
| 886 | ND_PRINT((ndo, "\n\tAuthentication Type %s", tok2str(ospf6_auth_type_str, "unknown (0x%04x)", EXTRACT_16BITS(cp)))); |
| 887 | cp += 2; |
| 888 | /* Auth Data Len */ |
| 889 | ND_TCHECK2(*cp, 2); |
| 890 | authdatalen = EXTRACT_16BITS(cp); |
| 891 | ND_PRINT((ndo, ", Length %u", authdatalen)); |
| 892 | if (authdatalen < OSPF6_AT_HDRLEN || authdatalen > len) |
| 893 | goto trunc; |
| 894 | cp += 2; |
| 895 | /* Reserved */ |
| 896 | ND_TCHECK2(*cp, 2); |
| 897 | cp += 2; |
| 898 | /* Security Association ID */ |
| 899 | ND_TCHECK2(*cp, 2); |
| 900 | ND_PRINT((ndo, ", SAID %u", EXTRACT_16BITS(cp))); |
| 901 | cp += 2; |
| 902 | /* Cryptographic Sequence Number (High-Order 32 Bits) */ |
| 903 | ND_TCHECK2(*cp, 4); |
| 904 | ND_PRINT((ndo, ", CSN 0x%08x", EXTRACT_32BITS(cp))); |
| 905 | cp += 4; |
| 906 | /* Cryptographic Sequence Number (Low-Order 32 Bits) */ |
| 907 | ND_TCHECK2(*cp, 4); |
| 908 | ND_PRINT((ndo, ":%08x", EXTRACT_32BITS(cp))); |
| 909 | cp += 4; |
| 910 | /* Authentication Data */ |
| 911 | ND_TCHECK2(*cp, authdatalen - OSPF6_AT_HDRLEN); |
| 912 | if (ndo->ndo_vflag > 1) |
| 913 | print_unknown_data(ndo,cp, "\n\tAuthentication Data ", authdatalen - OSPF6_AT_HDRLEN); |
| 914 | return 0; |
| 915 | |
| 916 | trunc: |
| 917 | return 1; |
| 918 | } |
| 919 | |
| 920 | /* The trailing data may include LLS and/or AT data (in this specific order). |
| 921 | * LLS data may be present only in Hello and DBDesc packets with the L-bit set. |
| 922 | * AT data may be present in Hello and DBDesc packets with the AT-bit set or in |
| 923 | * any other packet type, thus decode the AT data regardless of the AT-bit. |
| 924 | */ |
| 925 | static int |
| 926 | ospf6_decode_v3_trailer(netdissect_options *ndo, |
| 927 | const struct ospf6hdr *op, const u_char *cp, const unsigned len) |
| 928 | { |
| 929 | int llslen = 0; |
| 930 | int lls_hello = 0; |
| 931 | int lls_dd = 0; |
| 932 | |
| 933 | if (op->ospf6_type == OSPF_TYPE_HELLO) { |
| 934 | const struct hello6 *hellop = (const struct hello6 *)((uint8_t *)op + OSPF6HDR_LEN); |
| 935 | if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L) |
| 936 | lls_hello = 1; |
| 937 | } else if (op->ospf6_type == OSPF_TYPE_DD) { |
| 938 | const struct dd6 *ddp = (const struct dd6 *)((uint8_t *)op + OSPF6HDR_LEN); |
| 939 | if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L) |
| 940 | lls_dd = 1; |
| 941 | } |
| 942 | if ((lls_hello || lls_dd) && (llslen = ospf6_print_lls(ndo, cp, len)) < 0) |
| 943 | goto trunc; |
| 944 | return ospf6_decode_at(ndo, cp + llslen, len - llslen); |
| 945 | |
| 946 | trunc: |
| 947 | return 1; |
| 948 | } |
| 949 | |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 950 | void |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 951 | ospf6_print(netdissect_options *ndo, |
| 952 | register const u_char *bp, register u_int length) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 953 | { |
| 954 | register const struct ospf6hdr *op; |
| 955 | register const u_char *dataend; |
| 956 | register const char *cp; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 957 | uint16_t datalen; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 958 | |
| 959 | op = (struct ospf6hdr *)bp; |
| 960 | |
| 961 | /* If the type is valid translate it, or just print the type */ |
| 962 | /* value. If it's not valid, say so and return */ |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 963 | ND_TCHECK(op->ospf6_type); |
| 964 | cp = tok2str(ospf6_type_values, "unknown packet type (%u)", op->ospf6_type); |
| 965 | ND_PRINT((ndo, "OSPFv%u, %s, length %d", op->ospf6_version, cp, length)); |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 966 | if (*cp == 'u') { |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 967 | return; |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 968 | } |
| JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 969 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 970 | if(!ndo->ndo_vflag) { /* non verbose - so lets bail out here */ |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 971 | return; |
| 972 | } |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 973 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 974 | /* OSPFv3 data always comes first and optional trailing data may follow. */ |
| 975 | ND_TCHECK(op->ospf6_len); |
| 976 | datalen = EXTRACT_16BITS(&op->ospf6_len); |
| 977 | if (datalen > length) { |
| 978 | ND_PRINT((ndo, " [len %d]", datalen)); |
| 979 | return; |
| 980 | } |
| 981 | dataend = bp + datalen; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 982 | |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 983 | ND_TCHECK(op->ospf6_routerid); |
| 984 | ND_PRINT((ndo, "\n\tRouter-ID %s", ipaddr_string(ndo, &op->ospf6_routerid))); |
| 985 | |
| 986 | ND_TCHECK(op->ospf6_areaid); |
| 987 | if (EXTRACT_32BITS(&op->ospf6_areaid) != 0) |
| 988 | ND_PRINT((ndo, ", Area %s", ipaddr_string(ndo, &op->ospf6_areaid))); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 989 | else |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 990 | ND_PRINT((ndo, ", Backbone Area")); |
| 991 | ND_TCHECK(op->ospf6_instanceid); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 992 | if (op->ospf6_instanceid) |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 993 | ND_PRINT((ndo, ", Instance %u", op->ospf6_instanceid)); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 994 | |
| 995 | /* Do rest according to version. */ |
| 996 | switch (op->ospf6_version) { |
| 997 | |
| 998 | case 3: |
| 999 | /* ospf version 3 */ |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 1000 | if (ospf6_decode_v3(ndo, op, dataend) || |
| 1001 | ospf6_decode_v3_trailer(ndo, op, dataend, length - datalen)) |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1002 | goto trunc; |
| 1003 | break; |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1004 | } /* end switch on version */ |
| 1005 | |
| 1006 | return; |
| 1007 | trunc: |
| Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame^] | 1008 | ND_PRINT((ndo, "%s", tstr)); |
| The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1009 | } |