GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-ike.c Lines: 0 386 0.0 %
Date: 2017-11-07 Branches: 0 291 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-ike.c,v 1.37 2015/01/16 06:40:21 deraadt Exp $	*/
2
3
/*
4
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
5
 *	The Regents of the University of California.  All rights reserved.
6
 * Copyright (c) 2001 Håkan Olsson.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that: (1) source code distributions
10
 * retain the above copyright notice and this paragraph in its entirety, (2)
11
 * distributions including binary code include the above copyright notice and
12
 * this paragraph in its entirety in the documentation or other materials
13
 * provided with the distribution, and (3) all advertising materials mentioning
14
 * features or use of this software display the following acknowledgement:
15
 * ``This product includes software developed by the University of California,
16
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
17
 * the University nor the names of its contributors may be used to endorse
18
 * or promote products derived from this software without specific prior
19
 * written permission.
20
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
21
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
22
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23
 *
24
 * Format and print ike (isakmp) packets.
25
 *	By Tero Kivinen <kivinen@ssh.fi>, Tero Mononen <tmo@ssh.fi>,
26
 *         Tatu Ylonen <ylo@ssh.fi> and Timo J. Rinne <tri@ssh.fi>
27
 *         in co-operation with SSH Communications Security, Espoo, Finland
28
 */
29
30
#include <sys/time.h>
31
#include <sys/socket.h>
32
33
struct mbuf;
34
struct rtentry;
35
#include <net/if.h>
36
#include <netinet/in.h>
37
#include <arpa/inet.h>
38
39
#include <ctype.h>
40
#include <stdio.h>
41
#include <string.h>
42
43
#include "interface.h"
44
#include "addrtoname.h"
45
#include "ike.h"
46
47
struct isakmp_header {
48
	u_int8_t	init_cookie[8];
49
	u_int8_t	resp_cookie[8];
50
	u_int8_t	next_payload;
51
	u_int8_t	version;
52
	u_int8_t	exgtype;
53
	u_int8_t	flags;
54
	u_int8_t	msgid[4];
55
	u_int32_t	length;
56
	u_int8_t	payloads[0];
57
};
58
59
struct sa_payload {
60
	u_int8_t	next_payload;
61
	u_int8_t	reserved;
62
	u_int16_t	payload_length;
63
	u_int32_t	doi;
64
	u_int8_t	situation[0];
65
};
66
67
struct proposal_payload {
68
	u_int8_t	next_payload;
69
	u_int8_t	reserved;
70
	u_int16_t	payload_length;
71
	u_int8_t	nprop;
72
	u_int8_t	proto;
73
	u_int8_t	spi_size;
74
	u_int8_t	nspis;
75
	u_int8_t	spi[0];
76
};
77
78
struct transform_payload {
79
	u_int8_t	next_payload;
80
	u_int8_t	reserved;
81
	u_int16_t	payload_length;
82
	u_int8_t	ntrans;
83
	u_int8_t	transform;
84
	u_int16_t	reserved2;
85
	u_int8_t	attribute[0];
86
};
87
88
struct ke_payload {
89
	u_int8_t	next_payload;
90
	u_int8_t	reserved;
91
	u_int16_t	payload_length;
92
	u_int8_t	data[0];
93
};
94
95
struct id_payload {
96
	u_int8_t	next_payload;
97
	u_int8_t	reserved;
98
	u_int16_t	payload_length;
99
	u_int8_t	type;
100
	u_int8_t	id_data[3];
101
	u_int8_t	data[0];
102
};
103
104
struct notification_payload {
105
	u_int8_t	next_payload;
106
	u_int8_t	reserved;
107
	u_int16_t	payload_length;
108
	u_int32_t	doi;
109
	u_int8_t	protocol_id;
110
  	u_int8_t	spi_size;
111
  	u_int16_t	type;
112
	u_int8_t	data[0];
113
};
114
115
struct delete_payload {
116
	u_int8_t	next_payload;
117
	u_int8_t	reserved;
118
	u_int16_t	payload_length;
119
	u_int32_t	doi;
120
	u_int8_t	proto;
121
	u_int8_t	spi_size;
122
	u_int16_t	nspis;
123
	u_int8_t	spi[0];
124
};
125
126
struct vendor_payload {
127
	u_int8_t	next_payload;
128
	u_int8_t	reserved;
129
	u_int16_t	payload_length;
130
	u_int8_t	vid[0];
131
};
132
133
struct attribute_payload {
134
	u_int8_t	next_payload;
135
	u_int8_t	reserved;
136
	u_int16_t	payload_length;
137
	u_int8_t	type;
138
	u_int8_t	reserved2;
139
	u_int16_t	id;
140
};
141
142
static void ike_pl_print(u_int8_t, u_int8_t *, u_int8_t);
143
144
int ike_tab_level = 0;
145
u_int8_t xform_proto;
146
147
static const char *ike[] = IKE_PROTO_INITIALIZER;
148
149
#define SMALL_TABS 4
150
#define SPACES "                                                   "
151
const char *
152
ike_tab_offset(void)
153
{
154
	const char *p, *endline;
155
	static const char line[] = SPACES;
156
157
	endline = line + sizeof line - 1;
158
	p = endline - SMALL_TABS * (ike_tab_level);
159
160
	return (p > line ? p : line);
161
}
162
163
static char *
164
ike_get_cookie (u_int8_t *ic, u_int8_t *rc)
165
{
166
	static char cookie_jar[35];
167
	int i;
168
169
	for (i = 0; i < 8; i++)
170
		snprintf(cookie_jar + i*2, sizeof(cookie_jar) - i*2,
171
		    "%02x", *(ic + i));
172
	strlcat(cookie_jar, "->", sizeof(cookie_jar));
173
	for (i = 0; i < 8; i++)
174
		snprintf(cookie_jar + 18 + i*2, sizeof(cookie_jar) - 18 - i*2,
175
		    "%02x", *(rc + i));
176
	return cookie_jar;
177
}
178
179
/*
180
 * Print isakmp requests
181
 */
