]> The Tcpdump Group git mirrors - tcpdump/blob - print-esp.c
move ah/esp struct declratiaon into separate header (ah.h and esp.h).
[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 const char rcsid[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.15 2000-10-06 11:32:19 itojun Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38
39 #include <netinet/in.h>
40
41 #ifdef HAVE_LIBCRYPTO
42 #include <des.h>
43 #include <blowfish.h>
44 #ifdef HAVE_RC5_H
45 #include <rc5.h>
46 #endif
47 #ifdef HAVE_CAST_H
48 #include <cast.h>
49 #endif
50 #endif
51
52 #include <stdio.h>
53
54 #ifdef INET6
55 #include <netinet/ip6.h>
56 #endif
57
58 #include "ip.h"
59 #include "esp.h"
60
61 #include "interface.h"
62 #include "addrtoname.h"
63
64 int
65 esp_print(register const u_char *bp, register const u_char *bp2, int *nhdr)
66 {
67 register const struct esp *esp;
68 register const u_char *ep;
69 u_int32_t spi;
70 enum { NONE, DESCBC, BLOWFISH, RC5, CAST128, DES3CBC } algo = NONE;
71 struct ip *ip = NULL;
72 #ifdef INET6
73 struct ip6_hdr *ip6 = NULL;
74 #endif
75 int advance;
76 int len;
77 char *secret = NULL;
78 int ivlen = 0;
79 u_char *ivoff;
80
81 esp = (struct esp *)bp;
82 spi = (u_int32_t)ntohl(esp->esp_spi);
83
84 /* 'ep' points to the end of available data. */
85 ep = snapend;
86
87 if ((u_char *)(esp + 1) >= ep - sizeof(struct esp)) {
88 fputs("[|ESP]", stdout);
89 goto fail;
90 }
91 printf("ESP(spi=%u", spi);
92 printf(",seq=0x%x", (u_int32_t)ntohl(*(u_int32_t *)(esp + 1)));
93 printf(")");
94
95 /* if we don't have decryption key, we can't decrypt this packet. */
96 if (!espsecret)
97 goto fail;
98
99 if (strncmp(espsecret, "des-cbc:", 8) == 0
100 && strlen(espsecret + 8) == 8) {
101 algo = DESCBC;
102 ivlen = 8;
103 secret = espsecret + 8;
104 } else if (strncmp(espsecret, "blowfish-cbc:", 13) == 0) {
105 algo = BLOWFISH;
106 ivlen = 8;
107 secret = espsecret + 13;
108 } else if (strncmp(espsecret, "rc5-cbc:", 8) == 0) {
109 algo = RC5;
110 ivlen = 8;
111 secret = espsecret + 8;
112 } else if (strncmp(espsecret, "cast128-cbc:", 12) == 0) {
113 algo = CAST128;
114 ivlen = 8;
115 secret = espsecret + 12;
116 } else if (strncmp(espsecret, "3des-cbc:", 9) == 0
117 && strlen(espsecret + 9) == 24) {
118 algo = DES3CBC;
119 ivlen = 8;
120 secret = espsecret + 9;
121 } else if (strncmp(espsecret, "none:", 5) == 0) {
122 algo = NONE;
123 ivlen = 0;
124 secret = espsecret + 5;
125 } else if (strlen(espsecret) == 8) {
126 algo = DESCBC;
127 ivlen = 8;
128 secret = espsecret;
129 } else {
130 algo = NONE;
131 ivlen = 0;
132 secret = espsecret;
133 }
134
135 ip = (struct ip *)bp2;
136 switch (IP_V(ip)) {
137 #ifdef INET6
138 case 6:
139 ip6 = (struct ip6_hdr *)bp2;
140 ip = NULL;
141 /* we do not attempt to decrypt jumbograms */
142 if (!ntohs(ip6->ip6_plen))
143 goto fail;
144 /* if we can't get nexthdr, we do not need to decrypt it */
145 len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
146 break;
147 #endif /*INET6*/
148 case 4:
149 #ifdef INET6
150 ip6 = NULL;
151 #endif
152 len = ntohs(ip->ip_len);
153 break;
154 default:
155 goto fail;
156 }
157
158 /* if we can't get nexthdr, we do not need to decrypt it */
159 if (ep - bp2 < len)
160 goto fail;
161
162 if (Rflag)
163 ivoff = (u_char *)(esp + 1) + sizeof(u_int32_t);
164 else
165 ivoff = (u_char *)(esp + 1);
166
167 switch (algo) {
168 case DESCBC:
169 #ifdef HAVE_LIBCRYPTO
170 {
171 u_char iv[8];
172 des_key_schedule schedule;
173 u_char *p;
174
175 switch (ivlen) {
176 case 4:
177 memcpy(iv, ivoff, 4);
178 memcpy(&iv[4], ivoff, 4);
179 p = &iv[4];
180 *p++ ^= 0xff;
181 *p++ ^= 0xff;
182 *p++ ^= 0xff;
183 *p++ ^= 0xff;
184 break;
185 case 8:
186 memcpy(iv, ivoff, 8);
187 break;
188 default:
189 goto fail;
190 }
191
192 des_check_key = 0;
193 des_set_key((void *)secret, schedule);
194
195 p = ivoff + ivlen;
196 des_cbc_encrypt((void *)p, (void *)p,
197 (long)(ep - p), schedule, (void *)iv,
198 DES_DECRYPT);
199 advance = ivoff - (u_char *)esp + ivlen;
200 break;
201 }
202 #else
203 goto fail;
204 #endif /*HAVE_LIBCRYPTO*/
205
206 case BLOWFISH:
207 #ifdef HAVE_LIBCRYPTO
208 {
209 BF_KEY schedule;
210 u_char *p;
211
212 BF_set_key(&schedule, strlen(secret), secret);
213
214 p = ivoff + ivlen;
215 BF_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
216 BF_DECRYPT);
217 advance = ivoff - (u_char *)esp + ivlen;
218 break;
219 }
220 #else
221 goto fail;
222 #endif /*HAVE_LIBCRYPTO*/
223
224 case RC5:
225 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_RC5_H)
226 {
227 RC5_32_KEY schedule;
228 u_char *p;
229
230 RC5_32_set_key(&schedule, strlen(secret), secret,
231 RC5_16_ROUNDS);
232
233 p = ivoff + ivlen;
234 RC5_32_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
235 RC5_DECRYPT);
236 advance = ivoff - (u_char *)esp + ivlen;
237 break;
238 }
239 #else
240 goto fail;
241 #endif /*HAVE_LIBCRYPTO*/
242
243 case CAST128:
244 #if defined(HAVE_LIBCRYPTO) && defined(HAVE_CAST_H) && !defined(HAVE_BUGGY_CAST128)
245 {
246 CAST_KEY schedule;
247 u_char *p;
248
249 CAST_set_key(&schedule, strlen(secret), secret);
250
251 p = ivoff + ivlen;
252 CAST_cbc_encrypt(p, p, (long)(ep - p), &schedule, ivoff,
253 CAST_DECRYPT);
254 advance = ivoff - (u_char *)esp + ivlen;
255 break;
256 }
257 #else
258 goto fail;
259 #endif /*HAVE_LIBCRYPTO*/
260
261 case DES3CBC:
262 #if defined(HAVE_LIBCRYPTO)
263 {
264 des_key_schedule s1, s2, s3;
265 u_char *p;
266
267 des_check_key = 0;
268 des_set_key((void *)secret, s1);
269 des_set_key((void *)(secret + 8), s2);
270 des_set_key((void *)(secret + 16), s3);
271
272 p = ivoff + ivlen;
273 des_ede3_cbc_encrypt((void *)p, (void *)p,
274 (long)(ep - p), s1, s2, s3, (void *)ivoff, DES_DECRYPT);
275 advance = ivoff - (u_char *)esp + ivlen;
276 break;
277 }
278 #else
279 goto fail;
280 #endif /*HAVE_LIBCRYPTO*/
281
282 case NONE:
283 default:
284 if (Rflag)
285 advance = sizeof(struct esp) + sizeof(u_int32_t);
286 else
287 advance = sizeof(struct esp);
288 break;
289 }
290
291 /* sanity check for pad length */
292 if (ep - bp < *(ep - 2))
293 goto fail;
294
295 if (nhdr)
296 *nhdr = *(ep - 1);
297
298 printf(": ");
299 return advance;
300
301 fail:
302 if (nhdr)
303 *nhdr = -1;
304 return 65536;
305 }