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