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