1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright (c) 1999 by Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <stdio.h> 30*0Sstevel@tonic-gate #include <fcntl.h> 31*0Sstevel@tonic-gate #include <sys/socket.h> 32*0Sstevel@tonic-gate #include <netinet/in.h> 33*0Sstevel@tonic-gate #include <protocols/routed.h> 34*0Sstevel@tonic-gate #include <string.h> 35*0Sstevel@tonic-gate #include <arpa/inet.h> 36*0Sstevel@tonic-gate #include "snoop.h" 37*0Sstevel@tonic-gate #include "snoop_mip.h" 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate /* 40*0Sstevel@tonic-gate * This defines the length of internal, unbounded buffers. We set 41*0Sstevel@tonic-gate * this to be MAXLINE (the maximum verbose display line length) - 42*0Sstevel@tonic-gate * 64, which should be enough for all necessary descriptions. 43*0Sstevel@tonic-gate */ 44*0Sstevel@tonic-gate #define BUFLEN MAXLINE - 64 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate extern char *dlc_header; 47*0Sstevel@tonic-gate extern char *addrtoname(); 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate static enum EXT_TYPE { ADV, REG }; 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate /* 52*0Sstevel@tonic-gate * This defines the interface for all extention interpreter 53*0Sstevel@tonic-gate * functions. The function will be called with following 54*0Sstevel@tonic-gate * parameters: 55*0Sstevel@tonic-gate * 56*0Sstevel@tonic-gate * type: IN The type code for this extention 57*0Sstevel@tonic-gate * len IN The length of the payload (i.e. the 58*0Sstevel@tonic-gate * length field in an extension header) 59*0Sstevel@tonic-gate * payload IN A pointer to the beginning of the 60*0Sstevel@tonic-gate * extension payload 61*0Sstevel@tonic-gate */ 62*0Sstevel@tonic-gate typedef void interpreter_f(uint8_t type, uint8_t len, uchar_t *payload); 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate struct ext_dispatch { 65*0Sstevel@tonic-gate uint8_t type; 66*0Sstevel@tonic-gate interpreter_f *pfunc; 67*0Sstevel@tonic-gate }; 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate /* Description structure -- maps type to description */ 70*0Sstevel@tonic-gate struct ext_desc { 71*0Sstevel@tonic-gate uint8_t type; 72*0Sstevel@tonic-gate const char *desc; 73*0Sstevel@tonic-gate }; 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate /* 76*0Sstevel@tonic-gate * Interpreter function prototypes for both adv and reg. These 77*0Sstevel@tonic-gate * all must implement the interpret_f interface defined above. 78*0Sstevel@tonic-gate */ 79*0Sstevel@tonic-gate static void spi_ext(uint8_t, uint8_t, uchar_t *); 80*0Sstevel@tonic-gate static void key_ext(uint8_t, uint8_t, uchar_t *); 81*0Sstevel@tonic-gate static void trav_ext(uint8_t, uint8_t, uchar_t *); 82*0Sstevel@tonic-gate static void empty_ext(uint8_t, uint8_t, uchar_t *); 83*0Sstevel@tonic-gate static void nai_ext(uint8_t, uint8_t, uchar_t *); 84*0Sstevel@tonic-gate static void chall_ext(uint8_t, uint8_t, uchar_t *); 85*0Sstevel@tonic-gate static void ma_ext(uint8_t, uint8_t, uchar_t *); 86*0Sstevel@tonic-gate static void prefix_ext(uint8_t, uint8_t, uchar_t *); 87*0Sstevel@tonic-gate static void unk_ext(uint8_t, uint8_t, uchar_t *); 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate /* R E G I S T R A T I O N */ 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate #define REG_TBL_LEN 10 /* update this when adding to the table */ 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate /* Reg: type to description mapping table */ 94*0Sstevel@tonic-gate static struct ext_desc reg_desc[] = { 95*0Sstevel@tonic-gate MN_HA_AUTH, "(Mobile-Home Authentication Extension)", 96*0Sstevel@tonic-gate MN_FA_AUTH, "(Mobile-Foreign Authentication Extension", 97*0Sstevel@tonic-gate FA_HA_AUTH, "(Foreign-Home Authentication Extension)", 98*0Sstevel@tonic-gate GEN_AUTH, "(Generalized Authentication Extension)", 99*0Sstevel@tonic-gate MN_HA_KEY, "(Mobile-Home Key Extension)", 100*0Sstevel@tonic-gate MN_FA_KEY, "(Mobile-Foreign Key Extension)", 101*0Sstevel@tonic-gate MN_HA_TRAVERSE, "(Firewall Traversal Extension)", 102*0Sstevel@tonic-gate ENCAP_DELIV, "(Encapsulating Delivery Style Extension)", 103*0Sstevel@tonic-gate MN_NAI, "(Mobile Node Network Access Identifier)", 104*0Sstevel@tonic-gate FA_CHALLENGE, "(Mobile-Foreign Agent Challenge)", 105*0Sstevel@tonic-gate 0, "(Unrecognized Extension)" 106*0Sstevel@tonic-gate }; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate #define GENAUTH_TBL_LEN 1 /* update this when adding to the table */ 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate /* Subtypes for Generic Authentication Extension type (type 36) */ 111*0Sstevel@tonic-gate static struct ext_desc genauth_desc[] = { 112*0Sstevel@tonic-gate GEN_AUTH_MN_AAA, "(MN-AAA Authentication Subtype)", 113*0Sstevel@tonic-gate 0, "(Unrecognized Subtype)" 114*0Sstevel@tonic-gate }; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* Reg: type to function mapping table */ 117*0Sstevel@tonic-gate static struct ext_dispatch reg_dispatch[] = { 118*0Sstevel@tonic-gate MN_HA_AUTH, spi_ext, 119*0Sstevel@tonic-gate MN_FA_AUTH, spi_ext, 120*0Sstevel@tonic-gate FA_HA_AUTH, spi_ext, 121*0Sstevel@tonic-gate GEN_AUTH, spi_ext, 122*0Sstevel@tonic-gate MN_HA_KEY, key_ext, 123*0Sstevel@tonic-gate MN_FA_KEY, key_ext, 124*0Sstevel@tonic-gate MN_HA_TRAVERSE, trav_ext, 125*0Sstevel@tonic-gate ENCAP_DELIV, empty_ext, 126*0Sstevel@tonic-gate MN_NAI, nai_ext, 127*0Sstevel@tonic-gate FA_CHALLENGE, chall_ext, 128*0Sstevel@tonic-gate 0, unk_ext 129*0Sstevel@tonic-gate }; 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate /* A D V E R T I S E M E N T */ 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate #define ADV_TBL_LEN 5 /* update this when adding to the table */ 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate /* Adv: type to description mapping table */ 136*0Sstevel@tonic-gate static struct ext_desc adv_desc[] = { 137*0Sstevel@tonic-gate ICMP_ADV_MSG_PADDING_EXT, "(Padding)", 138*0Sstevel@tonic-gate ICMP_ADV_MSG_MOBILITY_AGT_EXT, "(Mobility Agent Extension)", 139*0Sstevel@tonic-gate ICMP_ADV_MSG_PREFIX_LENGTH_EXT, "(Prefix Lengths)", 140*0Sstevel@tonic-gate ICMP_ADV_MSG_FA_CHALLENGE, "(Foreign Agent Challenge)", 141*0Sstevel@tonic-gate ICMP_ADV_MSG_FA_NAI, "(Foreign Agent NAI)", 142*0Sstevel@tonic-gate 0, "(Unrecognized Extension)" 143*0Sstevel@tonic-gate }; 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate /* Adv: type to function mapping table */ 146*0Sstevel@tonic-gate static struct ext_dispatch adv_dispatch[] = { 147*0Sstevel@tonic-gate ICMP_ADV_MSG_PADDING_EXT, NULL, /* never called */ 148*0Sstevel@tonic-gate ICMP_ADV_MSG_MOBILITY_AGT_EXT, ma_ext, 149*0Sstevel@tonic-gate ICMP_ADV_MSG_PREFIX_LENGTH_EXT, prefix_ext, 150*0Sstevel@tonic-gate ICMP_ADV_MSG_FA_CHALLENGE, chall_ext, 151*0Sstevel@tonic-gate ICMP_ADV_MSG_FA_NAI, nai_ext, 152*0Sstevel@tonic-gate 0, unk_ext 153*0Sstevel@tonic-gate }; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate #define GETSPI(payload, hi, low) \ 156*0Sstevel@tonic-gate (void) memcpy(&hi, payload, sizeof (hi)); \ 157*0Sstevel@tonic-gate (void) memcpy(&low, payload + sizeof (hi), sizeof (low)) 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate static void dumphex(uchar_t *payload, int payload_len, char *buf, char *msg) { 160*0Sstevel@tonic-gate int index; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate for (index = 0; index < payload_len; index++) { 163*0Sstevel@tonic-gate (void) sprintf(&buf[index * 3], " %.2x", payload[index]); 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate (void) sprintf(get_line((char *)payload-dlc_header, 1), msg, buf); 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate static const char *get_desc(struct ext_desc table[], uint8_t type, int max) { 170*0Sstevel@tonic-gate int i; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate for (i = 0; i < max && table[i].type != type; i++) 173*0Sstevel@tonic-gate /* NO_OP */; 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate return (table[i].desc); 176*0Sstevel@tonic-gate } 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate /* 179*0Sstevel@tonic-gate * The following is an accessor for the description table, used by 180*0Sstevel@tonic-gate * snoop_icmp.c. This maintains the encapsulation of the internal 181*0Sstevel@tonic-gate * description table. 182*0Sstevel@tonic-gate */ 183*0Sstevel@tonic-gate const char *get_mip_adv_desc(uint8_t type) { 184*0Sstevel@tonic-gate return (get_desc(adv_desc, type, ADV_TBL_LEN)); 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate static interpreter_f *get_interpreter(struct ext_dispatch table[], 188*0Sstevel@tonic-gate uint8_t type, 189*0Sstevel@tonic-gate int max) { 190*0Sstevel@tonic-gate int i; 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate for (i = 0; i < max && table[i].type != type; i++) 193*0Sstevel@tonic-gate /* NO_OP */; 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate return (table[i].pfunc); 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate static int 199*0Sstevel@tonic-gate interpret_extensions(uchar_t *ext, 200*0Sstevel@tonic-gate int regext_size, 201*0Sstevel@tonic-gate enum EXT_TYPE etype) { 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate int curr_size = regext_size; /* remaining total for all exts */ 204*0Sstevel@tonic-gate exthdr_t *exthdr; 205*0Sstevel@tonic-gate gen_exthdr_t *gen_exthdr; 206*0Sstevel@tonic-gate const char *st; 207*0Sstevel@tonic-gate uchar_t *p; 208*0Sstevel@tonic-gate interpreter_f *f; 209*0Sstevel@tonic-gate uint8_t ext_type; 210*0Sstevel@tonic-gate uint16_t ext_len; 211*0Sstevel@tonic-gate uint_t ext_hdrlen; 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate show_space(); 214*0Sstevel@tonic-gate exthdr = (exthdr_t *)ALIGN(ext); 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate do { 218*0Sstevel@tonic-gate ext_type = exthdr->type; 219*0Sstevel@tonic-gate if (ext_type == GEN_AUTH) { 220*0Sstevel@tonic-gate gen_exthdr = (gen_exthdr_t *)exthdr; 221*0Sstevel@tonic-gate ext_hdrlen = sizeof (gen_exthdr_t); 222*0Sstevel@tonic-gate ext_len = ntohs(gen_exthdr->length); 223*0Sstevel@tonic-gate } else { 224*0Sstevel@tonic-gate ext_hdrlen = sizeof (exthdr_t); 225*0Sstevel@tonic-gate ext_len = exthdr->length; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate if (!((etype == ADV && ext_type == ICMP_ADV_MSG_PADDING_EXT && 229*0Sstevel@tonic-gate curr_size >= 1) || 230*0Sstevel@tonic-gate curr_size >= ext_hdrlen + ext_len)) 231*0Sstevel@tonic-gate break; 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate /* Print description for this extension */ 234*0Sstevel@tonic-gate if (etype == ADV) { 235*0Sstevel@tonic-gate st = get_desc(adv_desc, ext_type, ADV_TBL_LEN); 236*0Sstevel@tonic-gate } else /* REG */ { 237*0Sstevel@tonic-gate st = get_desc(reg_desc, ext_type, REG_TBL_LEN); 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate (void) sprintf(get_line((char *)exthdr-dlc_header, 1), 241*0Sstevel@tonic-gate "Extension header type = %d %s", ext_type, st); 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate if (ext_type == GEN_AUTH) { 244*0Sstevel@tonic-gate st = get_desc(genauth_desc, gen_exthdr->subtype, 245*0Sstevel@tonic-gate GENAUTH_TBL_LEN); 246*0Sstevel@tonic-gate (void) sprintf(get_line((char *)exthdr-dlc_header, 1), 247*0Sstevel@tonic-gate "Subtype = %d %s", gen_exthdr->subtype, st); 248*0Sstevel@tonic-gate } 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate /* Special case for 1-byte padding */ 251*0Sstevel@tonic-gate if (etype == ADV && ext_type == ICMP_ADV_MSG_PADDING_EXT) { 252*0Sstevel@tonic-gate exthdr = (exthdr_t *)((uchar_t *)exthdr + 1); 253*0Sstevel@tonic-gate curr_size--; 254*0Sstevel@tonic-gate continue; 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&exthdr->length-dlc_header, 1), 258*0Sstevel@tonic-gate "Length = %d", ext_len); 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate /* Parse out the extension's payload */ 261*0Sstevel@tonic-gate p = (uchar_t *)exthdr + ext_hdrlen; 262*0Sstevel@tonic-gate curr_size -= (ext_hdrlen + ext_len); 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate if (etype == ADV) { 265*0Sstevel@tonic-gate f = get_interpreter(adv_dispatch, ext_type, ADV_TBL_LEN); 266*0Sstevel@tonic-gate } else /* REG */ { 267*0Sstevel@tonic-gate f = get_interpreter(reg_dispatch, ext_type, REG_TBL_LEN); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate f(ext_type, ext_len, p); 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate show_space(); 273*0Sstevel@tonic-gate exthdr = (exthdr_t *)(p + ext_len); 274*0Sstevel@tonic-gate } while (B_TRUE); 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate return (0); 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate void interpret_icmp_mip_ext(uchar_t *p, int len) { 280*0Sstevel@tonic-gate show_space(); 281*0Sstevel@tonic-gate show_header("ICMP: ", " MIP Advertisement Extensions ", len); 282*0Sstevel@tonic-gate show_space(); 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate interpret_extensions(p, len, ADV); 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate void 288*0Sstevel@tonic-gate interpret_mip_cntrlmsg(int flags, uchar_t *msg, int fraglen) { 289*0Sstevel@tonic-gate char *pt, *pc = NULL; 290*0Sstevel@tonic-gate char *line; 291*0Sstevel@tonic-gate regreq_t rreq[1]; 292*0Sstevel@tonic-gate regrep_t rrep[1]; 293*0Sstevel@tonic-gate int regext_size; 294*0Sstevel@tonic-gate uchar_t *regext_data; 295*0Sstevel@tonic-gate struct in_addr addr_temp; 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate /* First byte of the message should be the type */ 299*0Sstevel@tonic-gate switch (*msg) { 300*0Sstevel@tonic-gate case REG_TYPE_REQ: 301*0Sstevel@tonic-gate if (fraglen < sizeof (regreq_t)) 302*0Sstevel@tonic-gate return; 303*0Sstevel@tonic-gate pt = (flags & F_DTAIL ? "registration request ":"reg rqst "); 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate (void) memcpy(rreq, msg, sizeof (*rreq)); 306*0Sstevel@tonic-gate regext_size = fraglen - sizeof (regreq_t); 307*0Sstevel@tonic-gate regext_data = msg + sizeof (*rreq); 308*0Sstevel@tonic-gate break; 309*0Sstevel@tonic-gate case REG_TYPE_REP: 310*0Sstevel@tonic-gate if (fraglen < sizeof (regrep_t)) 311*0Sstevel@tonic-gate return; 312*0Sstevel@tonic-gate pt = (flags & F_DTAIL ? "registration reply ":"reg reply "); 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate (void) memcpy(rrep, msg, sizeof (*rrep)); 315*0Sstevel@tonic-gate regext_size = fraglen - sizeof (regrep_t); 316*0Sstevel@tonic-gate regext_data = msg + sizeof (*rrep); 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate switch (rrep->code) { 319*0Sstevel@tonic-gate case REPLY_CODE_ACK: 320*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL)) ? 321*0Sstevel@tonic-gate "OK" : "OK code 0"; 322*0Sstevel@tonic-gate break; 323*0Sstevel@tonic-gate case REPLY_CODE_ACK_NO_SIMULTANEOUS: 324*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 325*0Sstevel@tonic-gate "OK simultaneous bindings" : "OK code 1"; 326*0Sstevel@tonic-gate break; 327*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_UNSPECIFIED: 328*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 329*0Sstevel@tonic-gate "FA denial: unspecified":"FA denial: code 64"; 330*0Sstevel@tonic-gate break; 331*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_PROHIBITED: 332*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 333*0Sstevel@tonic-gate "FA denial: prohibited":"FA denial: code 65"; 334*0Sstevel@tonic-gate break; 335*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_RESOURCES: 336*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 337*0Sstevel@tonic-gate "FA denial: no resources":"FA denial: code 66"; 338*0Sstevel@tonic-gate break; 339*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_MN_AUTH: 340*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 341*0Sstevel@tonic-gate "FA denial: MN auth failed":"FA denial: code 67"; 342*0Sstevel@tonic-gate break; 343*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_HA_AUTH: 344*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 345*0Sstevel@tonic-gate "FA denial: HA auth failed": 346*0Sstevel@tonic-gate "FA denial: code 68"; 347*0Sstevel@tonic-gate break; 348*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_LIFETIME: 349*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 350*0Sstevel@tonic-gate "FA denial: lifetime":"FA denial: code 69"; 351*0Sstevel@tonic-gate break; 352*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_BAD_REQUEST: 353*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 354*0Sstevel@tonic-gate "FA denial: bad request": "FA: code 70"; 355*0Sstevel@tonic-gate break; 356*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_BAD_REPLY: 357*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 358*0Sstevel@tonic-gate "FA denial: bad Reply":"FA denial: code 71"; 359*0Sstevel@tonic-gate break; 360*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_ENCAP_UNAVAILABLE: 361*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 362*0Sstevel@tonic-gate "FA denial: encapsulation":"FA denial: code 72"; 363*0Sstevel@tonic-gate break; 364*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_VJ_UNAVAILABLE: 365*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 366*0Sstevel@tonic-gate "FA denial: VJ compression":"FA denial: code 73"; 367*0Sstevel@tonic-gate break; 368*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_BIDIR_TUNNEL_UNAVAILABLE: 369*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 370*0Sstevel@tonic-gate "FA denial: reverse tunnel unavailable": 371*0Sstevel@tonic-gate "FA denial: code 74"; 372*0Sstevel@tonic-gate break; 373*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_BIDIR_TUNNEL_NO_TBIT: 374*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 375*0Sstevel@tonic-gate "FA denial: reverse tunnel: missing T-bit": 376*0Sstevel@tonic-gate "FA denial: code 75"; 377*0Sstevel@tonic-gate break; 378*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_BIDIR_TUNNEL_TOO_DISTANT: 379*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 380*0Sstevel@tonic-gate "FA denial: reverse tunnel: too distant": 381*0Sstevel@tonic-gate "FA denial: code 76"; 382*0Sstevel@tonic-gate break; 383*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_ICMP_HA_NET_UNREACHABLE: 384*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 385*0Sstevel@tonic-gate "FA denial: home network unreachable": 386*0Sstevel@tonic-gate "FA denial: code 80"; 387*0Sstevel@tonic-gate break; 388*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_ICMP_HA_HOST_UNREACHABLE: 389*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 390*0Sstevel@tonic-gate "FA denial: HA host unreachable": 391*0Sstevel@tonic-gate "FA denial: code 81"; 392*0Sstevel@tonic-gate break; 393*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_ICMP_HA_PORT_UNREACHABLE: 394*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 395*0Sstevel@tonic-gate "FA denial: HA port unreachable": 396*0Sstevel@tonic-gate "FA denial: code 82"; 397*0Sstevel@tonic-gate break; 398*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_ICMP_HA_UNREACHABLE: 399*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 400*0Sstevel@tonic-gate "FA denial: HA unreachable":"FA denial: code 88"; 401*0Sstevel@tonic-gate break; 402*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_UNIQUE_HOMEADDR_REQD: 403*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 404*0Sstevel@tonic-gate "FA denial: Unique Home Addr Required": 405*0Sstevel@tonic-gate "FA denial: code 96"; 406*0Sstevel@tonic-gate break; 407*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_MISSING_NAI: 408*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 409*0Sstevel@tonic-gate "FA denial: Missing NAI": 410*0Sstevel@tonic-gate "FA denial: code 97"; 411*0Sstevel@tonic-gate break; 412*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_MISSING_HOME_AGENT: 413*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 414*0Sstevel@tonic-gate "FA denial: Missing Home Agent": 415*0Sstevel@tonic-gate "FA denial: code 98"; 416*0Sstevel@tonic-gate break; 417*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_UNKNOWN_CHALLENGE: 418*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 419*0Sstevel@tonic-gate "FA denial: Unknown Challenge": 420*0Sstevel@tonic-gate "FA denial: code 104"; 421*0Sstevel@tonic-gate break; 422*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_MISSING_CHALLENGE: 423*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 424*0Sstevel@tonic-gate "FA denial: Missing Challenge": 425*0Sstevel@tonic-gate "FA denial: code 105"; 426*0Sstevel@tonic-gate break; 427*0Sstevel@tonic-gate case REPLY_CODE_FA_NACK_MISSING_MN_FA: 428*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 429*0Sstevel@tonic-gate "FA denial: Missing Mobile-Foreign Key Extension": 430*0Sstevel@tonic-gate "FA denial: code 106"; 431*0Sstevel@tonic-gate break; 432*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_UNSPECIFIED: 433*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 434*0Sstevel@tonic-gate "HA denial: unspecified":"HA denial: code 128"; 435*0Sstevel@tonic-gate break; 436*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_PROHIBITED: 437*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 438*0Sstevel@tonic-gate "HA denial: prohibited":"HA denial: code 129"; 439*0Sstevel@tonic-gate break; 440*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_RESOURCES: 441*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 442*0Sstevel@tonic-gate "HA denial: no resources":"HA denial: code 130"; 443*0Sstevel@tonic-gate break; 444*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_MN_AUTH: 445*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 446*0Sstevel@tonic-gate "HA denial: MN auth failed":"HA denial: code 131"; 447*0Sstevel@tonic-gate break; 448*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_FA_AUTH: 449*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 450*0Sstevel@tonic-gate "HA denial: FA auth failed":"HA denial: code 132"; 451*0Sstevel@tonic-gate break; 452*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_ID_MISMATCH: 453*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 454*0Sstevel@tonic-gate "HA denial: ID mismatch":"HA denial: code 133"; 455*0Sstevel@tonic-gate break; 456*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_BAD_REQUEST: 457*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 458*0Sstevel@tonic-gate "HA denial: bad request":"HA denial: code 134"; 459*0Sstevel@tonic-gate break; 460*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_TOO_MANY_BINDINGS: 461*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 462*0Sstevel@tonic-gate "HA denial: too many bindings": 463*0Sstevel@tonic-gate "HA denial: code 135"; 464*0Sstevel@tonic-gate break; 465*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_BAD_HA_ADDRESS: 466*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 467*0Sstevel@tonic-gate "HA denial: bad HA address":"HA denial: code 136"; 468*0Sstevel@tonic-gate break; 469*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_BIDIR_TUNNEL_UNAVAILABLE: 470*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 471*0Sstevel@tonic-gate "HA denial: no reverse tunnel": 472*0Sstevel@tonic-gate "HA denial: code 137"; 473*0Sstevel@tonic-gate break; 474*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_BIDIR_TUNNEL_NO_TBIT: 475*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 476*0Sstevel@tonic-gate "HA denial: reverse tunnel: no T-bit": 477*0Sstevel@tonic-gate "HA denial: code 138"; 478*0Sstevel@tonic-gate break; 479*0Sstevel@tonic-gate case REPLY_CODE_HA_NACK_BIDIR_ENCAP_UNAVAILABLE: 480*0Sstevel@tonic-gate pc = ((flags & F_ALLSUM) || (flags & F_DTAIL))? 481*0Sstevel@tonic-gate "HA denial: encapsulation unavailable": 482*0Sstevel@tonic-gate "HA denial: code 139"; 483*0Sstevel@tonic-gate break; 484*0Sstevel@tonic-gate default: 485*0Sstevel@tonic-gate pc = "?"; 486*0Sstevel@tonic-gate break; 487*0Sstevel@tonic-gate } 488*0Sstevel@tonic-gate break; 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate default : 491*0Sstevel@tonic-gate break; 492*0Sstevel@tonic-gate } 493*0Sstevel@tonic-gate if (flags & F_SUM) { 494*0Sstevel@tonic-gate line = get_sum_line(); 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate if (pc != NULL) 497*0Sstevel@tonic-gate (void) sprintf(line, "Mobile IP %s(%s)", pt, pc); 498*0Sstevel@tonic-gate else 499*0Sstevel@tonic-gate (void) sprintf(line, "Mobile IP %s", pt); 500*0Sstevel@tonic-gate } 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate if (flags & F_DTAIL) { 503*0Sstevel@tonic-gate show_header("MIP: ", "Mobile IP Header", fraglen); 504*0Sstevel@tonic-gate show_space(); 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate if (*msg == REG_TYPE_REQ) { 507*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&rreq - 508*0Sstevel@tonic-gate dlc_header, 1), "Registration header type = %s", 509*0Sstevel@tonic-gate pt); 510*0Sstevel@tonic-gate (void) sprintf(get_line( 511*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 512*0Sstevel@tonic-gate "%d... .... = %s simultaneous bindings ", 513*0Sstevel@tonic-gate (rreq->Simultaneous_registration == 1)? 1 : 0, 514*0Sstevel@tonic-gate (rreq->Simultaneous_registration == 1)? "":"no"); 515*0Sstevel@tonic-gate (void) sprintf(get_line( 516*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 517*0Sstevel@tonic-gate ".%d.. .... = %s broadcast datagrams ", 518*0Sstevel@tonic-gate (rreq->Broadcasts_desired == 1) ? 1 : 0, 519*0Sstevel@tonic-gate (rreq->Broadcasts_desired == 1) ? "":"no"); 520*0Sstevel@tonic-gate (void) sprintf(get_line( 521*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 522*0Sstevel@tonic-gate "..%d. .... = %s decapsulation by MN", 523*0Sstevel@tonic-gate (rreq->Decapsulation_done_locally == 1) ? 1 : 0, 524*0Sstevel@tonic-gate (rreq->Decapsulation_done_locally == 1) ? 525*0Sstevel@tonic-gate "" : "no"); 526*0Sstevel@tonic-gate (void) sprintf(get_line( 527*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 528*0Sstevel@tonic-gate "...%d .... = %s minimum encapsulation ", 529*0Sstevel@tonic-gate (rreq->Minimal_encap_desired == 1) ? 1 : 0, 530*0Sstevel@tonic-gate (rreq->Minimal_encap_desired == 1) ? "" : "no"); 531*0Sstevel@tonic-gate (void) sprintf(get_line( 532*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 533*0Sstevel@tonic-gate ".... %d... = %s GRE encapsulation ", 534*0Sstevel@tonic-gate (rreq->GRE_encap_desired == 1) ? 1 : 0, 535*0Sstevel@tonic-gate (rreq->GRE_encap_desired == 1) ? "" : "no"); 536*0Sstevel@tonic-gate (void) sprintf(get_line( 537*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 538*0Sstevel@tonic-gate ".... .%d.. = %s VJ hdr Compression ", 539*0Sstevel@tonic-gate (rreq->VJ_compression_desired == 1) ? 1 : 0, 540*0Sstevel@tonic-gate (rreq->VJ_compression_desired == 1) ? "" : "no"); 541*0Sstevel@tonic-gate (void) sprintf(get_line( 542*0Sstevel@tonic-gate (char *)(((uchar_t *)&rreq) + 1) - dlc_header, 1), 543*0Sstevel@tonic-gate ".... ..%d. = %s reverse tunnel", 544*0Sstevel@tonic-gate (rreq->BiDirectional_Tunnel_desired == 1) ? 1 : 0, 545*0Sstevel@tonic-gate (rreq->BiDirectional_Tunnel_desired == 1) ? 546*0Sstevel@tonic-gate "" : "no"); 547*0Sstevel@tonic-gate if (ntohs(rreq->lifetime) == 0xffff) { 548*0Sstevel@tonic-gate (void) sprintf(get_line( 549*0Sstevel@tonic-gate (char *)&rreq->lifetime - dlc_header, 1), 550*0Sstevel@tonic-gate "Life Time = 0xFFFF (infinity)"); 551*0Sstevel@tonic-gate } else if (ntohs(rreq->lifetime) == 0) { 552*0Sstevel@tonic-gate (void) sprintf(get_line( 553*0Sstevel@tonic-gate (char *)&rreq->lifetime - dlc_header, 1), 554*0Sstevel@tonic-gate "Life Time = 0 " 555*0Sstevel@tonic-gate "(request for de-registration)"); 556*0Sstevel@tonic-gate } else { 557*0Sstevel@tonic-gate (void) sprintf(get_line( 558*0Sstevel@tonic-gate (char *)&rreq->lifetime - dlc_header, 1), 559*0Sstevel@tonic-gate "Life time = %d seconds", 560*0Sstevel@tonic-gate ntohs(rreq->lifetime)); 561*0Sstevel@tonic-gate } 562*0Sstevel@tonic-gate addr_temp.s_addr = rreq->home_addr; 563*0Sstevel@tonic-gate (void) sprintf(get_line( 564*0Sstevel@tonic-gate (char *)&rreq->home_addr - dlc_header, 1), 565*0Sstevel@tonic-gate "Home address = %s, %s", 566*0Sstevel@tonic-gate inet_ntoa(addr_temp), 567*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 568*0Sstevel@tonic-gate addr_temp.s_addr = rreq->home_agent_addr; 569*0Sstevel@tonic-gate (void) sprintf(get_line( 570*0Sstevel@tonic-gate (char *)&rreq->home_agent_addr - dlc_header, 1), 571*0Sstevel@tonic-gate "Home Agent address = %s, %s", 572*0Sstevel@tonic-gate inet_ntoa(addr_temp), 573*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 574*0Sstevel@tonic-gate addr_temp.s_addr = rreq->care_of_addr; 575*0Sstevel@tonic-gate (void) sprintf(get_line( 576*0Sstevel@tonic-gate (char *)&rreq->care_of_addr - dlc_header, 1), 577*0Sstevel@tonic-gate "Care of address = %s, %s", 578*0Sstevel@tonic-gate inet_ntoa(addr_temp), 579*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 580*0Sstevel@tonic-gate (void) sprintf(get_line( 581*0Sstevel@tonic-gate (char *)&rreq->identification - dlc_header, 1), 582*0Sstevel@tonic-gate "Identification = 0x%x-%x", 583*0Sstevel@tonic-gate ntohl(rreq->identification.high_bits), 584*0Sstevel@tonic-gate ntohl(rreq->identification.low_bits)); 585*0Sstevel@tonic-gate } else if (*msg == REG_TYPE_REP) { 586*0Sstevel@tonic-gate (void) sprintf( 587*0Sstevel@tonic-gate get_line((char *)&rrep->type - dlc_header, 1), 588*0Sstevel@tonic-gate "Registration header type = %d (%s)", 589*0Sstevel@tonic-gate (int)rrep->type, pt); 590*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&rrep - dlc_header, 1), 591*0Sstevel@tonic-gate "Code = %d %s", (int)rrep->code, pc); 592*0Sstevel@tonic-gate if (ntohs(rrep->lifetime) == 0xffff) { 593*0Sstevel@tonic-gate (void) sprintf(get_line( 594*0Sstevel@tonic-gate (char *)&rrep->lifetime - dlc_header, 1), 595*0Sstevel@tonic-gate "Life time = 0xFFFF (infinity)"); 596*0Sstevel@tonic-gate } else if (ntohs(rrep->lifetime) == 0) { 597*0Sstevel@tonic-gate (void) sprintf(get_line( 598*0Sstevel@tonic-gate (char *)&rrep->lifetime - dlc_header, 1), 599*0Sstevel@tonic-gate ((rrep->code == REPLY_CODE_ACK) || 600*0Sstevel@tonic-gate (rrep->code == 601*0Sstevel@tonic-gate REPLY_CODE_ACK_NO_SIMULTANEOUS))? 602*0Sstevel@tonic-gate "Life time = 0 (de-registeration success)" : 603*0Sstevel@tonic-gate "Life time = 0 (de-registration failed)"); 604*0Sstevel@tonic-gate } else { 605*0Sstevel@tonic-gate (void) sprintf(get_line( 606*0Sstevel@tonic-gate (char *)&rrep->lifetime - dlc_header, 1), 607*0Sstevel@tonic-gate "Life time = %d seconds", 608*0Sstevel@tonic-gate ntohs(rrep->lifetime)); 609*0Sstevel@tonic-gate } 610*0Sstevel@tonic-gate addr_temp.s_addr = rrep->home_addr; 611*0Sstevel@tonic-gate (void) sprintf( 612*0Sstevel@tonic-gate get_line((char *)&rrep->home_addr - dlc_header, 1), 613*0Sstevel@tonic-gate "Home address = %s, %s", 614*0Sstevel@tonic-gate inet_ntoa(addr_temp), 615*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 616*0Sstevel@tonic-gate addr_temp.s_addr = rrep->home_agent_addr; 617*0Sstevel@tonic-gate (void) sprintf(get_line( 618*0Sstevel@tonic-gate (char *)&rrep->home_agent_addr - dlc_header, 1), 619*0Sstevel@tonic-gate "Home Agent address = %s, %s", 620*0Sstevel@tonic-gate inet_ntoa(addr_temp), 621*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 622*0Sstevel@tonic-gate (void) sprintf(get_line( 623*0Sstevel@tonic-gate (char *)&rrep->identification - dlc_header, 1), 624*0Sstevel@tonic-gate "Identification = 0x%x-%x", 625*0Sstevel@tonic-gate ntohl(rrep->identification.high_bits), 626*0Sstevel@tonic-gate ntohl(rrep->identification.low_bits)); 627*0Sstevel@tonic-gate } 628*0Sstevel@tonic-gate fraglen = interpret_extensions(regext_data, regext_size, REG); 629*0Sstevel@tonic-gate } 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate /*ARGSUSED*/ 633*0Sstevel@tonic-gate static void spi_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 634*0Sstevel@tonic-gate uint16_t spi_hi, spi_low; 635*0Sstevel@tonic-gate char auth_prn_str[BUFLEN]; 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate /* SPI */ 638*0Sstevel@tonic-gate GETSPI(p, spi_hi, spi_low); 639*0Sstevel@tonic-gate (void) sprintf(get_line((char *)p - dlc_header, 1), 640*0Sstevel@tonic-gate "Security Parameter Index = 0x%x%x", 641*0Sstevel@tonic-gate ntohs(spi_hi), ntohs(spi_low)); 642*0Sstevel@tonic-gate p += sizeof (spi_hi) + sizeof (spi_low); 643*0Sstevel@tonic-gate this_ext_len -= sizeof (spi_hi) + sizeof (spi_low); 644*0Sstevel@tonic-gate 645*0Sstevel@tonic-gate /* The rest is the authenticator; dump it in hex */ 646*0Sstevel@tonic-gate dumphex(p, 647*0Sstevel@tonic-gate /* don't write past our string buffer ... */ 648*0Sstevel@tonic-gate (this_ext_len*3 > BUFLEN ? BUFLEN : this_ext_len), 649*0Sstevel@tonic-gate auth_prn_str, 650*0Sstevel@tonic-gate "Authenticator = %s"); 651*0Sstevel@tonic-gate } 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate static void key_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 654*0Sstevel@tonic-gate uint16_t alg, spi_hi, spi_low; 655*0Sstevel@tonic-gate char *alg_string; 656*0Sstevel@tonic-gate char *hafa = (type == MN_HA_KEY ? "HA" : "FA"); 657*0Sstevel@tonic-gate char sec_msg[32]; 658*0Sstevel@tonic-gate char auth_prn_str[BUFLEN]; 659*0Sstevel@tonic-gate 660*0Sstevel@tonic-gate /* Algorithm Type */ 661*0Sstevel@tonic-gate (void) memcpy(&alg, p, sizeof (alg)); 662*0Sstevel@tonic-gate alg = ntohs(alg); 663*0Sstevel@tonic-gate switch (alg) { 664*0Sstevel@tonic-gate case KEY_ALG_NONE: 665*0Sstevel@tonic-gate alg_string = "None"; 666*0Sstevel@tonic-gate break; 667*0Sstevel@tonic-gate case SA_MD5_MODE_PREF_SUF: 668*0Sstevel@tonic-gate alg_string = "MD5/prefix+suffix"; 669*0Sstevel@tonic-gate break; 670*0Sstevel@tonic-gate case SA_HMAC_MD5: 671*0Sstevel@tonic-gate alg_string = "HMAC MD5"; 672*0Sstevel@tonic-gate break; 673*0Sstevel@tonic-gate default: 674*0Sstevel@tonic-gate alg_string = "Unknown"; 675*0Sstevel@tonic-gate break; 676*0Sstevel@tonic-gate } 677*0Sstevel@tonic-gate (void) sprintf(get_line((char *)p-dlc_header, 1), 678*0Sstevel@tonic-gate "Algorithm = 0x%x: %s", alg, alg_string); 679*0Sstevel@tonic-gate p += sizeof (alg); 680*0Sstevel@tonic-gate this_ext_len -= sizeof (alg); 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate /* AAA SPI */ 683*0Sstevel@tonic-gate GETSPI(p, spi_hi, spi_low); 684*0Sstevel@tonic-gate (void) sprintf(get_line((char *)p - dlc_header, 1), 685*0Sstevel@tonic-gate "AAA Security Parameter Index = 0x%x%x", 686*0Sstevel@tonic-gate ntohs(spi_hi), ntohs(spi_low)); 687*0Sstevel@tonic-gate p += sizeof (spi_hi) + sizeof (spi_low); 688*0Sstevel@tonic-gate this_ext_len -= sizeof (spi_hi) + sizeof (spi_low); 689*0Sstevel@tonic-gate 690*0Sstevel@tonic-gate /* HA / FA SPI */ 691*0Sstevel@tonic-gate GETSPI(p, spi_hi, spi_low); 692*0Sstevel@tonic-gate (void) sprintf(get_line((char *)p - dlc_header, 1), 693*0Sstevel@tonic-gate "%s Security Parameter Index = 0x%x%x", 694*0Sstevel@tonic-gate hafa, ntohs(spi_hi), ntohs(spi_low)); 695*0Sstevel@tonic-gate p += sizeof (spi_hi) + sizeof (spi_low); 696*0Sstevel@tonic-gate this_ext_len -= sizeof (spi_hi) + sizeof (spi_low); 697*0Sstevel@tonic-gate 698*0Sstevel@tonic-gate /* The rest is the security info; dump it in hex */ 699*0Sstevel@tonic-gate sprintf(sec_msg, "%s Security Info = %%s", hafa); 700*0Sstevel@tonic-gate dumphex(p, 701*0Sstevel@tonic-gate /* don't write past our string buffer ... */ 702*0Sstevel@tonic-gate (this_ext_len*3 > BUFLEN ? BUFLEN : this_ext_len), 703*0Sstevel@tonic-gate auth_prn_str, 704*0Sstevel@tonic-gate sec_msg); 705*0Sstevel@tonic-gate } 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate /*ARGSUSED*/ 708*0Sstevel@tonic-gate static void trav_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 709*0Sstevel@tonic-gate struct in_addr addr_temp; 710*0Sstevel@tonic-gate 711*0Sstevel@tonic-gate /* skip reserved */ 712*0Sstevel@tonic-gate p += 2; 713*0Sstevel@tonic-gate this_ext_len -= 2; 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate /* Mobile-Home Traversal Address */ 716*0Sstevel@tonic-gate (void) memcpy(&(addr_temp.s_addr), p, sizeof (addr_temp.s_addr)); 717*0Sstevel@tonic-gate (void) sprintf(get_line((char *)p-dlc_header, 1), 718*0Sstevel@tonic-gate "Mobile-Home Traversal Address= %s, %s", 719*0Sstevel@tonic-gate inet_ntoa(addr_temp), 720*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 721*0Sstevel@tonic-gate p += sizeof (addr_temp.s_addr); 722*0Sstevel@tonic-gate this_ext_len -= sizeof (addr_temp.s_addr); 723*0Sstevel@tonic-gate 724*0Sstevel@tonic-gate /* Home-Mobile Traversal Address */ 725*0Sstevel@tonic-gate (void) memcpy(&(addr_temp.s_addr), p, sizeof (addr_temp.s_addr)); 726*0Sstevel@tonic-gate (void) sprintf(get_line((char *)p-dlc_header, 1), 727*0Sstevel@tonic-gate "Home-Mobile Traversal Address= %s, %s", 728*0Sstevel@tonic-gate inet_ntoa(addr_temp), 729*0Sstevel@tonic-gate addrtoname(AF_INET, &addr_temp)); 730*0Sstevel@tonic-gate } 731*0Sstevel@tonic-gate 732*0Sstevel@tonic-gate /*ARGSUSED*/ 733*0Sstevel@tonic-gate static void empty_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 734*0Sstevel@tonic-gate /* no payload */ 735*0Sstevel@tonic-gate } 736*0Sstevel@tonic-gate 737*0Sstevel@tonic-gate /*ARGSUSED*/ 738*0Sstevel@tonic-gate static void nai_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 739*0Sstevel@tonic-gate /* payload points to the NAI */ 740*0Sstevel@tonic-gate char *desc = "Network Access Identifier = "; 741*0Sstevel@tonic-gate size_t desclen = strlen(desc) + 1 + this_ext_len; 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate (void) snprintf(get_line((char *)p-dlc_header, 1), 744*0Sstevel@tonic-gate desclen > MAXLINE ? MAXLINE : desclen, 745*0Sstevel@tonic-gate "%s%s", desc, p); 746*0Sstevel@tonic-gate } 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate /*ARGSUSED*/ 749*0Sstevel@tonic-gate static void chall_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 750*0Sstevel@tonic-gate char auth_prn_str[BUFLEN]; 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gate /* payload points to the challenge */ 753*0Sstevel@tonic-gate dumphex(p, 754*0Sstevel@tonic-gate /* don't write past our string buffer ... */ 755*0Sstevel@tonic-gate (this_ext_len*3 > BUFLEN ? BUFLEN / 3 : this_ext_len), 756*0Sstevel@tonic-gate auth_prn_str, 757*0Sstevel@tonic-gate "Challenge = %s"); 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate /*ARGSUSED*/ 761*0Sstevel@tonic-gate static void ma_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 762*0Sstevel@tonic-gate mobagtadvext_t adv_ext[1]; 763*0Sstevel@tonic-gate int i, len; 764*0Sstevel@tonic-gate struct in_addr temp_addr; 765*0Sstevel@tonic-gate 766*0Sstevel@tonic-gate (void) memcpy(adv_ext, p - sizeof (exthdr_t), sizeof (*adv_ext)); 767*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), "Sequence number = %d", 768*0Sstevel@tonic-gate ntohs(adv_ext->sequence_num)); 769*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 770*0Sstevel@tonic-gate "Registration lifetime = %d seconds", 771*0Sstevel@tonic-gate ntohs(adv_ext->reg_lifetime)); 772*0Sstevel@tonic-gate if (adv_ext->reg_bit) { 773*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 774*0Sstevel@tonic-gate "1... .... = registration required " 775*0Sstevel@tonic-gate "through FA"); 776*0Sstevel@tonic-gate } else { 777*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 778*0Sstevel@tonic-gate "0... .... = registration not required " 779*0Sstevel@tonic-gate "through FA"); 780*0Sstevel@tonic-gate } 781*0Sstevel@tonic-gate if (adv_ext->busy_bit) { 782*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), ".1.. .... = FA busy"); 783*0Sstevel@tonic-gate } else { 784*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), ".0.. .... = FA not busy"); 785*0Sstevel@tonic-gate } 786*0Sstevel@tonic-gate if (adv_ext->ha_bit) { 787*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), "..1. .... = node is HA"); 788*0Sstevel@tonic-gate } else { 789*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), "..0. .... = node not HA"); 790*0Sstevel@tonic-gate } 791*0Sstevel@tonic-gate if (adv_ext->fa_bit) { 792*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), "...1 .... = node is FA "); 793*0Sstevel@tonic-gate } else { 794*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), "...0 .... = node not FA "); 795*0Sstevel@tonic-gate } 796*0Sstevel@tonic-gate if (adv_ext->minencap_bit) { 797*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), ".... 1... = minimal encapsulation " 798*0Sstevel@tonic-gate "supported"); 799*0Sstevel@tonic-gate } else { 800*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 801*0Sstevel@tonic-gate ".... 0... = no minimal encapsulation"); 802*0Sstevel@tonic-gate } 803*0Sstevel@tonic-gate if (adv_ext->greencap_bit) { 804*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 805*0Sstevel@tonic-gate ".... .1.. = GRE encapsulation supported"); 806*0Sstevel@tonic-gate } else { 807*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 808*0Sstevel@tonic-gate ".... .0.. = no GRE encapsulation"); 809*0Sstevel@tonic-gate } 810*0Sstevel@tonic-gate if (adv_ext->vanjacob_hdr_comp_bit) { 811*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 812*0Sstevel@tonic-gate ".... ..1. = VJ header compression"); 813*0Sstevel@tonic-gate } else { 814*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 815*0Sstevel@tonic-gate ".... ..0. = no VJ header compression"); 816*0Sstevel@tonic-gate } 817*0Sstevel@tonic-gate if (adv_ext->reverse_tunnel_bit) { 818*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 819*0Sstevel@tonic-gate ".... ...1 = reverse tunneling supported"); 820*0Sstevel@tonic-gate } else { 821*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 822*0Sstevel@tonic-gate ".... ...0 = no reverse tunneling"); 823*0Sstevel@tonic-gate } 824*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 825*0Sstevel@tonic-gate "Reserved Byte = 0x%x", adv_ext->reserved); 826*0Sstevel@tonic-gate 827*0Sstevel@tonic-gate /* Parse out COA's */ 828*0Sstevel@tonic-gate p += sizeof (*adv_ext); 829*0Sstevel@tonic-gate len = this_ext_len + sizeof (exthdr_t); 830*0Sstevel@tonic-gate /* this_ext_len is unsigned, and here we need a signed number */ 831*0Sstevel@tonic-gate len -= sizeof (*adv_ext); 832*0Sstevel@tonic-gate 833*0Sstevel@tonic-gate for (i = 0; len >= sizeof (temp_addr.s_addr); i++) { 834*0Sstevel@tonic-gate memcpy(&(temp_addr.s_addr), p - sizeof (exthdr_t), 835*0Sstevel@tonic-gate sizeof (temp_addr.s_addr)); 836*0Sstevel@tonic-gate 837*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 838*0Sstevel@tonic-gate "Care of address-%d = %s, %s", i, 839*0Sstevel@tonic-gate inet_ntoa(temp_addr), 840*0Sstevel@tonic-gate addrtoname(AF_INET, &temp_addr)); 841*0Sstevel@tonic-gate 842*0Sstevel@tonic-gate p += sizeof (temp_addr); 843*0Sstevel@tonic-gate len -= sizeof (temp_addr); 844*0Sstevel@tonic-gate } 845*0Sstevel@tonic-gate } 846*0Sstevel@tonic-gate 847*0Sstevel@tonic-gate /*ARGSUSED*/ 848*0Sstevel@tonic-gate static void prefix_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 849*0Sstevel@tonic-gate int i; 850*0Sstevel@tonic-gate 851*0Sstevel@tonic-gate for (i = 0; i < this_ext_len; i++) { 852*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 853*0Sstevel@tonic-gate "Prefix length of router address[%d] " 854*0Sstevel@tonic-gate "= %d bits", 855*0Sstevel@tonic-gate i, p[i]); 856*0Sstevel@tonic-gate } 857*0Sstevel@tonic-gate } 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate /*ARGSUSED*/ 860*0Sstevel@tonic-gate static void unk_ext(uint8_t type, uint8_t this_ext_len, uchar_t *p) { 861*0Sstevel@tonic-gate char auth_prn_str[BUFLEN]; 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate /* Unknown extension; just dump the rest of the payload */ 864*0Sstevel@tonic-gate dumphex(p, 865*0Sstevel@tonic-gate /* don't write past our string buffer ... */ 866*0Sstevel@tonic-gate (this_ext_len*3 > BUFLEN ? BUFLEN : this_ext_len), 867*0Sstevel@tonic-gate auth_prn_str, 868*0Sstevel@tonic-gate "Payload = %s"); 869*0Sstevel@tonic-gate } 870