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