182
void
183
ike_print (const u_int8_t *cp, u_int length)
184
{
185
	struct isakmp_header *ih;
186
	const u_int8_t *ep;
187
	u_int8_t *payload, next_payload;
188
	int encrypted;
189
	static const char *exgtypes[] = IKE_EXCHANGE_TYPES_INITIALIZER;
190
191
	encrypted = 0;
192
193
#ifdef TCHECK
194
#undef TCHECK
195
#endif
196
#define TCHECK(var, l) if ((u_int8_t *)&(var) > ep - l) goto trunc
197
198
	ih = (struct isakmp_header *)cp;
199
200
	if (length < sizeof (struct isakmp_header))
201
		goto trunc;
202
203
	/* 'ep' points to the end of avaible data. */
204
	ep = snapend;
205
206
	printf(" isakmp");
207
208
	printf(" v%d.%d", ih->version >> 4, ih->version & 0xf);
209
210
	printf(" exchange ");
211
	if (ih->exgtype < (sizeof exgtypes/sizeof exgtypes[0]))
212
		printf("%s", exgtypes[ih->exgtype]);
213
	else
214
		printf("%d (unknown)", ih->exgtype);
215
216
	if (ih->flags & FLAGS_ENCRYPTION) {
217
		printf(" encrypted");
218
		encrypted = 1;
219
	}
220
221
	if (ih->flags & FLAGS_COMMIT) {
222
		printf(" commit");
223
	}
224
225
	printf("\n\tcookie: %s", ike_get_cookie (ih->init_cookie,
226
						 ih->resp_cookie));
227
228
	TCHECK(ih->msgid, sizeof(ih->msgid));
229
	printf(" msgid: %02x%02x%02x%02x", ih->msgid[0], ih->msgid[1],
230
	    ih->msgid[2], ih->msgid[3]);
231
232
	TCHECK(ih->length, sizeof(ih->length));
233
	printf(" len: %d", ntohl(ih->length));
234
235
	if (ih->version > IKE_VERSION_2) {
236
		printf(" new version");
237
		return;
238
	}
239
240
	payload = ih->payloads;
241
	next_payload = ih->next_payload;
242
243
	/* if encrypted, then open special file for encryption keys */
244
	if (encrypted) {
245
		/* decrypt XXX */
246
		return;
247
	}
248
249
	/* if verbose, print payload data */
250
	if (vflag)
251
		ike_pl_print(next_payload, payload, ISAKMP_DOI);
252
253
	return;
254
255
trunc:
256
	fputs(" [|isakmp]", stdout);
257
}
258
259
void
260
ike_pl_sa_print (u_int8_t *buf, int len)
261
{
262
	struct sa_payload *sp = (struct sa_payload *)buf;
263
	u_int32_t sit_ipsec, doi;
264
265
	if (len < sizeof(struct sa_payload)) {
266
		printf(" [|payload]");
267
		return;
268
	}
269
270
	doi = ntohl(sp->doi);
271
	printf(" DOI: %d", doi);
272
273
	if (doi == IPSEC_DOI) {
274
		if ((sp->situation + sizeof(u_int32_t)) > (buf + len)) {
275
			printf(" [|payload]");
276
			return;
277
		}
278
		printf("(IPSEC) situation: ");
279
		sit_ipsec = ntohl(*(u_int32_t *)sp->situation);
280
		if (sit_ipsec & IKE_SITUATION_IDENTITY_ONLY)
281
			printf("IDENTITY_ONLY ");
282
		if (sit_ipsec & IKE_SITUATION_SECRECY)
283
			printf("SECRECY ");
284
		if (sit_ipsec & IKE_SITUATION_INTEGRITY)
285
			printf("INTEGRITY ");
286
		if ((sit_ipsec & IKE_SITUATION_MASK) == 0)
287
			printf("0x%x (unknown)", sit_ipsec);
288
		ike_pl_print (PAYLOAD_PROPOSAL, buf +
289
		    sizeof(struct sa_payload) + sizeof(u_int32_t), IPSEC_DOI);
290
	} else
291
		printf(" situation: (unknown)");
292
}
293
294
int
295
ike_attribute_print (u_int8_t *buf, u_int8_t doi, int maxlen)
296
{
297
	static char *attrs[] = IKE_ATTR_INITIALIZER;
298
	static char *attr_enc[] = IKE_ATTR_ENCRYPT_INITIALIZER;
299
	static char *attr_hash[] = IKE_ATTR_HASH_INITIALIZER;
300
	static char *attr_auth[] = IKE_ATTR_AUTH_INITIALIZER;
301
	static char *attr_gdesc[] = IKE_ATTR_GROUP_DESC_INITIALIZER;
302
	static char *attr_gtype[] = IKE_ATTR_GROUP_INITIALIZER;
303
	static char *attr_ltype[] = IKE_ATTR_SA_DURATION_INITIALIZER;
304
	static char *ipsec_attrs[] = IPSEC_ATTR_INITIALIZER;
305
	static char *ipsec_attr_auth[] = IPSEC_ATTR_AUTH_INITIALIZER;
306
	static char *ipsec_attr_ltype[] = IPSEC_ATTR_DURATION_INITIALIZER;
307
308
	u_int8_t af   = buf[0] >> 7;
309
	u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1];
