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