Change the IP address wrappers to include the version. Makes comparing
easier. Hard-coded some IPv6 localhost tests.
This commit is contained in:
parent
d1d2eb0edd
commit
a5bfb8a18b
139
src/sniffer.c
139
src/sniffer.c
@ -317,9 +317,12 @@ typedef struct NamedKey {
|
||||
#endif
|
||||
|
||||
|
||||
typedef union IpAddrInfo {
|
||||
word32 ip4;
|
||||
word32 ip6[4];
|
||||
typedef struct IpAddrInfo {
|
||||
int version;
|
||||
union {
|
||||
word32 ip4;
|
||||
byte ip6[16];
|
||||
};
|
||||
} IpAddrInfo;
|
||||
|
||||
|
||||
@ -328,7 +331,6 @@ typedef struct SnifferServer {
|
||||
SSL_CTX* ctx; /* SSL context */
|
||||
char address[MAX_SERVER_ADDRESS]; /* passed in server address */
|
||||
IpAddrInfo server; /* network order address */
|
||||
int version; /* IP version */
|
||||
int port; /* server port */
|
||||
#ifdef HAVE_SNI
|
||||
NamedKey* namedKeys; /* mapping of names and keys */
|
||||
@ -392,7 +394,6 @@ typedef struct SnifferSession {
|
||||
SSL* sslClient; /* SSL client side decode */
|
||||
IpAddrInfo server; /* server address in network byte order */
|
||||
IpAddrInfo client; /* client address in network byte order */
|
||||
int version;
|
||||
word16 srvPort; /* server port */
|
||||
word16 cliPort; /* client port */
|
||||
word32 cliSeqStart; /* client start sequence */
|
||||
@ -782,7 +783,6 @@ static void InitSession(SnifferSession* session)
|
||||
|
||||
/* IP Info from IP Header */
|
||||
typedef struct IpInfo {
|
||||
int version; /* IP version */
|
||||
int length; /* length of this header */
|
||||
int total; /* total length of fragment */
|
||||
IpAddrInfo src; /* network order source address */
|
||||
@ -855,8 +855,8 @@ typedef struct Ip6Hdr {
|
||||
word16 length; /* payload length */
|
||||
byte next_header; /* next header (6 for TCP, any other skip) */
|
||||
byte hl; /* hop limit */
|
||||
word32 src[4]; /* source address */
|
||||
word32 dst[4]; /* destination address */
|
||||
byte src[16]; /* source address */
|
||||
byte dst[16]; /* destination address */
|
||||
} Ip6Hdr;
|
||||
|
||||
|
||||
@ -960,12 +960,12 @@ static char* IpToS(word32 addr, char* str)
|
||||
|
||||
|
||||
/* Convert network byte order address into human readable */
|
||||
static char* Ip6ToS(word32* addr, char* str)
|
||||
static char* Ip6ToS(byte* addr, char* str)
|
||||
{
|
||||
byte* p = (byte*)addr;
|
||||
|
||||
/* Very incorrect. XXX */
|
||||
SNPRINTF(str, TRACE_MSG_SZ, "::%d", p[127]);
|
||||
SNPRINTF(str, TRACE_MSG_SZ, "::%d", p[15]);
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -989,7 +989,7 @@ static void TraceIP6(Ip6Hdr* iphdr)
|
||||
if (TraceOn) {
|
||||
char src[TRACE_MSG_SZ];
|
||||
char dst[TRACE_MSG_SZ];
|
||||
fprintf(TraceFile, "\tdst:%s src:%s\n", Ip6ToS(iphdr->dst, dst),
|
||||
fprintf(TraceFile, "\tdst: %s src: %s\n", Ip6ToS(iphdr->dst, dst),
|
||||
Ip6ToS(iphdr->src, src));
|
||||
}
|
||||
}
|
||||
@ -1166,6 +1166,19 @@ static void SetError(int idx, char* error, SnifferSession* session, int fatal)
|
||||
}
|
||||
|
||||
|
||||
/* Compare IpAddrInfo structs */
|
||||
static inline int MatchAddr(IpAddrInfo l, IpAddrInfo r)
|
||||
{
|
||||
if (l.version == r.version) {
|
||||
if (l.version == IPV4)
|
||||
return (l.ip4 == r.ip4);
|
||||
else if (l.version == IPV6)
|
||||
return (0 == XMEMCMP(l.ip6, r.ip6, sizeof(l.ip6)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef WOLFSSL_SNIFFER_WATCH
|
||||
|
||||
/* See if this IPV4 network order address has been registered */
|
||||
@ -1195,7 +1208,7 @@ static int IsServerRegistered(word32 addr)
|
||||
/* See if this port has been registered to watch */
|
||||
/* See if this IPV4 network order address has been registered */
|
||||
/* return 1 is true, 0 is false */
|
||||
static int IsServerRegistered6(word32* addr)
|
||||
static int IsServerRegistered6(byte* addr)
|
||||
{
|
||||
int ret = 0; /* false */
|
||||
SnifferServer* sniffer;
|
||||
@ -1204,7 +1217,8 @@ static int IsServerRegistered6(word32* addr)
|
||||
|
||||
sniffer = ServerList;
|
||||
while (sniffer) {
|
||||
if (XMEMCMP(sniffer->server.ip6, addr, sizeof(sniffer->server.ip6))) {
|
||||
if (sniffer->server.version == IPV6 &&
|
||||
0 == XMEMCMP(sniffer->server.ip6, addr, sizeof(sniffer->server.ip6))) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
@ -1254,24 +1268,12 @@ static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
|
||||
|
||||
#ifndef WOLFSSL_SNIFFER_WATCH
|
||||
while (sniffer) {
|
||||
if (ipInfo->version == IPV4) {
|
||||
if (sniffer->port == tcpInfo->srcPort &&
|
||||
sniffer->server.ip4 == ipInfo->src.ip4)
|
||||
break;
|
||||
if (sniffer->port == tcpInfo->dstPort &&
|
||||
sniffer->server.ip4 == ipInfo->dst.ip4)
|
||||
break;
|
||||
}
|
||||
else if (ipInfo->version == IPV6) {
|
||||
if (sniffer->port == tcpInfo->srcPort &&
|
||||
XMEMCMP(sniffer->server.ip6, ipInfo->src.ip6,
|
||||
sizeof(sniffer->server.ip6)) == 0)
|
||||
break;
|
||||
if (sniffer->port == tcpInfo->dstPort &&
|
||||
XMEMCMP(sniffer->server.ip6, ipInfo->dst.ip6,
|
||||
sizeof(sniffer->server.ip6)) == 0)
|
||||
break;
|
||||
}
|
||||
if (sniffer->port == tcpInfo->srcPort &&
|
||||
MatchAddr(sniffer->server, ipInfo->src))
|
||||
break;
|
||||
if (sniffer->port == tcpInfo->dstPort &&
|
||||
MatchAddr(sniffer->server, ipInfo->dst))
|
||||
break;
|
||||
|
||||
sniffer = sniffer->next;
|
||||
}
|
||||
@ -1291,17 +1293,18 @@ static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
|
||||
{
|
||||
word32 hash = 1;
|
||||
|
||||
if (ipInfo->version == IPV4) {
|
||||
if (ipInfo->src.version == IPV4) {
|
||||
hash *= ipInfo->src.ip4 * ipInfo->dst.ip4;
|
||||
}
|
||||
else if (ipInfo->version == IPV6) {
|
||||
word32 x;
|
||||
x = ipInfo->src.ip6[0] ^ ipInfo->src.ip6[1] ^
|
||||
ipInfo->src.ip6[2] ^ ipInfo->src.ip6[3];
|
||||
hash *= x;
|
||||
x = ipInfo->dst.ip6[0] ^ ipInfo->dst.ip6[1] ^
|
||||
ipInfo->dst.ip6[2] ^ ipInfo->dst.ip6[3];
|
||||
hash *= x;
|
||||
else if (ipInfo->src.version == IPV6) {
|
||||
word32* x;
|
||||
word32 y;
|
||||
x = (word32*)ipInfo->src.ip6;
|
||||
y = x[0] ^ x[1] ^ x[2] ^ x[3];
|
||||
hash *= y;
|
||||
x = (word32*)ipInfo->dst.ip6;
|
||||
y = x[0] ^ x[1] ^ x[2] ^ x[3];
|
||||
hash *= y;
|
||||
}
|
||||
hash *= tcpInfo->srcPort * tcpInfo->dstPort;
|
||||
|
||||
@ -1309,15 +1312,6 @@ static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
|
||||
}
|
||||
|
||||
|
||||
static inline int MatchAddr(int version, IpAddrInfo l, IpAddrInfo r)
|
||||
{
|
||||
if (version == IPV4)
|
||||
return (l.ip4 == r.ip4);
|
||||
else
|
||||
return (0 == XMEMCMP(l.ip6, r.ip6, sizeof(l.ip6)));
|
||||
}
|
||||
|
||||
|
||||
/* Get Exisiting SnifferSession from IP and Port */
|
||||
static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
|
||||
{
|
||||
@ -1331,14 +1325,14 @@ static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
|
||||
|
||||
session = SessionTable[row];
|
||||
while (session) {
|
||||
if (MatchAddr(session->version, session->server, ipInfo->src) &&
|
||||
MatchAddr(session->version, session->client, ipInfo->dst) &&
|
||||
if (MatchAddr(session->server, ipInfo->src) &&
|
||||
MatchAddr(session->client, ipInfo->dst) &&
|
||||
session->srvPort == tcpInfo->srcPort &&
|
||||
session->cliPort == tcpInfo->dstPort)
|
||||
break;
|
||||
|
||||
if (MatchAddr(session->version, session->client, ipInfo->src) &&
|
||||
MatchAddr(session->version, session->server, ipInfo->dst) &&
|
||||
if (MatchAddr(session->client, ipInfo->src) &&
|
||||
MatchAddr(session->server, ipInfo->dst) &&
|
||||
session->cliPort == tcpInfo->srcPort &&
|
||||
session->srvPort == tcpInfo->dstPort)
|
||||
break;
|
||||
@ -1353,7 +1347,7 @@ static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
|
||||
|
||||
/* determine side */
|
||||
if (session) {
|
||||
if (MatchAddr(ipInfo->version, ipInfo->dst, session->server) &&
|
||||
if (MatchAddr(ipInfo->dst, session->server) &&
|
||||
tcpInfo->dstPort == session->srvPort) {
|
||||
|
||||
session->flags.side = WOLFSSL_SERVER_END;
|
||||
@ -1451,7 +1445,8 @@ static int CreateWatchSnifferServer(char* error)
|
||||
{
|
||||
SnifferServer* sniffer;
|
||||
|
||||
sniffer = (SnifferServer*)XMALLOC(sizeof(SnifferServer), NULL, DYNAMIC_TYPE_SNIFFER_SERVER);
|
||||
sniffer = (SnifferServer*)XMALLOC(sizeof(SnifferServer), NULL,
|
||||
DYNAMIC_TYPE_SNIFFER_SERVER);
|
||||
if (sniffer == NULL) {
|
||||
SetError(MEMORY_STR, error, NULL, 0);
|
||||
return -1;
|
||||
@ -1482,7 +1477,7 @@ static int SetNamedPrivateKey(const char* name, const char* address, int port,
|
||||
int type = (typeKey == FILETYPE_PEM) ? WOLFSSL_FILETYPE_PEM :
|
||||
WOLFSSL_FILETYPE_ASN1;
|
||||
int isNew = 0;
|
||||
word32 serverIp;
|
||||
IpAddrInfo serverIp;
|
||||
|
||||
#ifdef HAVE_SNI
|
||||
NamedKey* namedKey = NULL;
|
||||
@ -1515,10 +1510,18 @@ static int SetNamedPrivateKey(const char* name, const char* address, int port,
|
||||
}
|
||||
#endif
|
||||
|
||||
serverIp = inet_addr(address);
|
||||
serverIp.version = IPV4;
|
||||
serverIp.ip4 = inet_addr(address);
|
||||
if (serverIp.ip4 == INADDR_NONE) {
|
||||
if (inet_pton(AF_INET6, address, serverIp.ip6) == 1) {
|
||||
serverIp.version = IPV6;
|
||||
serverIp.ip6[0] = 0;
|
||||
serverIp.ip6[1] = 0;
|
||||
}
|
||||
}
|
||||
sniffer = ServerList;
|
||||
while (sniffer != NULL &&
|
||||
(sniffer->server.ip4 != serverIp || sniffer->port != port)) {
|
||||
(!MatchAddr(sniffer->server, serverIp) || sniffer->port != port)) {
|
||||
sniffer = sniffer->next;
|
||||
}
|
||||
|
||||
@ -1537,7 +1540,7 @@ static int SetNamedPrivateKey(const char* name, const char* address, int port,
|
||||
|
||||
XSTRNCPY(sniffer->address, address, MAX_SERVER_ADDRESS-1);
|
||||
sniffer->address[MAX_SERVER_ADDRESS-1] = '\0';
|
||||
sniffer->server.ip4 = serverIp;
|
||||
sniffer->server = serverIp;
|
||||
sniffer->port = port;
|
||||
|
||||
sniffer->ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||
@ -1665,10 +1668,13 @@ static int CheckIp6Hdr(Ip6Hdr* iphdr, IpInfo* info, int length, char* error)
|
||||
}
|
||||
#endif
|
||||
|
||||
info->total = ntohs(iphdr->length);
|
||||
info->version = IPV6;
|
||||
info->length = 40;
|
||||
info->total = ntohs(iphdr->length) + info->length;
|
||||
/* IPv6 doesn't include its own header size in the length like v4. */
|
||||
info->src.version = IPV6;
|
||||
XMEMCPY(info->src.ip6, iphdr->src, sizeof(info->src.ip6));
|
||||
XMEMCPY(info->dst.ip6, iphdr->src, sizeof(info->dst.ip6));
|
||||
info->dst.version = IPV6;
|
||||
XMEMCPY(info->dst.ip6, iphdr->dst, sizeof(info->dst.ip6));
|
||||
|
||||
/* This needs to massage the length and size to match what the sniffer
|
||||
* expects. IPv4 and IPv6 treat the length parameter differently. */
|
||||
@ -1686,12 +1692,12 @@ static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
|
||||
{
|
||||
int version = IP_V(iphdr);
|
||||
|
||||
TraceIP(iphdr);
|
||||
Trace(IP_CHECK_STR);
|
||||
|
||||
if (version == IPV6)
|
||||
return CheckIp6Hdr((Ip6Hdr*)iphdr, info, length, error);
|
||||
|
||||
TraceIP(iphdr);
|
||||
Trace(IP_CHECK_STR);
|
||||
|
||||
if (version != IPV4) {
|
||||
SetError(BAD_IPVER_STR, error, NULL, 0);
|
||||
return -1;
|
||||
@ -1711,8 +1717,9 @@ static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
|
||||
|
||||
info->length = IP_HL(iphdr);
|
||||
info->total = ntohs(iphdr->length);
|
||||
info->version = IPV4;
|
||||
info->src.version = IPV4;
|
||||
info->src.ip4 = iphdr->src;
|
||||
info->dst.version = IPV4;
|
||||
info->dst.ip4 = iphdr->dst;
|
||||
|
||||
if (info->total == 0)
|
||||
|
@ -184,7 +184,23 @@ static char* iptos(unsigned int addr)
|
||||
static char output[32];
|
||||
byte *p = (byte*)&addr;
|
||||
|
||||
SNPRINTF(output, sizeof(output), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
snprintf(output, sizeof(output), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
static char* ip6tos(const unsigned char* addr)
|
||||
{
|
||||
static char output[42];
|
||||
|
||||
snprintf(output, sizeof(output),
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x",
|
||||
addr[0], addr[1], addr[2], addr[3],
|
||||
addr[4], addr[5], addr[6], addr[7],
|
||||
addr[8], addr[9], addr[10], addr[11],
|
||||
addr[12], addr[13], addr[14], addr[15]);
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -347,22 +363,21 @@ int main(int argc, char** argv)
|
||||
|
||||
if (pcap == NULL) printf("pcap_create failed %s\n", err);
|
||||
|
||||
/* get an IPv4 address */
|
||||
/* get an IPv4 or IPv6 address */
|
||||
for (a = d->addresses; a; a = a->next) {
|
||||
switch(a->addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
server =
|
||||
iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);
|
||||
printf("server = %s\n", server);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (a->addr->sa_family == AF_INET)
|
||||
server =
|
||||
iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);
|
||||
else if (a->addr->sa_family == AF_INET6)
|
||||
server =
|
||||
ip6tos(((struct sockaddr_in6 *)a->addr)->sin6_addr.s6_addr);
|
||||
else
|
||||
server = NULL;
|
||||
}
|
||||
if (server == NULL)
|
||||
err_sys("Unable to get device IPv4 address");
|
||||
err_sys("Unable to get device IPv4 or IPv6 address");
|
||||
else
|
||||
printf("server = %s\n", server);
|
||||
|
||||
ret = pcap_set_snaplen(pcap, 65536);
|
||||
if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
|
||||
@ -395,6 +410,7 @@ int main(int argc, char** argv)
|
||||
if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
|
||||
|
||||
#ifndef WOLFSSL_SNIFFER_WATCH
|
||||
server = "::1";
|
||||
ret = ssl_SetPrivateKey(server, port, "../../certs/server-key.pem",
|
||||
FILETYPE_PEM, NULL, err);
|
||||
if (ret != 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user