summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcr <mcr>2007-11-24 18:13:33 +0000
committermcr <mcr>2007-11-24 18:13:33 +0000
commit5fa8fc69b23ca302382f07b8ab3de69072fdb68b (patch)
tree1c6094aeff9bda72364dc9836bcf7fc3f2f2f108
parentc51a2d7a9a66ea0398e29473ed8019ea37423c7b (diff)
downloadtcpdump-5fa8fc69b23ca302382f07b8ab3de69072fdb68b.tar.gz
added "make check"
when optimization is not on, glibc6 doesn't define ntohs(), and our attempt to optimize it for x86 doesn't work --- the functions need to be static, not extern. added decryption of IKE v2 payloads, when keys are provided by -E.
-rw-r--r--Makefile.in5
-rw-r--r--isakmp.h24
-rw-r--r--netdissect.h9
-rw-r--r--print-esp.c391
-rw-r--r--print-isakmp.c169
-rw-r--r--tcpdump-stdinc.h12
6 files changed, 471 insertions, 139 deletions
diff --git a/Makefile.in b/Makefile.in
index f8d4f3fa..0a41c77e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -17,7 +17,7 @@
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
-# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.317 2007-09-24 23:46:26 guy Exp $ (LBL)
+# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.318 2007-11-24 18:13:33 mcr Exp $ (LBL)
#
# Various configurable paths (remember to edit Makefile.in, not Makefile)
@@ -197,6 +197,9 @@ distclean:
rm -f $(CLEANFILES) Makefile config.cache config.log config.status \
config.h gnuc.h os-proto.h stamp-h stamp-h.in
+check:
+ (cd tests && ./TESTrun.sh)
+
tags: $(TAGFILES)
ctags -wtd $(TAGFILES)
diff --git a/isakmp.h b/isakmp.h
index 85d383d1..d628f7ae 100644
--- a/isakmp.h
+++ b/isakmp.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* YIPS @(#)$Id: isakmp.h,v 1.11 2007-08-29 02:38:14 mcr Exp $ */
+/* YIPS @(#)$Id: isakmp.h,v 1.12 2007-11-24 18:13:33 mcr Exp $ */
/* refer to RFC 2408 */
@@ -127,6 +127,7 @@ struct isakmp {
#define ISAKMP_NPTYPE_N 11 /* Notification */
#define ISAKMP_NPTYPE_D 12 /* Delete */
#define ISAKMP_NPTYPE_VID 13 /* Vendor ID */
+#define ISAKMP_NPTYPE_v2E 46 /* v2 Encrypted payload */
#define IKEv1_MAJOR_VERSION 1
#define IKEv1_MINOR_VERSION 0
@@ -422,14 +423,31 @@ struct ikev2_ke {
};
+/* 3.5. Identification Payloads */
+enum ikev2_id_type {
+ ID_IPV4_ADDR=1,
+ ID_FQDN=2,
+ ID_RFC822_ADDR=3,
+ ID_IPV6_ADDR=5,
+ ID_DER_ASN1_DN=9,
+ ID_DER_ASN1_GN=10,
+ ID_KEY_ID=11,
+};
+struct ikev2_id {
+ struct isakmp_gen h;
+ u_int8_t type; /* ID type */
+ u_int8_t res1;
+ u_int16_t res2;
+ /* SPI */
+ /* Notification Data */
+};
+
/* 3.10 Notification Payload */
struct ikev2_n {
struct isakmp_gen h;
u_int8_t prot_id; /* Protocol-ID */
u_int8_t spi_size; /* SPI Size */
u_int16_t type; /* Notify Message Type */
- /* SPI */
- /* Notification Data */
};
enum ikev2_n_type {
diff --git a/netdissect.h b/netdissect.h
index fc8dfbab..bea9252f 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -21,7 +21,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.23 2007-01-29 09:59:42 hannes Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.24 2007-11-24 18:13:33 mcr Exp $ (LBL)
*/
#ifndef netdissect_h
@@ -438,4 +438,11 @@ extern u_short in_cksum(const u_short *,
#endif
+extern void esp_print_decodesecret(netdissect_options *ndo);
+extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
+ int initiator,
+ u_char spii[8], u_char spir[8],
+ u_char *buf, u_char *end);
+
+
#endif /* netdissect_h */
diff --git a/print-esp.c b/print-esp.c
index 260fe871..6640f374 100644
--- a/print-esp.c
+++ b/print-esp.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.56 2005-04-21 06:44:40 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.57 2007-11-24 18:13:33 mcr Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -71,14 +71,71 @@ struct sockaddr_storage {
struct sa_list {
struct sa_list *next;
struct sockaddr_storage daddr;
- u_int32_t spi;
+ u_int32_t spi; /* if == 0, then IKEv2 */
+ int initiator;
+ u_char spii[8]; /* for IKEv2 */
+ u_char spir[8];
const EVP_CIPHER *evp;
int ivlen;
int authlen;
+ u_char authsecret[256];
+ int authsecret_len;
u_char secret[256]; /* is that big enough for all secrets? */
int secretlen;
};
+/*
+ * this will adjust ndo_packetp and ndo_snapend to new buffer!
+ */
+int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
+ int initiator,
+ u_char spii[8], u_char spir[8],
+ u_char *buf, u_char *end)
+{
+ struct sa_list *sa;
+ u_char *iv;
+ int len;
+ EVP_CIPHER_CTX ctx;
+
+ /* initiator arg is any non-zero value */
+ if(initiator) initiator=1;
+
+ /* see if we can find the SA, and if so, decode it */
+ for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
+ if (sa->spi == 0
+ && initiator == sa->initiator
+ && memcmp(spii, sa->spii, 8) == 0
+ && memcmp(spir, sa->spir, 8) == 0)
+ break;
+ }
+
+ if(sa == NULL) return 0;
+ if(sa->evp == NULL) return 0;
+
+ /*
+ * remove authenticator, and see if we still have something to
+ * work with
+ */
+ end = end - sa->authlen;
+ iv = buf;
+ buf = buf + sa->ivlen;
+ len = end-buf;
+
+ if(end <= buf) return 0;
+
+ memset(&ctx, 0, sizeof(ctx));
+ if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0)
+ (*ndo->ndo_warning)(ndo, "espkey init failed");
+ EVP_CipherInit(&ctx, NULL, NULL, iv, 0);
+ EVP_Cipher(&ctx, buf, buf, len);
+
+ ndo->ndo_packetp = buf;
+ ndo->ndo_snapend = end;
+
+ return 1;
+
+}
+
static void esp_print_addsa(netdissect_options *ndo,
struct sa_list *sa, int sa_def)
{
@@ -123,13 +180,193 @@ static u_int hex2byte(netdissect_options *ndo, char *hexstring)
}
/*
+ * returns size of binary, 0 on failure.
+ */
+static
+int espprint_decode_hex(netdissect_options *ndo,
+ u_char *binbuf, unsigned int binbuf_len,
+ char *hex)
+{
+ unsigned int len;
+ int i;
+
+ len = strlen(hex) / 2;
+
+ if (len > binbuf_len) {
+ (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
+ return 0;
+ }
+
+ i = 0;
+ while (hex[0] != '\0' && hex[1]!='\0') {
+ binbuf[i] = hex2byte(ndo, hex);
+ hex += 2;
+ i++;
+ }
+
+ return i;
+}
+
+/*
* decode the form: SPINUM@IP <tab> ALGONAME:0xsecret
+ */
+
+static int
+espprint_decode_encalgo(netdissect_options *ndo,
+ char *decode, struct sa_list *sa)
+{
+ int len;
+ size_t i;
+ const EVP_CIPHER *evp;
+ int authlen = 0;
+ char *colon, *p;
+
+ colon = strchr(decode, ':');
+ if (colon == NULL) {
+ (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
+ return 0;
+ }
+ *colon = '\0';
+
+ len = colon - decode;
+ if (strlen(decode) > strlen("-hmac96") &&
+ !strcmp(decode + strlen(decode) - strlen("-hmac96"),
+ "-hmac96")) {
+ p = strstr(decode, "-hmac96");
+ *p = '\0';
+ authlen = 12;
+ }
+ if (strlen(decode) > strlen("-cbc") &&
+ !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
+ p = strstr(decode, "-cbc");
+ *p = '\0';
+ }
+ evp = EVP_get_cipherbyname(decode);
+
+ if (!evp) {
+ (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
+ sa->evp = NULL;
+ sa->authlen = 0;
+ sa->ivlen = 0;
+ return 0;
+ }
+
+ sa->evp = evp;
+ sa->authlen = authlen;
+ sa->ivlen = EVP_CIPHER_iv_length(evp);
+
+ colon++;
+ if (colon[0] == '0' && colon[1] == 'x') {
+ /* decode some hex! */
+
+ colon += 2;
+ sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
+ if(sa->secretlen == 0) return 0;
+ } else {
+ i = strlen(colon);
+
+ if (i < sizeof(sa->secret)) {
+ memcpy(sa->secret, colon, i);
+ sa->secretlen = i;
+ } else {
+ memcpy(sa->secret, colon, sizeof(sa->secret));
+ sa->secretlen = sizeof(sa->secret);
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * for the moment, ignore the auth algorith, just hard code the authenticator
+ * length. Need to research how openssl looks up HMAC stuff.
+ */
+static int
+espprint_decode_authalgo(netdissect_options *ndo,
+ char *decode, struct sa_list *sa)
+{
+ char *colon;
+
+ colon = strchr(decode, ':');
+ if (colon == NULL) {
+ (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
+ return 0;
+ }
+ *colon = '\0';
+
+ if(strcasecmp(colon,"sha1") == 0 ||
+ strcasecmp(colon,"md5") == 0) {
+ sa->authlen = 12;
+ }
+ return 1;
+}
+
+static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
+ const char *file, int lineno)
+{
+ /* it's an IKEv2 secret, store it instead */
+ struct sa_list sa1;
+
+ char *init;
+ char *icookie, *rcookie;
+ int ilen, rlen;
+ char *authkey;
+ char *enckey;
+
+ init = strsep(&line, " \t");
+ icookie = strsep(&line, " \t");
+ rcookie = strsep(&line, " \t");
+ authkey = strsep(&line, " \t");
+ enckey = strsep(&line, " \t");
+
+ /* if any fields are missing */
+ if(!init || !icookie || !rcookie || !authkey || !enckey) {
+ (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
+ file, lineno);
+
+ return;
+ }
+
+ ilen = strlen(icookie);
+ rlen = strlen(rcookie);
+
+ if((init[0]!='I' && init[0]!='R')
+ || icookie[0]!='0' || icookie[1]!='x'
+ || rcookie[0]!='0' || rcookie[1]!='x'
+ || ilen!=18
+ || rlen!=18) {
+ (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
+ file, lineno);
+
+ (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
+ init, icookie, ilen, rcookie, rlen);
+
+ return;
+ }
+
+ sa1.spi = 0;
+ sa1.initiator = (init[0] == 'I');
+ if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
+ return;
+
+ if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
+ return;
+
+ if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
+
+ if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
+
+ esp_print_addsa(ndo, &sa1, FALSE);
+}
+
+/*
*
* special form: file /name
* causes us to go read from this file instead.
*
*/
-static void esp_print_decode_onesecret(netdissect_options *ndo, char *line)
+static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
+ const char *file, int lineno)
{
struct sa_list sa1;
int sa_def;
@@ -155,15 +392,18 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line)
/* open file and read it */
FILE *secretfile;
char fileline[1024];
+ int lineno=0;
char *nl;
+ char *filename = line;
- secretfile = fopen(line, FOPEN_READ_TXT);
+ secretfile = fopen(filename, FOPEN_READ_TXT);
if (secretfile == NULL) {
- perror(line);
+ perror(filename);
exit(3);
}
while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
+ lineno++;
/* remove newline from the line */
nl = strchr(fileline, '\n');
if (nl)
@@ -171,31 +411,37 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line)
if (fileline[0] == '#') continue;
if (fileline[0] == '\0') continue;
- esp_print_decode_onesecret(ndo, fileline);
+ esp_print_decode_onesecret(ndo, fileline, filename, lineno);
}
fclose(secretfile);
return;
}
+ if (spikey && strcasecmp(spikey, "ikev2") == 0) {
+ esp_print_decode_ikeline(ndo, line, file, lineno);
+ return;
+ }
+
if (spikey) {
+
char *spistr, *foo;
u_int32_t spino;
struct sockaddr_in *sin;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
-
+
spistr = strsep(&spikey, "@");
-
+
spino = strtoul(spistr, &foo, 0);
if (spistr == foo || !spikey) {
(*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
return;
}
-
+
sa1.spi = spino;
-
+
sin = (struct sockaddr_in *)&sa1.daddr;
#ifdef INET6
sin6 = (struct sockaddr_in6 *)&sa1.daddr;
@@ -206,122 +452,63 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line)
sin6->sin6_family = AF_INET6;
} else
#endif
- if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) {
+ if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) {
#ifdef HAVE_SOCKADDR_SA_LEN
- sin->sin_len = sizeof(struct sockaddr_in);
+ sin->sin_len = sizeof(struct sockaddr_in);
#endif
- sin->sin_family = AF_INET;
- } else {
- (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
- return;
- }
+ sin->sin_family = AF_INET;
+ } else {
+ (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
+ return;
+ }
}
if (decode) {
- char *colon, *p;
- u_char espsecret_key[256];
- int len;
- size_t i;
- const EVP_CIPHER *evp;
- int authlen = 0;
-
/* skip any blank spaces */
while (isspace((unsigned char)*decode))
decode++;
-
- colon = strchr(decode, ':');
- if (colon == NULL) {
- (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
+
+ if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
return;
}
- *colon = '\0';
-
- len = colon - decode;
- if (strlen(decode) > strlen("-hmac96") &&
- !strcmp(decode + strlen(decode) - strlen("-hmac96"),
- "-hmac96")) {
- p = strstr(decode, "-hmac96");
- *p = '\0';
- authlen = 12;
- }
- if (strlen(decode) > strlen("-cbc") &&
- !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
- p = strstr(decode, "-cbc");
- *p = '\0';
- }
- evp = EVP_get_cipherbyname(decode);
- if (!evp) {
- (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
- sa1.evp = NULL;
- sa1.authlen = 0;
- sa1.ivlen = 0;
- return;
- }
-
- sa1.evp = evp;
- sa1.authlen = authlen;
- sa1.ivlen = EVP_CIPHER_iv_length(evp);
-
- colon++;
- if (colon[0] == '0' && colon[1] == 'x') {
- /* decode some hex! */
- colon += 2;
- len = strlen(colon) / 2;
-
- if (len > 256) {
- (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
- return;
- }
-
- i = 0;
- while (colon[0] != '\0' && colon[1]!='\0') {
- espsecret_key[i] = hex2byte(ndo, colon);
- colon += 2;
- i++;
- }
-
- memcpy(sa1.secret, espsecret_key, i);
- sa1.secretlen = i;
- } else {
- i = strlen(colon);
-
- if (i < sizeof(sa1.secret)) {
- memcpy(sa1.secret, colon, i);
- sa1.secretlen = i;
- } else {
- memcpy(sa1.secret, colon, sizeof(sa1.secret));
- sa1.secretlen = sizeof(sa1.secret);
- }
- }
}
esp_print_addsa(ndo, &sa1, sa_def);
}
-static void esp_print_decodesecret(netdissect_options *ndo)
+static void esp_init(netdissect_options *ndo _U_)
+{
+
+ OpenSSL_add_all_algorithms();
+ EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
+}
+
+void esp_print_decodesecret(netdissect_options *ndo)
{
char *line;
char *p;
+ static int initialized = 0;
+
+ if (!initialized) {
+ esp_init(ndo);
+ initialized = 1;
+ }
p = ndo->ndo_espsecret;
- while (ndo->ndo_espsecret && ndo->ndo_espsecret[0] != '\0') {
+ while (p && p[0] != '\0') {
/* pick out the first line or first thing until a comma */
- if ((line = strsep(&ndo->ndo_espsecret, "\n,")) == NULL) {
- line = ndo->ndo_espsecret;
- ndo->ndo_espsecret = NULL;
+ if ((line = strsep(&p, "\n,")) == NULL) {
+ line = p;
+ p = NULL;
}
- esp_print_decode_onesecret(ndo, line);
+ esp_print_decode_onesecret(ndo, line, "cmdline", 0);
}
-}
-static void esp_init(netdissect_options *ndo _U_)
-{
-
- OpenSSL_add_all_algorithms();
- EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
+ ndo->ndo_espsecret = NULL;
}
+
#endif
int
@@ -359,7 +546,6 @@ esp_print(netdissect_options *ndo,
u_char *p;
EVP_CIPHER_CTX ctx;
int blocksz;
- static int initialized = 0;
#endif
esp = (struct newesp *)bp;
@@ -367,11 +553,6 @@ esp_print(netdissect_options *ndo,
#ifdef HAVE_LIBCRYPTO
secret = NULL;
advance = 0;
-
- if (!initialized) {
- esp_init(ndo);
- initialized = 1;
- }
#endif
#if 0
diff --git a/print-isakmp.c b/print-isakmp.c
index 319087e6..2a4c56fe 100644
--- a/print-isakmp.c
+++ b/print-isakmp.c
@@ -30,7 +30,7 @@
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.57 2007-11-22 21:53:43 mcr Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.58 2007-11-24 18:13:33 mcr Exp $ (LBL)";
#endif
#define NETDISSECT_REWORKED
@@ -94,16 +94,27 @@ DECLARE_PRINTER(v2_n);
DECLARE_PRINTER(v2_d);
DECLARE_PRINTER(v2_vid);
DECLARE_PRINTER(v2_TS);
-DECLARE_PRINTER(v2_e);
DECLARE_PRINTER(v2_cp);
DECLARE_PRINTER(v2_eap);
+static const u_char *ikev2_e_print(netdissect_options *ndo,
+ struct isakmp *base,
+ u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len,
+ const u_char *end_pointer,
+ u_int32_t phase,
+ u_int32_t doi0,
+ u_int32_t proto0, int depth);
+
+
static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
static const u_char *ikev2_sub_print(netdissect_options *ndo,
+ struct isakmp *base,
u_char np, const struct isakmp_gen *ext,
const u_char *ep, u_int32_t phase,
u_int32_t doi, u_int32_t proto,
@@ -185,7 +196,7 @@ static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
ikev2_vid_print, /* 43 */
ikev2_TS_print, /* 44 */
ikev2_TS_print, /* 45 */
- ikev2_e_print, /* 46 */
+ NULL, /* ikev2_e_print,*/ /* 46 - special */
ikev2_cp_print, /* 47 */
ikev2_eap_print, /* 48 */
};
@@ -391,22 +402,29 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator)
return 0;
}
-static int
-rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
+static void
+hexprint(netdissect_options *ndo, caddr_t loc, size_t len)
{
- static u_char *p;
+ u_char *p;
size_t i;
- ND_TCHECK2(*loc, len);
-
p = (u_char *)loc;
for (i = 0; i < len; i++)
ND_PRINT((ndo,"%02x", p[i] & 0xff));
+}
+
+static int
+rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
+{
+ ND_TCHECK2(*loc, len);
+
+ hexprint(ndo, loc, len);
return 1;
trunc:
return 0;
}
+
/*
* returns false if we run out of data buffer
*/
@@ -1507,7 +1525,7 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
ND_TCHECK(*ext);
- cp = ikev2_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
+ cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
prop.prot_id, depth);
return cp;
@@ -1534,7 +1552,7 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
sa_len = osa_len - 4;
ND_PRINT((ndo," len=%d", sa_len));
- ikev2_sub_print(ndo, ISAKMP_NPTYPE_P,
+ ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
ext1+1, ep,
0, 0, 0, depth);
@@ -1580,7 +1598,79 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
u_int32_t phase _U_, u_int32_t doi _U_,
u_int32_t proto _U_, int depth _U_)
{
- return ikev2_gen_print(ndo, tpay, ext);
+ struct ikev2_id id;
+ int id_len, idtype_len, i;
+ unsigned int dumpascii, dumphex;
+ unsigned char *typedata;
+
+ ND_TCHECK(*ext);
+ safememcpy(&id, ext, sizeof(id));
+ ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
+
+ id_len = ntohs(id.h.len);
+
+ ND_PRINT((ndo," len=%d", id_len - 4));
+ if (2 < ndo->ndo_vflag && 4 < id_len) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4))
+ goto trunc;
+ }
+
+ idtype_len =id_len - sizeof(struct ikev2_id);
+ dumpascii = 0;
+ dumphex = 0;
+ typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id);
+
+ switch(id.type) {
+ case ID_IPV4_ADDR:
+ ND_PRINT((ndo, " ipv4:"));
+ dumphex=1;
+ break;
+ case ID_FQDN:
+ ND_PRINT((ndo, " fqdn:"));
+ dumpascii=1;
+ break;
+ case ID_RFC822_ADDR:
+ ND_PRINT((ndo, " rfc822:"));
+ dumpascii=1;
+ break;
+ case ID_IPV6_ADDR:
+ ND_PRINT((ndo, " ipv6:"));
+ dumphex=1;
+ break;
+ case ID_DER_ASN1_DN:
+ ND_PRINT((ndo, " dn:"));
+ dumphex=1;
+ break;
+ case ID_DER_ASN1_GN:
+ ND_PRINT((ndo, " gn:"));
+ dumphex=1;
+ break;
+ case ID_KEY_ID:
+ ND_PRINT((ndo, " keyid:"));
+ dumphex=1;
+ break;
+ }
+
+ if(dumpascii) {
+ ND_TCHECK2(*typedata, idtype_len);
+ for(i=0; i<idtype_len; i++) {
+ if(isprint(typedata[i])) {
+ ND_PRINT((ndo, "%c", typedata[i]));
+ } else {
+ ND_PRINT((ndo, "."));
+ }
+ }
+ }
+ if(dumphex) {
+ if (!rawprint(ndo, typedata, idtype_len))
+ goto trunc;
+ }
+
+ return (u_char *)ext + id_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
}
static const u_char *
@@ -1930,25 +2020,47 @@ ikev2_TS_print(netdissect_options *ndo, u_char tpay,
}
static const u_char *
-ikev2_e_print(netdissect_options *ndo, u_char tpay,
+ikev2_e_print(netdissect_options *ndo, struct isakmp *base,
+ u_char tpay,
const struct isakmp_gen *ext,
u_int item_len _U_, const u_char *ep _U_,
- u_int32_t phase _U_, u_int32_t doi _U_,
- u_int32_t proto _U_, int depth _U_)
+ u_int32_t phase, u_int32_t doi,
+ u_int32_t proto, int depth)
{
struct isakmp_gen e;
+ u_char *dat;
+ volatile int dlen;
ND_TCHECK(*ext);
safememcpy(&e, ext, sizeof(e));
ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
- ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
- if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ dlen = ntohs(e.len)-4;
+
+ ND_PRINT((ndo," len=%d", dlen));
+ if (2 < ndo->ndo_vflag && 4 < dlen) {
ND_PRINT((ndo," "));
- if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ if (!rawprint(ndo, (caddr_t)(ext + 1), dlen))
goto trunc;
}
+ dat = (u_char *)(ext+1);
+ ND_TCHECK2(*dat, dlen);
+
+ /* try to decypt it! */
+ if(esp_print_decrypt_buffer_by_ikev2(ndo,
+ base->flags & ISAKMP_FLAG_I,
+ base->i_ck, base->r_ck,
+ dat, dat+dlen)) {
+
+ ext = (const struct isakmp_gen *)ndo->ndo_packetp;
+
+ /* got it decrypted, print stuff inside. */
+ ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
+ phase, doi, proto, depth+1);
+ }
+
+
/* always return NULL, because E must be at end, and NP refers
* to what was inside.
*/
@@ -2156,7 +2268,8 @@ done:
}
static const u_char *
-ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount,
+ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
+ u_char np, int pcount,
const struct isakmp_gen *ext, const u_char *ep,
u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
{
@@ -2184,6 +2297,9 @@ ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount,
} else if(np == ISAKMP_NPTYPE_T) {
cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
ep, phase, doi, proto, depth);
+ } else if(np == ISAKMP_NPTYPE_v2E) {
+ cp = ikev2_e_print(ndo, base, np, ext, item_len,
+ ep, phase, doi, proto, depth);
} else if (NPFUNC(np)) {
/*
* XXX - what if item_len is too short, or too long,
@@ -2204,6 +2320,7 @@ trunc:
static const u_char *
ikev2_sub_print(netdissect_options *ndo,
+ struct isakmp *base,
u_char np, const struct isakmp_gen *ext, const u_char *ep,
u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
{
@@ -2227,7 +2344,7 @@ ikev2_sub_print(netdissect_options *ndo,
for (i = 0; i < depth; i++)
ND_PRINT((ndo," "));
ND_PRINT((ndo,"("));
- cp = ikev2_sub0_print(ndo, np, pcount,
+ cp = ikev2_sub0_print(ndo, base, np, pcount,
ext, ep, phase, doi, proto, depth);
ND_PRINT((ndo,")"));
depth--;
@@ -2294,7 +2411,7 @@ ikev2_print(netdissect_options *ndo,
np = base->np;
ext = (struct isakmp_gen *)(p + 1);
- ikev2_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
+ ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
}
done:
@@ -2316,6 +2433,12 @@ isakmp_print(netdissect_options *ndo,
const u_char *ep;
int major, minor;
+ /* initiailize SAs */
+ if (ndo->ndo_sa_list_head == NULL) {
+ if (ndo->ndo_espsecret)
+ esp_print_decodesecret(ndo);
+ }
+
p = (const struct isakmp *)bp;
ep = ndo->ndo_snapend;
@@ -2338,14 +2461,14 @@ isakmp_print(netdissect_options *ndo,
if (ndo->ndo_vflag) {
ND_PRINT((ndo," msgid "));
- rawprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
+ hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
}
if (1 < ndo->ndo_vflag) {
ND_PRINT((ndo," cookie "));
- rawprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
+ hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
ND_PRINT((ndo,"->"));
- rawprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
+ hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
}
ND_PRINT((ndo,":"));
diff --git a/tcpdump-stdinc.h b/tcpdump-stdinc.h
index 30d42fcd..12caf777 100644
--- a/tcpdump-stdinc.h
+++ b/tcpdump-stdinc.h
@@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
- * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.17 2006-05-19 17:55:34 hannes Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.18 2007-11-24 18:13:33 mcr Exp $ (LBL)
*/
/*
@@ -143,21 +143,21 @@ typedef char* caddr_t;
#define FOPEN_WRITE_BIN FOPEN_WRITE_TXT
#endif
-#if defined(__GNUC__) && defined(__i386__) && !defined(__ntohl)
+#if defined(__GNUC__) && defined(__i386__) && !defined(__ntohl)
#undef ntohl
#undef ntohs
#undef htonl
#undef htons
- extern __inline__ unsigned long __ntohl (unsigned long x);
- extern __inline__ unsigned short __ntohs (unsigned short x);
+ static __inline__ unsigned long __ntohl (unsigned long x);
+ static __inline__ unsigned short __ntohs (unsigned short x);
#define ntohl(x) __ntohl(x)
#define ntohs(x) __ntohs(x)
#define htonl(x) __ntohl(x)
#define htons(x) __ntohs(x)
- extern __inline__ unsigned long __ntohl (unsigned long x)
+ static __inline__ unsigned long __ntohl (unsigned long x)
{
__asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */
"rorl $16, %0\n\t" /* swap words */
@@ -166,7 +166,7 @@ typedef char* caddr_t;
return (x);
}
- extern __inline__ unsigned short __ntohs (unsigned short x)
+ static __inline__ unsigned short __ntohs (unsigned short x)
{
__asm__ ("xchgb %b0, %h0" /* swap bytes */
: "=q" (x) : "0" (x));