summaryrefslogtreecommitdiffstats
path: root/contrib/tcpdump/print-esp.c
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2009-03-20 13:27:51 +0000
committerrpaulo <rpaulo@FreeBSD.org>2009-03-20 13:27:51 +0000
commit04b1d6babecbe3eed463c150b6e933a2b6d342a9 (patch)
tree36afae3dff76dde8d1cee5971ff7f1bc4922ad0f /contrib/tcpdump/print-esp.c
parent3b74598d7ea581deadb14ec8ba1c77c14295a7c8 (diff)
downloadFreeBSD-src-04b1d6babecbe3eed463c150b6e933a2b6d342a9.zip
FreeBSD-src-04b1d6babecbe3eed463c150b6e933a2b6d342a9.tar.gz
Flatten vendor/tcpdump and remove keyword expansion.
Diffstat (limited to 'contrib/tcpdump/print-esp.c')
-rw-r--r--contrib/tcpdump/print-esp.c511
1 files changed, 0 insertions, 511 deletions
diff --git a/contrib/tcpdump/print-esp.c b/contrib/tcpdump/print-esp.c
deleted file mode 100644
index 3ccc899..0000000
--- a/contrib/tcpdump/print-esp.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.55.2.1 2005/04/21 06:44:57 guy Exp $ (LBL)";
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <tcpdump-stdinc.h>
-
-#include <stdlib.h>
-
-#ifdef HAVE_LIBCRYPTO
-#ifdef HAVE_OPENSSL_EVP_H
-#include <openssl/evp.h>
-#endif
-#endif
-
-#include <stdio.h>
-
-#include "ip.h"
-#include "esp.h"
-#ifdef INET6
-#include "ip6.h"
-#endif
-
-#include "netdissect.h"
-#include "addrtoname.h"
-#include "extract.h"
-
-#ifndef HAVE_SOCKADDR_STORAGE
-#ifdef INET6
-struct sockaddr_storage {
- union {
- struct sockaddr_in sin;
- struct sockaddr_in6 sin6;
- } un;
-};
-#else
-#define sockaddr_storage sockaddr
-#endif
-#endif /* HAVE_SOCKADDR_STORAGE */
-
-#ifdef HAVE_LIBCRYPTO
-struct sa_list {
- struct sa_list *next;
- struct sockaddr_storage daddr;
- u_int32_t spi;
- const EVP_CIPHER *evp;
- int ivlen;
- int authlen;
- u_char secret[256]; /* is that big enough for all secrets? */
- int secretlen;
-};
-
-static void esp_print_addsa(netdissect_options *ndo,
- struct sa_list *sa, int sa_def)
-{
- /* copy the "sa" */
-
- struct sa_list *nsa;
-
- nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
- if (nsa == NULL)
- (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
-
- *nsa = *sa;
-
- if (sa_def)
- ndo->ndo_sa_default = nsa;
-
- nsa->next = ndo->ndo_sa_list_head;
- ndo->ndo_sa_list_head = nsa;
-}
-
-
-static u_int hexdigit(netdissect_options *ndo, char hex)
-{
- if (hex >= '0' && hex <= '9')
- return (hex - '0');
- else if (hex >= 'A' && hex <= 'F')
- return (hex - 'A' + 10);
- else if (hex >= 'a' && hex <= 'f')
- return (hex - 'a' + 10);
- else {
- (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
- return 0;
- }
-}
-
-static u_int hex2byte(netdissect_options *ndo, char *hexstring)
-{
- u_int byte;
-
- byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
- return byte;
-}
-
-/*
- * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret
- *
- * special form: file /name
- * causes us to go read from this file instead.
- *
- */
-static void esp_print_decode_onesecret(netdissect_options *ndo, char *line)
-{
- struct sa_list sa1;
- int sa_def;
-
- char *spikey;
- char *decode;
-
- spikey = strsep(&line, " \t");
- sa_def = 0;
- memset(&sa1, 0, sizeof(struct sa_list));
-
- /* if there is only one token, then it is an algo:key token */
- if (line == NULL) {
- decode = spikey;
- spikey = NULL;
- /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
- /* sa1.spi = 0; */
- sa_def = 1;
- } else
- decode = line;
-
- if (spikey && strcasecmp(spikey, "file") == 0) {
- /* open file and read it */
- FILE *secretfile;
- char fileline[1024];
- char *nl;
-
- secretfile = fopen(line, FOPEN_READ_TXT);
- if (secretfile == NULL) {
- perror(line);
- exit(3);
- }
-
- while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
- /* remove newline from the line */
- nl = strchr(fileline, '\n');
- if (nl)
- *nl = '\0';
- if (fileline[0] == '#') continue;
- if (fileline[0] == '\0') continue;
-
- esp_print_decode_onesecret(ndo, fileline);
- }
- fclose(secretfile);
-
- 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;
- if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) {
-#ifdef HAVE_SOCKADDR_SA_LEN
- sin6->sin6_len = sizeof(struct sockaddr_in6);
-#endif
- sin6->sin6_family = AF_INET6;
- } else
-#endif
- if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) {
-#ifdef HAVE_SOCKADDR_SA_LEN
- 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;
- }
- }
-
- 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);
- 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)
-{
- char *line;
- char *p;
-
- p = ndo->ndo_espsecret;
-
- while (ndo->ndo_espsecret && ndo->ndo_espsecret[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;
- }
-
- esp_print_decode_onesecret(ndo, line);
- }
-}
-
-static void esp_init(netdissect_options *ndo _U_)
-{
-
- OpenSSL_add_all_algorithms();
- EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
-}
-#endif
-
-int
-esp_print(netdissect_options *ndo,
- const u_char *bp, const int length, const u_char *bp2
-#ifndef HAVE_LIBCRYPTO
- _U_
-#endif
- ,
- int *nhdr
-#ifndef HAVE_LIBCRYPTO
- _U_
-#endif
- ,
- int *padlen
-#ifndef HAVE_LIBCRYPTO
- _U_
-#endif
- )
-{
- register const struct newesp *esp;
- register const u_char *ep;
-#ifdef HAVE_LIBCRYPTO
- struct ip *ip;
- struct sa_list *sa = NULL;
- int espsecret_keylen;
-#ifdef INET6
- struct ip6_hdr *ip6 = NULL;
-#endif
- int advance;
- int len;
- u_char *secret;
- int ivlen = 0;
- u_char *ivoff;
- u_char *p;
- EVP_CIPHER_CTX ctx;
- int blocksz;
- static int initialized = 0;
-#endif
-
- esp = (struct newesp *)bp;
-
-#ifdef HAVE_LIBCRYPTO
- secret = NULL;
- advance = 0;
-
- if (!initialized) {
- esp_init(ndo);
- initialized = 1;
- }
-#endif
-
-#if 0
- /* keep secret out of a register */
- p = (u_char *)&secret;
-#endif
-
- /* 'ep' points to the end of available data. */
- ep = ndo->ndo_snapend;
-
- if ((u_char *)(esp + 1) >= ep) {
- fputs("[|ESP]", stdout);
- goto fail;
- }
- (*ndo->ndo_printf)(ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi));
- (*ndo->ndo_printf)(ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq));
- (*ndo->ndo_printf)(ndo, ", length %u", length);
-
-#ifndef HAVE_LIBCRYPTO
- goto fail;
-#else
- /* initiailize SAs */
- if (ndo->ndo_sa_list_head == NULL) {
- if (!ndo->ndo_espsecret)
- goto fail;
-
- esp_print_decodesecret(ndo);
- }
-
- if (ndo->ndo_sa_list_head == NULL)
- goto fail;
-
- ip = (struct ip *)bp2;
- switch (IP_V(ip)) {
-#ifdef INET6
- case 6:
- ip6 = (struct ip6_hdr *)bp2;
- /* we do not attempt to decrypt jumbograms */
- if (!EXTRACT_16BITS(&ip6->ip6_plen))
- goto fail;
- /* if we can't get nexthdr, we do not need to decrypt it */
- len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
-
- /* see if we can find the SA, and if so, decode it */
- for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr;
- if (sa->spi == ntohl(esp->esp_spi) &&
- sin6->sin6_family == AF_INET6 &&
- memcmp(&sin6->sin6_addr, &ip6->ip6_dst,
- sizeof(struct in6_addr)) == 0) {
- break;
- }
- }
- break;
-#endif /*INET6*/
- case 4:
- /* nexthdr & padding are in the last fragment */
- if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
- goto fail;
- len = EXTRACT_16BITS(&ip->ip_len);
-
- /* see if we can find the SA, and if so, decode it */
- for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
- struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr;
- if (sa->spi == ntohl(esp->esp_spi) &&
- sin->sin_family == AF_INET &&
- sin->sin_addr.s_addr == ip->ip_dst.s_addr) {
- break;
- }
- }
- break;
- default:
- goto fail;
- }
-
- /* if we didn't find the specific one, then look for
- * an unspecified one.
- */
- if (sa == NULL)
- sa = ndo->ndo_sa_default;
-
- /* if not found fail */
- if (sa == NULL)
- goto fail;
-
- /* if we can't get nexthdr, we do not need to decrypt it */
- if (ep - bp2 < len)
- goto fail;
- if (ep - bp2 > len) {
- /* FCS included at end of frame (NetBSD 1.6 or later) */
- ep = bp2 + len;
- }
-
- ivoff = (u_char *)(esp + 1) + 0;
- ivlen = sa->ivlen;
- secret = sa->secret;
- espsecret_keylen = sa->secretlen;
- ep = ep - sa->authlen;
-
- if (sa->evp) {
- memset(&ctx, 0, sizeof(ctx));
- if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0)
- (*ndo->ndo_warning)(ndo, "espkey init failed");
-
- blocksz = EVP_CIPHER_CTX_block_size(&ctx);
-
- p = ivoff;
- EVP_CipherInit(&ctx, NULL, NULL, p, 0);
- EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen));
- advance = ivoff - (u_char *)esp + ivlen;
- } else
- advance = sizeof(struct newesp);
-
- /* sanity check for pad length */
- if (ep - bp < *(ep - 2))
- goto fail;
-
- if (padlen)
- *padlen = *(ep - 2) + 2;
-
- if (nhdr)
- *nhdr = *(ep - 1);
-
- (ndo->ndo_printf)(ndo, ": ");
- return advance;
-#endif
-
-fail:
- return -1;
-}
-
-/*
- * Local Variables:
- * c-style: whitesmith
- * c-basic-offset: 8
- * End:
- */
OpenPOWER on IntegriCloud