]> The Tcpdump Group git mirrors - tcpdump/blob - print-esp.c
Bring in KAME IPv6 tcpdump. replaces esp/ah/isakmp decoder.
[tcpdump] / print-esp.c
1 /* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24 #ifndef lint
25 static char rcsid[] =
26 "@(#) Header: print-ah.c,v 1.37 94/06/10 17:01:42 mccanne Exp (LBL)";
27 #endif
28
29 #include <string.h>
30 #include <sys/param.h>
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34
35 #include <net/route.h>
36 #include <net/if.h>
37
38 #include <netinet/in.h>
39 #include <netinet/if_ether.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/ip.h>
42 #include <netinet/ip_icmp.h>
43 #include <netinet/ip_var.h>
44 #include <netinet/udp.h>
45 #include <netinet/udp_var.h>
46 #include <netinet/tcp.h>
47
48 #ifdef CRYPTO
49 #include <des.h>
50 #include <blowfish.h>
51 #ifdef HAVE_RC5_H
52 #include <rc5.h>
53 #endif
54 #ifdef HAVE_CAST_H
55 #include <cast.h>
56 #endif
57 #endif
58
59 #include <stdio.h>
60
61 #ifdef INET6
62 #include <netinet/ip6.h>
63 #endif
64
65 /* there's no standard definition so we are on our own */
66 struct esp {
67 u_int32_t esp_spi; /* ESP */
68 /*variable size, 32bit bound*/ /* Initialization Vector */
69 /*variable size*/ /* Payload data */
70 /*variable size*/ /* padding */
71 /*8bit*/ /* pad size */
72 /*8bit*/ /* next header */
73 /*8bit*/ /* next header */
74 /*variable size, 32bit bound*/ /* Authentication data (new IPsec) */
75 };
76
77 struct newesp {
78 u_int32_t esp_spi; /* ESP */
79 u_int32_t esp_seq; /* Sequence number */
80 /*variable size*/ /* (IV and) Payload data */
81 /*variable size*/ /* padding */
82 /*8bit*/ /* pad size */
83 /*8bit*/ /* next header */
84 /*8bit*/ /* next header */
85 /*variable size, 32bit bound*/ /* Authentication data */
86 };
87
88 #include "interface.h"
89 #include "addrtoname.h"
90
91 int
92 esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
93 {
94 register const struct esp *esp;
95 register const u_char *ep;
96 u_int32_t spi;
97 enum { NONE, DESCBC, BLOWFISH, RC5, CAST128, DES3CBC } algo = NONE;
98 struct ip *ip = NULL;
99 #ifdef INET6
100 struct ip6_hdr *ip6 = NULL;
101 #endif
102 int advance;
103 int len;
104 char *secret = NULL;
105 int ivlen = 0;
106 u_char *ivoff;
107
108 esp = (struct esp *)bp;
109 spi = (u_int32_t)ntohl(esp->esp_spi);
110
111 /* 'ep' points to the end of avaible data. */
112 ep = snapend;
113
114 if ((u_char *)(esp + 1) >= ep - sizeof(struct esp)) {
115 fputs("[|ESP]", stdout);
116 goto fail;
117 }
118 printf("ESP(spi=%u", spi);
119 printf(",seq=0x%x", (u_int32_t)ntohl(*(u_int32_t *)(esp + 1)));
120 printf(")");
121
122 /* if we don't have decryption key, we can't decrypt this packet. */
123 if (!espsecret)
124 goto fail;
125
126 if (strncmp(espsecret, "des-cbc:", 8) == 0
127 && strlen(espsecret + 8) == 8) {
128 algo = DESCBC;
129 ivlen = 8;
130 secret = espsecret + 8;
131 } else if (strncmp(espsecret, "blowfish-cbc:", 13) == 0) {
132 algo = BLOWFISH;
133 ivlen = 8;
134 secret = espsecret + 13;
135 } else if (strncmp(espsecret, "rc5-cbc:", 8) == 0) {
136 algo = RC5;
137 ivlen = 8;
138 secret = espsecret + 8;
139 } else if (strncmp(espsecret, "cast128-cbc:", 12) == 0) {
140 algo = CAST128;
141 ivlen = 8;
142 secret = espsecret + 12;
143 } else if (strncmp(espsecret, "3des-cbc:", 9) == 0
144 && strlen(espsecret + 9) == 24) {
145 algo = DES3CBC;
146 ivlen = 8;
147 secret = espsecret + 9;
148 } else if (strncmp(espsecret, "none:", 5) == 0) {
149 algo = NONE;
150 ivlen = 0;
151 secret = espsecret + 5;
152 } else if (strlen(espsecret) == 8) {
153 algo = DESCBC;
154 ivlen = 8;
155 secret = espsecret;
156 } else {
157 algo = NONE;
158 ivlen = 0;
159 secret = espsecret;
160 }
161
162 ip = (struct ip *)bp2;
163 switch (ip->ip_v) {
164 #ifdef INET6
165 case 6:
166 ip6 = (struct ip6_hdr *)bp2;
167 ip = NULL;
168 /* we do not attempt to decrypt jumbograms */
169 if (!ntohs(ip6->ip6_plen))
170 goto fail;
171 /* if we can't get nexthdr, we do not need to decrypt it */
172 len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
173 break;
174 #endif /*INET6*/
175 case 4:
176 #ifdef INET6
177 ip6 = NULL;
178 #endif
179 len = ntohs(ip->ip_len);
180 break;
181 default:
182 goto fail;
183 }
184
185 /* if we can't get nexthdr, we do not need to decrypt it */
186 if (ep - bp2 < len)
187 goto fail;
188
189 if (Rflag)
190 ivoff = (u_char *)(esp + 1) + sizeof(u_int32_t);
191 else
192 ivoff = (u_char *)(esp + 1);
193
194 switch (algo) {
195 case DESCBC:
196 #ifdef CRYPTO
197 {
198 u_char iv[8];
199 des_key_schedule schedule;
200 u_char *p;
201
202 switch (ivlen) {
203 case 4:
204 memcpy(iv, ivoff, 4);
205 memcpy(&iv[4], ivoff, 4);
206 p = &iv[4];
207 *p++ ^= 0xff;
208 *p++ ^= 0xff;
209 *p++ ^= 0xff;
210 *p++ ^= 0xff;
211 break;
212 case 8:
213 memcpy(iv, ivoff, 8);
214 break;
215 default:
216 goto fail;
217 }
218
219 des_check_key = 0;
220 des_set_key((void *)secret, schedule);
221
222 p = ivoff + ivlen;
223 des_cbc_encrypt((void *)p, (void *)p,
224 (long)(ep - p), schedule, (void *)iv,
225 DES_DECRYPT);
226 advance = ivoff - (u_char *)esp + ivlen;
227 break;
228 }
229 #else
230 goto fail;
231 #endif /*CRYPTO*/
232
233 case BLOWFISH:
234 #ifdef CRYPTO
235 {
236 BF_KEY schedule;
237 u_char *p;
238
239 BF_set_key(&schedule, strlen(secret), secret);
240
241 p = ivoff + ivlen;
242 BF_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
243 BF_DECRYPT);
244 advance = ivoff - (u_char *)esp + ivlen;
245 break;
246 }
247 #else
248 goto fail;
249 #endif /*CRYPTO*/
250
251 case RC5:
252 #if defined(CRYPTO) && defined(HAVE_RC5_H)
253 {
254 RC5_32_KEY schedule;
255 u_char *p;
256
257 RC5_32_set_key(&schedule, strlen(secret), secret,
258 RC5_16_ROUNDS);
259
260 p = ivoff + ivlen;
261 RC5_32_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
262 RC5_DECRYPT);
263 advance = ivoff - (u_char *)esp + ivlen;
264 break;
265 }
266 #else
267 goto fail;
268 #endif /*CRYPTO*/
269
270 case CAST128:
271 #if defined(CRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128)
272 {
273 CAST_KEY schedule;
274 u_char *p;
275
276 CAST_set_key(&schedule, strlen(secret), secret);
277
278 p = ivoff + ivlen;
279 CAST_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
280 CAST_DECRYPT);
281 advance = ivoff - (u_char *)esp + ivlen;
282 break;
283 }
284 #else
285 goto fail;
286 #endif /*CRYPTO*/
287
288 case DES3CBC:
289 #if defined(CRYPTO)
290 {
291 des_key_schedule s1, s2, s3;
292 u_char *p;
293
294 des_check_key = 0;
295 des_set_key((void *)secret, s1);
296 des_set_key((void *)(secret + 8), s2);
297 des_set_key((void *)(secret + 16), s3);
298
299 p = ivoff + ivlen;
300 des_ede3_cbc_encrypt((void *)p, (void *)p,
301 (long)(ep - p), s1, s2, s3, (void *)ivoff, DES_DECRYPT);
302 advance = ivoff - (u_char *)esp + ivlen;
303 break;
304 }
305 #else
306 goto fail;
307 #endif /*CRYPTO*/
308
309 case NONE:
310 default:
311 if (Rflag)
312 advance = sizeof(struct esp) + sizeof(u_int32_t);
313 else
314 advance = sizeof(struct esp);
315 break;
316 }
317
318 /* sanity check for pad length */
319 if (ep - bp < *(ep - 2))
320 goto fail;
321
322 if (nhdr)
323 *nhdr = *(ep - 1);
324
325 printf(": ");
326 return advance;
327
328 fail:
329 if (nhdr)
330 *nhdr = -1;
331 return 65536;
332 }