310
	u_int16_t len  = buf[2] << 8 | buf[3], val;
311
312
	if (doi == ISAKMP_DOI)
313
		printf("\n\t%sattribute %s = ", ike_tab_offset(),
314
		    (type < sizeof attrs / sizeof attrs[0] ?
315
		    attrs[type] : "<unknown>"));
316
	else
317
		printf("\n\t%sattribute %s = ", ike_tab_offset(),
318
		    (type < (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ?
319
		    ipsec_attrs[type] : "<unknown>"));
320
321
	if ((af == 1 && maxlen < 4) || (af == 0 && maxlen < (len + 4))) {
322
		printf("\n\t%s[|attr]", ike_tab_offset());
323
		return maxlen;
324
	}
325
326
	if (af == 0) {
327
		/* AF=0; print the variable length attribute value */
328
		for (val = 0; val < len; val++)
329
			printf("%02x", *(buf + 4 + val));
330
		return len + 4;
331
	}
332
333
	val = len;	/* For AF=1, this field is the "VALUE" */
334
	len = 4; 	/* and with AF=1, length is always 4 */
335
336
#define CASE_PRINT(TYPE, var) \
337
	case TYPE : \
338
		if (val < sizeof var / sizeof var [0]) \
339
			printf("%s", var [val]); \
340
		else \
341
			printf("%d (unknown)", val); \
342
		break;
343
344
	if (doi == ISAKMP_DOI)
345
		switch(type) {
346
			CASE_PRINT(IKE_ATTR_ENCRYPTION_ALGORITHM, attr_enc);
347
			CASE_PRINT(IKE_ATTR_HASH_ALGORITHM, attr_hash);
348
			CASE_PRINT(IKE_ATTR_AUTHENTICATION_METHOD, attr_auth);
349
			CASE_PRINT(IKE_ATTR_GROUP_DESC, attr_gdesc);
350
			CASE_PRINT(IKE_ATTR_GROUP_TYPE, attr_gtype);
351
			CASE_PRINT(IKE_ATTR_LIFE_TYPE, attr_ltype);
352
		default:
353
			printf("%d", val);
354
		}
355
	else
356
		switch(type) {
357
			CASE_PRINT(IPSEC_ATTR_SA_LIFE_TYPE, ipsec_attr_ltype);
358
			CASE_PRINT(IPSEC_ATTR_AUTHENTICATION_ALGORITHM,
359
			    ipsec_attr_auth);
360
			case IPSEC_ATTR_ENCAPSULATION_MODE:
361
				printf("%s", tok2str(ipsec_attr_encap,
362
				    "%d", val));
363
				break;
364
		default:
365
			printf("%d", val);
366
		}
367
368
#undef CASE_PRINT
369
	return len;
370
}
371
372
void
373
ike_pl_transform_print (u_int8_t *buf, int len, u_int8_t doi)
374
{
375
	struct transform_payload *tp = (struct transform_payload *)buf;
376
	const char *ah[] = IPSEC_AH_INITIALIZER;
377
	const char *esp[] = IPSEC_ESP_INITIALIZER;
378
	const char *ipcomp[] = IPCOMP_INITIALIZER;
379
	u_int8_t *attr = tp->attribute;
380
381
	if (len < sizeof(struct transform_payload)) {
382
		printf(" [|payload]");
383
		return;
384
	}
385
386
	printf("\n\t%stransform: %u ID: ", ike_tab_offset(), tp->ntrans);
387
388
	switch (doi) {
389
	case ISAKMP_DOI:
390
		if (tp->transform < (sizeof ike / sizeof ike[0]))
391
			printf("%s", ike[tp->transform]);
392
		else
393
			printf("%d(unknown)", tp->transform);
394
		break;
395
396
	default: /* IPSEC_DOI */
397
		switch (xform_proto) { /* from ike_proposal_print */
398
		case PROTO_IPSEC_AH:
399
			if (tp->transform < (sizeof ah / sizeof ah[0]))
400
				printf("%s", ah[tp->transform]);
401
			else
402
				printf("%d(unknown)", tp->transform);
403
			break;
404
		case PROTO_IPSEC_ESP:
405
			if (tp->transform < (sizeof esp / sizeof esp[0]))
406
				printf("%s", esp[tp->transform]);
407
			else
408
				printf("%d(unknown)", tp->transform);
409
			break;
410
		case PROTO_IPCOMP:
411
			if (tp->transform < (sizeof ipcomp / sizeof ipcomp[0]))
412
				printf("%s", ipcomp[tp->transform]);
413
			else
414
				printf("%d(unknown)", tp->transform);
415
			break;
416
		default:
417
			printf("%d(unknown)", tp->transform);
418
		}
419
		break;
420
	}
421
422
	ike_tab_level++;
423
	while ((int)(attr - buf) < len) /* Skip last 'NONE' attr */
424
		attr += ike_attribute_print(attr, doi, len - (attr - buf));
425
	ike_tab_level--;
426
}
427
428
void
429
ike_pl_proposal_print (u_int8_t *buf, int len, u_int8_t doi)
430
{
431
	struct proposal_payload *pp = (struct proposal_payload *)buf;
432
	int i;
433
434
	if (len < sizeof(struct proposal_payload)) {
435
		printf(" [|payload]");
436
		return;
437
	}
438
439
	printf(" proposal: %d proto: %s spisz: %d xforms: %d",
440
	    pp->nprop, (pp->proto < (sizeof ike / sizeof ike[0]) ?
441
	    ike[pp->proto] : "(unknown)"), pp->spi_size, pp->nspis);
442
443
	xform_proto = pp->proto;
444
445
	if (pp->spi_size) {
446
		if ((pp->spi + pp->spi_size) > (buf + len)) {
447
			printf(" [|payload]");
448
			return;
449
		}
450
		if (pp->proto == PROTO_IPCOMP)
451
			printf(" CPI: 0x");
452
		else
453
			printf(" SPI: 0x");
454
		for (i = 0; i < pp->spi_size; i++)
455
			printf("%02x", pp->spi[i]);
456
	}
457
458
	/* Reset to sane value. */
459
	if (pp->proto == PROTO_ISAKMP)
460
		doi = ISAKMP_DOI;
461
	else
462
		doi = IPSEC_DOI;
463
464
	if (pp->nspis > 0)
465
		ike_pl_print(PAYLOAD_TRANSFORM, pp->spi + pp->spi_size, doi);
466
}
467
468
void
469
ike_pl_ke_print (u_int8_t *buf, int len, u_int8_t doi)
470
{
471
	if (len < sizeof(struct ke_payload)) {
472
		printf(" [|payload]");
473
		return;
474
	}
475
476
	if (doi != IPSEC_DOI)
477
		return;
478
479
	/* XXX ... */
480
}
481
482
void
483
ipsec_id_print (u_int8_t *buf, int len, u_int8_t doi)
484
{
485
	struct id_payload *ip = (struct id_payload *)buf;
486
	static const char *idtypes[] = IPSEC_ID_TYPE_INITIALIZER;
487
	char ntop_buf[INET6_ADDRSTRLEN];
488
	struct in_addr in;
489
	u_int8_t *p;
490
491
	if (len < sizeof (struct id_payload)) {
492
		printf(" [|payload]");
493
		return;
494
	}
495
496
	if (doi != ISAKMP_DOI)
497
		return;
498
499
	/* Don't print proto+port unless actually used */
500
	if (ip->id_data[0] | ip->id_data[1] | ip->id_data[2])
501
		printf(" proto: %d port: %d", ip->id_data[0],
502
		    (ip->id_data[1] << 8) + ip->id_data[2]);
503
504
	printf(" type: %s = ", ip->type < (sizeof idtypes/sizeof idtypes[0]) ?
505
	    idtypes[ip->type] : "<unknown>");
506
507
	switch (ip->type) {
508
	case IPSEC_ID_IPV4_ADDR:
509
		if ((ip->data + sizeof in) > (buf + len)) {
510
			printf(" [|payload]");
511
			return;
512
		}
513
		memcpy (&in.s_addr, ip->data, sizeof in);
514
		printf("%s", inet_ntoa (in));
515
		break;
516
517
	case IPSEC_ID_IPV4_ADDR_SUBNET:
518
	case IPSEC_ID_IPV4_ADDR_RANGE:
519
		if ((ip->data + 2 * (sizeof in)) > (buf + len)) {
520
			printf(" [|payload]");
521
			return;
522
		}
523
		memcpy (&in.s_addr, ip->data, sizeof in);
524
		printf("%s%s", inet_ntoa (in),
525
		    ip->type == IPSEC_ID_IPV4_ADDR_SUBNET ? "/" : "-");
526
		memcpy (&in.s_addr, ip->data + sizeof in, sizeof in);
527
		printf("%s", inet_ntoa (in));
528
		break;
529
530
	case IPSEC_ID_IPV6_ADDR:
531
		if ((ip->data + sizeof ntop_buf) > (buf + len)) {
532
			printf(" [|payload]");
533
			return;
534
		}
535
		printf("%s", inet_ntop (AF_INET6, ip->data, ntop_buf,
536
		    sizeof ntop_buf));
537
		break;
538
539
	case IPSEC_ID_IPV6_ADDR_SUBNET:
540
	case IPSEC_ID_IPV6_ADDR_RANGE:
541
		if ((ip->data + 2 * sizeof ntop_buf) > (buf + len)) {
542
			printf(" [|payload]");
543
			return;
544
		}
545
		printf("%s%s", inet_ntop (AF_INET6, ip->data, ntop_buf,
546
		    sizeof ntop_buf),
547
		    ip->type == IPSEC_ID_IPV6_ADDR_SUBNET ? "/" : "-");
548
		printf("%s", inet_ntop (AF_INET6, ip->data + sizeof ntop_buf,
549
		    ntop_buf, sizeof ntop_buf));
550
		break;
551
552
	case IPSEC_ID_FQDN:
553
	case IPSEC_ID_USER_FQDN:
554
		printf("\"");
555
		for (p = ip->data; (int)(p - buf) < len; p++)
556
			printf("%c",(isprint(*p) ? *p : '.'));
557
		printf("\"");
558
		break;
559
560
	case IPSEC_ID_DER_ASN1_DN:
561
	case IPSEC_ID_DER_ASN1_GN:
562
	case IPSEC_ID_KEY_ID:
563
	default:
564
		printf("\"(not shown)\"");
565
		break;
566
	}
567
}
568
569
void
570
ike_pl_delete_print (u_int8_t *buf, int len)
571
{
572
  	struct delete_payload *dp = (struct delete_payload *)buf;
573
	u_int32_t doi;
574
	u_int16_t s, nspis;
575
	u_int8_t *data;
576
577
	if (len < sizeof (struct delete_payload)) {
578
		printf(" [|payload]");
579
		return;
580
	}
581
582
	doi   = ntohl(dp->doi);
583
	nspis = ntohs(dp->nspis);
584
585
	if (doi != ISAKMP_DOI && doi != IPSEC_DOI) {
586
		printf(" (unknown DOI)");
587
		return;
588
	}
589
590
	printf(" DOI: %u(%s) proto: %s nspis: %u", doi,
591
	    doi == ISAKMP_DOI ? "ISAKMP" : "IPSEC",
592
	    dp->proto < (sizeof ike / sizeof ike[0]) ? ike[dp->proto] :
593
	    "(unknown)", nspis);
594
595
	if ((dp->spi + nspis * dp->spi_size) > (buf + len)) {
596
		printf(" [|payload]");
597
		return;
598
	}
599
600
	for (s = 0; s < nspis; s++) {
601
		data = dp->spi + s * dp->spi_size;
602
		if (dp->spi_size == 16)
603
			printf("\n\t%scookie: %s", ike_tab_offset(),
604
			    ike_get_cookie(&data[0], &data[8]));
605
		else
606
			printf("\n\t%sSPI: 0x%08x", ike_tab_offset(),
607
			    data[0]<<24 | data[1]<<16 | data[2]<<8 | data[3]);
608
	}
609
}
610
611
void
612
ike_pl_notification_print (u_int8_t *buf, int len)
613
{
614
  	static const char *nftypes[] = IKE_NOTIFY_TYPES_INITIALIZER;
615
  	struct notification_payload *np = (struct notification_payload *)buf;
616
	u_int32_t *replay, *seq;
617
	u_int32_t doi;
618
	u_int16_t type;
619
	u_int8_t *attr;
620
621
	if (len < sizeof (struct notification_payload)) {
622
		printf(" [|payload]");
623
		return;
624
	}
625
626
	doi  = ntohl (np->doi);
627
	type = ntohs (np->type);
628
629
	if (doi != ISAKMP_DOI && doi != IPSEC_DOI) {
630
		printf(" (unknown DOI)");
631
		return;
632
	}
633
634
	printf("\n\t%snotification: ", ike_tab_offset());
635
636
	if (type > 0 && type < (sizeof nftypes / sizeof nftypes[0])) {
637
		printf("%s", nftypes[type]);
638
		return;
639
	}
640
	switch (type) {
641
642
	case NOTIFY_IPSEC_RESPONDER_LIFETIME:
643
		printf("RESPONDER LIFETIME ");
644
		if (np->spi_size == 16)
645
			printf("(%s)", ike_get_cookie (&np->data[0],
646
			    &np->data[8]));
647
		else
648
			printf("SPI: 0x%08x", np->data[0]<<24 |
649
			    np->data[1]<<16 | np->data[2]<<8 | np->data[3]);
650
		attr = &np->data[np->spi_size];
651
		ike_tab_level++;
652
		while ((int)(attr - buf) < len - 4)  /* Skip last 'NONE' attr */
653
			attr += ike_attribute_print(attr, IPSEC_DOI,
654
			    len - (attr-buf));
655
		ike_tab_level--;
656
		break;
657
658
	case NOTIFY_IPSEC_REPLAY_STATUS:
659
		replay = (u_int32_t *)&np->data[np->spi_size];
660
		printf("REPLAY STATUS [%sabled] ", *replay ? "en" : "dis");
661
		if (np->spi_size == 16)
662
			printf("(%s)", ike_get_cookie (&np->data[0],
663
			    &np->data[8]));
664
		else
665
			printf("SPI: 0x%08x", np->data[0]<<24 |
666
			    np->data[1]<<16 | np->data[2]<<8 | np->data[3]);
667
		break;
668
669
	case NOTIFY_IPSEC_INITIAL_CONTACT:
670
		printf("INITIAL CONTACT (%s)", ike_get_cookie (&np->data[0],
671
		    &np->data[8]));
672
		break;
673
674
	case NOTIFY_STATUS_DPD_R_U_THERE:
675
	case NOTIFY_STATUS_DPD_R_U_THERE_ACK:
676
		printf("STATUS_DPD_R_U_THERE%s ",
677
		    type == NOTIFY_STATUS_DPD_R_U_THERE ? "" : "_ACK");
678
		if (np->spi_size != 16 ||
679
		    len < sizeof(struct notification_payload) +
680
		    sizeof(u_int32_t))
681
			printf("[bad notify]");
682
		else {
683
			seq = (u_int32_t *)&np->data[np->spi_size];
684
			printf("seq %u", ntohl(*seq));
685
		}
686
		break;
687
688
689
	default:
690
	  	printf("%d (unknown)", type);
691
		break;
692
	}
693
}
694
695
void
696
ike_pl_vendor_print (u_int8_t *buf, int len, u_int8_t doi)
697
{
698
	struct vendor_payload *vp = (struct vendor_payload *)buf;
699
	u_int8_t *p;
700
	int i;
701
702
	if (len < sizeof(struct vendor_payload)) {
703
		printf(" [|payload]");
704
		return;
705
	}
706
707
	for (i = 0; i < sizeof vendor_ids / sizeof vendor_ids[0]; i ++)
708
		if (memcmp(vp->vid, vendor_ids[i].vid,
709
		    vendor_ids[i].len) == 0) {
710
			printf (" (supports %s)", vendor_ids[i].name);
711
			return;
712
		}
713
714
	if (doi != IPSEC_DOI)
715
		return;
716
717
	printf(" \"");
718
	for (p = vp->vid; (int)(p - buf) < len; p++)
719
		printf("%c", (isprint(*p) ? *p : '.'));
720
	printf("\"");
721
}
722
723
/* IKE mode-config. */
724
int
725
ike_cfg_attribute_print (u_int8_t *buf, int attr_type, int maxlen)
726
{
727
	static char *attrs[] = IKE_CFG_ATTRIBUTE_INITIALIZER;
728
	char ntop_buf[INET6_ADDRSTRLEN];
729
	struct in_addr in;
730
731
	u_int8_t af = buf[0] >> 7;
732
	u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1];
733
	u_int16_t len = af ? 2 : buf[2] << 8 | buf[3], p;
734
	u_int8_t *val = af ? buf + 2 : buf + 4;
735
736
	printf("\n\t%sattribute %s = ", ike_tab_offset(),
737
	    type < (sizeof attrs / sizeof attrs[0]) ? attrs[type] :
738
	    "<unknown>");
739
740
	if ((af == 1 && maxlen < 4) ||
741
	    (af == 0 && maxlen < (len + 4))) {
742
		printf("\n\t%s[|attr]", ike_tab_offset());
743
		return maxlen;
744
	}
745
746
	/* XXX The 2nd term is for bug compatibility with PGPnet.  */
747
	if (len == 0 || (af && !val[0] && !val[1])) {
748
		printf("<none>");
749
		return 4;
750
	}
751
752
	/* XXX Generally lengths are not checked well below.  */
753
	switch (type) {
754
	case IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS:
755
	case IKE_CFG_ATTR_INTERNAL_IP4_NETMASK:
756
	case IKE_CFG_ATTR_INTERNAL_IP4_DNS:
757
	case IKE_CFG_ATTR_INTERNAL_IP4_NBNS:
758
	case IKE_CFG_ATTR_INTERNAL_IP4_DHCP:
759
		memcpy (&in.s_addr, val, sizeof in);
760
		printf("%s", inet_ntoa (in));
761
		break;
762
763
	case IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS:
764
	case IKE_CFG_ATTR_INTERNAL_IP6_NETMASK:
765
	case IKE_CFG_ATTR_INTERNAL_IP6_DNS:
766
	case IKE_CFG_ATTR_INTERNAL_IP6_NBNS:
767
	case IKE_CFG_ATTR_INTERNAL_IP6_DHCP:
768
		printf("%s", inet_ntop (AF_INET6, val, ntop_buf,
769
		    sizeof ntop_buf));
770
		break;
771
772
	case IKE_CFG_ATTR_INTERNAL_IP4_SUBNET:
773
		memcpy(&in.s_addr, val, sizeof in);
774
		printf("%s/", inet_ntoa (in));
775
		memcpy(&in.s_addr, val + sizeof in, sizeof in);
776
		printf("%s", inet_ntoa (in));
777
		break;
778
779
	case IKE_CFG_ATTR_INTERNAL_IP6_SUBNET:
780
		printf("%s/%u", inet_ntop (AF_INET6, val, ntop_buf,
781
		    sizeof ntop_buf), val[16]);
782
		break;
783
784
	case IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY:
785
		printf("%u seconds",
786
		    val[0] << 24 | val[1] << 16 | val[2] << 8 | val[3]);
787
		break;
788
789
	case IKE_CFG_ATTR_APPLICATION_VERSION:
790
		for (p = 0; p < len; p++)
791
			printf("%c", isprint(val[p]) ? val[p] : '.');
792
		break;
793
794
	case IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES:
795
		printf("<%d attributes>", len / 2);
796
		ike_tab_level++;
797
		for (p = 0; p < len; p += 2) {
798
			type = (val[p] << 8 | val[p + 1]) & 0x7fff;
799
			printf("\n\t%s%s", ike_tab_offset(),
800
			    type < (sizeof attrs/sizeof attrs[0]) ?
801
			    attrs[type] : "<unknown>");
802
		}
803
		ike_tab_level--;
804
		break;
805
806
	default:
807
		break;
808
	}
809
	return af ? 4 : len + 4;
810
}
811
812
void
813
ike_pl_attribute_print (u_int8_t *buf, int len)
814
{
815
	struct attribute_payload *ap = (struct attribute_payload *)buf;
816
	static const char *pl_attr[] = IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER;
817
	u_int8_t *attr = buf + sizeof(struct attribute_payload);
818
819
	if (len < sizeof(struct attribute_payload)) {
820
		printf(" [|payload]");
821
		return;
822
	}
823
824
	printf(" type: %s Id: %d",
825
	    ap->type < (sizeof pl_attr/sizeof pl_attr[0]) ? pl_attr[ap->type] :
826
	    "<unknown>", ap->id);
827
828
	while ((int)(attr - buf) < len)
829
		attr += ike_cfg_attribute_print(attr, ap->type,
830
		    len - (attr - buf));
831
}
832
833
void
834
ike_pl_print (u_int8_t type, u_int8_t *buf, u_int8_t doi)
835
{
836
	static const char *pltypes[] = IKE_PAYLOAD_TYPES_INITIALIZER;
837
	static const char *plprivtypes[] =
838
	    IKE_PRIVATE_PAYLOAD_TYPES_INITIALIZER;
839
	static const char *plv2types[] = IKEV2_PAYLOAD_TYPES_INITIALIZER;
840
	u_int8_t next_type;
841
	u_int16_t this_len;
842
843
	if (&buf[4] > snapend) {
844
		goto pltrunc;
845
	}
846
847
	next_type = buf[0];
848
	this_len = buf[2]<<8 | buf[3];
849
850
	if (type < PAYLOAD_PRIVATE_MIN && type >= PAYLOAD_IKEV2_SA)
851
		printf("\n\t%spayload: %s len: %hu", ike_tab_offset(),
852
		    plv2types[type - PAYLOAD_IKEV2_SA], this_len);
853
	else if (type < PAYLOAD_PRIVATE_MIN || type >= PAYLOAD_PRIVATE_MAX)
854
		printf("\n\t%spayload: %s len: %hu", ike_tab_offset(),
855
		    (type < (sizeof pltypes/sizeof pltypes[0]) ?
856
			pltypes[type] : "<unknown>"), this_len);
857
	else
858
		printf("\n\t%spayload: %s len: %hu", ike_tab_offset(),
859
		    plprivtypes[type - PAYLOAD_PRIVATE_MIN], this_len);
860
861
	if ((type < PAYLOAD_RESERVED_MIN &&
862
	    (type < sizeof(min_payload_lengths)/sizeof(min_payload_lengths[0]) &&
863
	    this_len < min_payload_lengths[type])) ||
864
	    this_len == 0)
865
		goto pltrunc;
866
867
	if ((type > PAYLOAD_PRIVATE_MIN && type < PAYLOAD_PRIVATE_MAX &&
868
	    this_len < min_priv_payload_lengths[type - PAYLOAD_PRIVATE_MIN]) ||
869
	    this_len == 0)
870
		goto pltrunc;
871
872
	if (buf + this_len > snapend)
873
		goto pltrunc;
874
875
	ike_tab_level++;
876
	switch (type) {
877
	case PAYLOAD_NONE:
878
		return;
879
880
	case PAYLOAD_SA:
881
		ike_pl_sa_print(buf, this_len);
882
		break;
883
884
	case PAYLOAD_PROPOSAL:
885
		ike_pl_proposal_print(buf, this_len, doi);
886
		break;
887
888
	case PAYLOAD_TRANSFORM:
889
		ike_pl_transform_print(buf, this_len, doi);
890
		break;
891
892
	case PAYLOAD_KE:
893
		ike_pl_ke_print(buf, this_len, doi);
894
		break;
895
896
	case PAYLOAD_ID:
897
		/* Should only happen with IPsec DOI */
898
		ipsec_id_print(buf, this_len, doi);
899
		break;
900
901
	case PAYLOAD_CERT:
902
	case PAYLOAD_CERTREQUEST:
903
	case PAYLOAD_HASH:
904
	case PAYLOAD_SIG:
905
	case PAYLOAD_NONCE:
906
		break;
907
908
	case PAYLOAD_DELETE:
909
		ike_pl_delete_print(buf, this_len);
910
		break;
911
912
	case PAYLOAD_NOTIFICATION:
913
	  	ike_pl_notification_print(buf, this_len);
914
		break;
915
916
	case PAYLOAD_VENDOR:
917
		ike_pl_vendor_print(buf, this_len, doi);
918
		break;
919
920
	case PAYLOAD_ATTRIBUTE:
921
		ike_pl_attribute_print(buf, this_len);
922
		break;
923
924
	case PAYLOAD_SAK:
925
	case PAYLOAD_SAT:
926
	case PAYLOAD_KD:
927
	case PAYLOAD_SEQ:
928
	case PAYLOAD_POP:
929
	case PAYLOAD_NAT_D:
930
		break;
931
932
	case PAYLOAD_NAT_OA:
933
		/* RFC3947 NAT-OA uses a subset of the ID payload */
934
		ipsec_id_print(buf, this_len, doi);
935
		break;
936
937
	case PAYLOAD_NAT_D_DRAFT:
938
		break;
939
940
	case PAYLOAD_NAT_OA_DRAFT:
941
		ipsec_id_print(buf, this_len, doi);
942
		break;
943
944
	default:
945
		break;
946
	}
947
	ike_tab_level--;
948
949
	if (next_type)  /* Recurse over next payload */
950
		ike_pl_print(next_type, buf + this_len, doi);
951
952
	return;
953
954
pltrunc:
955
	if (doi == ISAKMP_DOI)
956
		fputs(" [|isakmp]", stdout);
957
	else
958
		fputs(" [|ipsec]", stdout);
959
}