Package: knockd Version: 0.5-3 Severity: normal Tags: ipv6 patch I would like to offer an initial patch to enable server and client to use IPv6 in addition to IPv4. It has been tested with SYN-knocking so far.
Neither manual page have has amended. For backwards compatibility one could consider to have the client use IPv4 by default, instead of the present code that lets the resolver decide which family to prefer. Best regards, Mats Erik Andersson, DM
diff -Naur knockd-0.5.orig/Makefile.in knockd-0.5/Makefile.in
--- knockd-0.5.orig/Makefile.in 2005-06-27 07:11:34.000000000 +0200
+++ knockd-0.5/Makefile.in 2011-03-05 23:28:24.177144829 +0100
@@ -41,7 +41,7 @@
CXX = @CC@
CXXFLAGS += @CFLAGS@ -g -Wall -pedantic -fno-exceptions \
- -D_GNU_SOURCE -I.
+ -fno-strict-aliasing -D_GNU_SOURCE -I.
LDFLAGS += @LDFLAGS@
SRCS = $(SRCDIR)knockd.c \
diff -Naur knockd-0.5.orig/src/knock.c knockd-0.5/src/knock.c
--- knockd-0.5.orig/src/knock.c 2005-06-27 07:11:34.000000000 +0200
+++ knockd-0.5/src/knock.c 2011-03-05 23:51:00.247215485 +0100
@@ -44,13 +44,16 @@
int o_verbose = 0;
int o_udp = 0;
+int o_family = AF_UNSPEC;
int main(int argc, char** argv)
{
int sd;
- struct hostent* host;
- struct sockaddr_in addr;
- int opt, optidx = 1;
+ struct sockaddr_storage addr;
+ char hostaddr[INET6_ADDRSTRLEN];
+ socklen_t addrlen = 0;
+ struct addrinfo hints, * res, * ai;
+ int opt, optidx = 1, err;
static struct option opts[] =
{
{"verbose", no_argument, 0, 'v'},
@@ -60,12 +63,14 @@
{0, 0, 0, 0}
};
- while((opt = getopt_long(argc, argv, "vuhV", opts, &optidx))) {
+ while((opt = getopt_long(argc, argv, "46vuhV", opts, &optidx))) {
if(opt < 0) {
break;
}
switch(opt) {
case 0: break;
+ case '4': o_family = AF_INET; break;
+ case '6': o_family = AF_INET6; break;
case 'v': o_verbose = 1; break;
case 'u': o_udp = 1; break;
case 'V': ver();
@@ -77,11 +82,40 @@
usage();
}
- host = gethostbyname(argv[optind++]);
- if(host == NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = o_family;
+ hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
+ err = getaddrinfo(argv[optind++], NULL, &hints, &res);
+ if (err) {
fprintf(stderr, "Cannot resolve hostname\n");
exit(1);
}
+ for (ai = res; ai; ai = ai->ai_next) {
+ sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (sd < 0)
+ continue;
+ if ( ((o_family != AF_UNSPEC) && (ai->ai_family != o_family))
+ || !(ai->ai_family == AF_INET || ai->ai_family == AF_INET6)) {
+ close(sd);
+ sd = -1;
+ continue;
+ }
+ /* This address is good enough. */
+ addrlen = ai->ai_addrlen;
+ memcpy(&addr, ai->ai_addr, ai->ai_addrlen);
+ break;
+ }
+ if (res)
+ freeaddrinfo(res);
+ if (ai == NULL) {
+ fprintf(stderr, "Cannot use %s with host \"%s\".\n",
+ (o_family == AF_UNSPEC) ? "IPv4/IPv6"
+ : (o_family == AF_INET) ? "IPv4" : "IPv6", argv[optind -1]);
+ exit(1);
+ }
+ getnameinfo((struct sockaddr *) &addr, addrlen,
+ hostaddr, sizeof(hostaddr), NULL, 0, NI_NUMERICHOST);
+
for(; optind < argc; optind++) {
unsigned short port, proto = PROTO_TCP;
char *ptr, *arg = strdup(argv[optind]);
@@ -100,14 +134,14 @@
}
if(o_udp || proto == PROTO_UDP) {
- sd = socket(PF_INET, SOCK_DGRAM, 0);
+ sd = socket(addr.ss_family, SOCK_DGRAM, 0);
if(sd == -1) {
fprintf(stderr, "Cannot open socket\n");
exit(1);
}
} else {
int flags;
- sd = socket(PF_INET, SOCK_STREAM, 0);
+ sd = socket(addr.ss_family, SOCK_STREAM, 0);
if(sd == -1) {
fprintf(stderr, "Cannot open socket\n");
exit(1);
@@ -115,17 +149,22 @@
flags = fcntl(sd, F_GETFL, 0);
fcntl(sd, F_SETFL, flags | O_NONBLOCK);
}
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = *((long*)host->h_addr_list[0]);
- addr.sin_port = htons(port);
+ switch (addr.ss_family) {
+ case AF_INET6:
+ ((struct sockaddr_in6 *) &addr)->sin6_port = htons(port);
+ break;
+ case AF_INET:
+ default:
+ ((struct sockaddr_in *) &addr)->sin_port = htons(port);
+ }
+
if(o_udp || proto == PROTO_UDP) {
- vprint("hitting udp %s:%u\n", inet_ntoa(addr.sin_addr), port);
- connect(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr));
+ vprint("hitting udp %s:%u\n", hostaddr, port);
+ connect(sd, (struct sockaddr*)&addr, addrlen);
send(sd, NULL, 0, MSG_DONTWAIT);
} else {
- vprint("hitting tcp %s:%u\n", inet_ntoa(addr.sin_addr), port);
- connect(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr));
+ vprint("hitting tcp %s:%u\n", hostaddr, port);
+ connect(sd, (struct sockaddr*)&addr, addrlen);
}
close(sd);
}
diff -Naur knockd-0.5.orig/src/knockd.c knockd-0.5/src/knockd.c
--- knockd-0.5.orig/src/knockd.c 2005-06-27 07:11:34.000000000 +0200
+++ knockd-0.5/src/knockd.c 2011-03-08 14:22:25.294603947 +0100
@@ -31,10 +31,12 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <net/if.h>
+#include <ifaddrs.h>
#include <bits/time.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -46,6 +48,7 @@
#include <syslog.h>
#include <pcap.h>
#include <errno.h>
+#include <limits.h> /* PATH_MAX */
#include "list.h"
static char version[] = "0.5";
@@ -87,7 +90,7 @@
typedef struct knocker {
opendoor_t *door;
short stage;
- char src[16]; /* IP address */
+ char src[INET6_ADDRSTRLEN]; /* IP address */
char *srchost; /* Hostname */
time_t seq_start;
} knocker_t;
@@ -115,7 +118,7 @@
void generate_pcap_filter();
size_t realloc_strcat(char **dest, const char *src, size_t size);
void close_door(opendoor_t *door);
-char* get_ip(const char* iface, char *buf, int bufsize);
+char* get_ip(const char* iface, char *buf, int bufsize, char *buf6, int buf6size);
size_t parse_cmd(char* dest, size_t size, const char* command, const char* src);
int exec_cmd(char* command, char* name);
void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet);
@@ -123,7 +126,10 @@
pcap_t *cap = NULL;
FILE *logfd = NULL;
int lltype = -1;
-char myip[32];
+char myip[INET_ADDRSTRLEN];
+char myip6[INET6_ADDRSTRLEN];
+struct in_addr my_inaddr;
+struct in6_addr my_in6addr;
int o_usesyslog = 0;
int o_verbose = 0;
@@ -219,11 +225,11 @@
}
/* get our local IP address */
- if(get_ip(o_int, myip, 32) == NULL) {
+ if(get_ip(o_int, myip, sizeof(myip), myip6, sizeof(myip6)) == NULL) {
fprintf(stderr, "could not get IP address for %s\n", o_int);
cleanup(1);
} else {
- dprint("Local IP: %s\n", myip);
+ dprint("Local IP: %s, IPv6: %s\n", myip, myip6);
}
generate_pcap_filter();
@@ -836,58 +842,100 @@
/* append the TCP flag filters */
if(tcp_present) {
if(door->flag_fin != DONT_CARE) {
- bufsize = realloc_strcat(&buffer, " and tcp[tcpflags] & tcp-fin ", bufsize);
+ bufsize = realloc_strcat(&buffer, " and (tcp[tcpflags] & tcp-fin ", bufsize);
if(door->flag_fin == SET) {
bufsize = realloc_strcat(&buffer, "!= 0", bufsize);
}
if(door->flag_fin == NOT_SET) {
bufsize = realloc_strcat(&buffer, "== 0", bufsize);
}
+ bufsize = realloc_strcat(&buffer, " or ip6[77] & tcp-fin ", bufsize);
+ if(door->flag_syn == SET) {
+ bufsize = realloc_strcat(&buffer, "!= 0)", bufsize);
+ }
+ if(door->flag_syn == NOT_SET) {
+ bufsize = realloc_strcat(&buffer, "== 0)", bufsize);
+ }
}
if(door->flag_syn != DONT_CARE) {
- bufsize = realloc_strcat(&buffer, " and tcp[tcpflags] & tcp-syn ", bufsize);
+ bufsize = realloc_strcat(&buffer, " and (tcp[tcpflags] & tcp-syn ", bufsize);
if(door->flag_syn == SET) {
bufsize = realloc_strcat(&buffer, "!= 0", bufsize);
}
if(door->flag_syn == NOT_SET) {
bufsize = realloc_strcat(&buffer, "== 0", bufsize);
}
+ bufsize = realloc_strcat(&buffer, " or ip6[77] & tcp-syn ", bufsize);
+ if(door->flag_syn == SET) {
+ bufsize = realloc_strcat(&buffer, "!= 0)", bufsize);
+ }
+ if(door->flag_syn == NOT_SET) {
+ bufsize = realloc_strcat(&buffer, "== 0)", bufsize);
+ }
}
if(door->flag_rst != DONT_CARE) {
- bufsize = realloc_strcat(&buffer, " and tcp[tcpflags] & tcp-rst ", bufsize);
+ bufsize = realloc_strcat(&buffer, " and (tcp[tcpflags] & tcp-rst ", bufsize);
if(door->flag_rst == SET) {
bufsize = realloc_strcat(&buffer, "!= 0", bufsize);
}
if(door->flag_rst == NOT_SET) {
bufsize = realloc_strcat(&buffer, "== 0", bufsize);
}
+ bufsize = realloc_strcat(&buffer, " or ip6[77] & tcp-rst ", bufsize);
+ if(door->flag_syn == SET) {
+ bufsize = realloc_strcat(&buffer, "!= 0)", bufsize);
+ }
+ if(door->flag_syn == NOT_SET) {
+ bufsize = realloc_strcat(&buffer, "== 0)", bufsize);
+ }
}
if(door->flag_psh != DONT_CARE) {
- bufsize = realloc_strcat(&buffer, " and tcp[tcpflags] & tcp-psh ", bufsize);
+ bufsize = realloc_strcat(&buffer, " and (tcp[tcpflags] & tcp-psh ", bufsize);
if(door->flag_psh == SET) {
bufsize = realloc_strcat(&buffer, "!= 0", bufsize);
}
if(door->flag_psh == NOT_SET) {
bufsize = realloc_strcat(&buffer, "== 0", bufsize);
}
+ bufsize = realloc_strcat(&buffer, " or ip6[77] & tcp-psh ", bufsize);
+ if(door->flag_syn == SET) {
+ bufsize = realloc_strcat(&buffer, "!= 0)", bufsize);
+ }
+ if(door->flag_syn == NOT_SET) {
+ bufsize = realloc_strcat(&buffer, "== 0)", bufsize);
+ }
}
if(door->flag_ack != DONT_CARE) {
- bufsize = realloc_strcat(&buffer, " and tcp[tcpflags] & tcp-ack ", bufsize);
+ bufsize = realloc_strcat(&buffer, " and (tcp[tcpflags] & tcp-ack ", bufsize);
if(door->flag_ack == SET) {
bufsize = realloc_strcat(&buffer, "!= 0", bufsize);
}
if(door->flag_ack == NOT_SET) {
bufsize = realloc_strcat(&buffer, "== 0", bufsize);
}
+ bufsize = realloc_strcat(&buffer, " or ip6[77] & tcp-ack ", bufsize);
+ if(door->flag_syn == SET) {
+ bufsize = realloc_strcat(&buffer, "!= 0)", bufsize);
+ }
+ if(door->flag_syn == NOT_SET) {
+ bufsize = realloc_strcat(&buffer, "== 0)", bufsize);
+ }
}
if(door->flag_urg != DONT_CARE) {
- bufsize = realloc_strcat(&buffer, " and tcp[tcpflags] & tcp-urg ", bufsize);
+ bufsize = realloc_strcat(&buffer, " and (tcp[tcpflags] & tcp-urg ", bufsize);
if(door->flag_urg == SET) {
bufsize = realloc_strcat(&buffer, "!= 0", bufsize);
}
if(door->flag_urg == NOT_SET) {
bufsize = realloc_strcat(&buffer, "== 0", bufsize);
}
+ bufsize = realloc_strcat(&buffer, " or ip6[77] & tcp-urg ", bufsize);
+ if(door->flag_syn == SET) {
+ bufsize = realloc_strcat(&buffer, "!= 0)", bufsize);
+ }
+ if(door->flag_syn == NOT_SET) {
+ bufsize = realloc_strcat(&buffer, "== 0)", bufsize);
+ }
}
bufsize = realloc_strcat(&buffer, ")", bufsize); /* close parentheses of flags */
}
@@ -949,8 +997,18 @@
* )
*/
if(modified_filters) {
- bufsize = realloc_strcat(&buffer, "dst host ", bufsize); /* accept only incoming packets */
- bufsize = realloc_strcat(&buffer, myip, bufsize);
+ bufsize = realloc_strcat(&buffer, "(", bufsize);
+ if (myip[0]) {
+ bufsize = realloc_strcat(&buffer, "dst host ", bufsize); /* accept only incoming packets */
+ bufsize = realloc_strcat(&buffer, myip, bufsize);
+ }
+ if (myip[0] && myip6[0])
+ bufsize = realloc_strcat(&buffer, " or ", bufsize);
+ if (myip6[0]) {
+ bufsize = realloc_strcat(&buffer, "dst host ", bufsize); /* accept only incoming packets */
+ bufsize = realloc_strcat(&buffer, myip6, bufsize);
+ }
+ bufsize = realloc_strcat(&buffer, ") ", bufsize);
bufsize = realloc_strcat(&buffer, " and (", bufsize);
/* iterate over all doors */
for(lp = doors; lp; lp = lp->next) {
@@ -969,6 +1027,7 @@
cleanup(1);
}
+ dprint("Pcap filter: %s\n", buffer);
if(pcap_compile(cap, &bpf_prog, buffer, 1, 0) < 0) { /* optimize filter (1), no netmask (0) (we're not interested in broadcasts) */
pcap_perror(cap, "pcap");
cleanup(1);
@@ -1046,36 +1105,74 @@
/* Get the IP address of an interface
*/
-char* get_ip(const char* iface, char *buf, int bufsize)
+char* get_ip(const char* iface, char *buf, int bufsize, char *buf6, int buf6size)
{
- int s;
- struct ifreq ifr;
+ struct ifaddrs *ifaddr, *ifa;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
- if(bufsize <= 0) {
+ if(buf == NULL && buf6 == NULL) {
return(NULL);
}
- if(buf == NULL) {
+ if( (buf && (bufsize <= 0)) || (buf6 && (buf6size <= 0)) ) {
return(NULL);
}
- buf[0] = '\0';
+ if (buf)
+ buf[0] = '\0';
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if(s < 0) {
- return(NULL);
- }
+ if (buf6)
+ buf6[0] = '\0';
- bzero((void*)(&ifr.ifr_name), sizeof(ifr.ifr_name));
- strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)-1);
- ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
- if(ioctl(s, SIOCGIFADDR, &ifr)) {
- close(s);
- return(NULL);
+ if (getifaddrs(&ifaddr) < 0)
+ return NULL;
+
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ if ( (buf && (ifa->ifa_addr->sa_family != AF_INET))
+ && (buf6 && (ifa->ifa_addr->sa_family != AF_INET6)) )
+ continue;
+
+ if (strcmp(ifa->ifa_name, iface))
+ continue;
+
+ sin = (struct sockaddr_in *) ifa->ifa_addr;
+ sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
+
+ /* Ignore site-local and link-local IPv6 addresses. */
+ if ((ifa->ifa_addr->sa_family == AF_INET6)
+ && (IN6_IS_ADDR_SITELOCAL(sin6->sin6_addr.s6_addr)
+ || IN6_IS_ADDR_LINKLOCAL(sin6->sin6_addr.s6_addr)) )
+ continue;
+
+ /* Extract IPv4 if so desired. */
+ if (buf && (ifa->ifa_addr->sa_family == AF_INET)) {
+ memcpy(&my_inaddr, &sin->sin_addr, sizeof(my_inaddr));
+ getnameinfo((struct sockaddr *) sin, sizeof(*sin), buf, bufsize,
+ NULL, 0, NI_NUMERICHOST);
+ continue;
+ }
+
+ /* Extract IPv6 if so desired. */
+ if (buf6 && (ifa->ifa_addr->sa_family == AF_INET6)) {
+ memcpy(&my_in6addr, &sin6->sin6_addr, sizeof(my_in6addr));
+ getnameinfo((struct sockaddr *) sin6, sizeof(*sin6), buf6, buf6size,
+ NULL, 0, NI_NUMERICHOST);
+ continue;
+ }
}
- close(s);
+ if (ifaddr)
+ freeifaddrs(ifaddr);
- strncpy(buf, inet_ntoa((*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr), bufsize-1);
- buf[bufsize-1] = '\0';
- return(buf);
+ /* Did all required information fail? Then we fail. */
+ if ( (buf && (buf[0] == '\0')) && (buf6 && (buf6[0] == '\0')) )
+ return NULL;
+
+ /* Return IPv4 as preferred result. */
+ if (buf && (buf[0] != '\0'))
+ return buf;
+ else if (buf6 && (buf6[0] == '\0'))
+ return buf6;
+ else
+ return NULL; /* Should not happen. */
}
/* Parse a command line, replacing tokens (eg, %IP%) with their real values and
@@ -1163,13 +1260,16 @@
/* packet structs */
struct ethhdr* eth = NULL;
struct iphdr* ip = NULL;
+ struct ip6_hdr* ip6 = NULL;
struct tcphdr* tcp = NULL;
struct udphdr* udp = NULL;
char proto[8];
/* TCP/IP data */
struct in_addr inaddr;
+ struct in6_addr in6addr;
unsigned short sport, dport;
- char srcIP[16], dstIP[16];
+ char srcIP[INET6_ADDRSTRLEN], dstIP[INET6_ADDRSTRLEN];
+ int vers;
/* timestamp */
time_t pkt_secs = hdr->ts.tv_sec;
struct tm* pkt_tm;
@@ -1180,50 +1280,71 @@
if(lltype == DLT_EN10MB) {
eth = (struct ethhdr*)packet;
- if(ntohs(eth->h_proto) != ETH_P_IP) {
+ if(ntohs(eth->h_proto) != ETH_P_IP && ntohs(eth->h_proto) != ETH_P_IPV6) {
return;
}
ip = (struct iphdr*)(packet + sizeof(struct ethhdr));
+ ip6 = (struct ip6_hdr*)(packet + sizeof(struct ethhdr));
} else if(lltype == DLT_LINUX_SLL) {
ip = (struct iphdr*)((u_char*)packet + 16);
} else if(lltype == DLT_RAW) {
ip = (struct iphdr*)((u_char*)packet);
}
-
- if(ip->version != 4) {
- /* no IPv6 yet */
- dprint("packet is not IPv4, ignoring...\n");
+
+ vers = ip->version;
+
+ if((vers == 4 &&ip->protocol == IPPROTO_ICMP)
+ || (vers == 6 && ip6->ip6_nxt == IPPROTO_ICMPV6)) {
+ /* we don't do ICMP */
return;
}
- if(ip->protocol == IPPROTO_ICMP) {
- /* we don't do ICMP */
+
+ /* Is the relevant address family active? */
+ if( !(vers == 4 && myip[0]) && !(vers == 6 && myip6[0]) ) {
+ /* no IPv6 yet */
+ dprint("packet is not relevant for %s, ignoring...\n", o_int);
return;
}
+ sport = dport = 0;
+
/* make sure this packet was sent TO us, not FROM us or THROUGH us.
* Actually the pcap filter will take care of forwarding only packets
* destined for us, but another check won't hurt... */
- if(inet_aton(myip, &inaddr) == 0) {
- fprintf(stderr, "error: could not understand IP address: %s\n", myip);
- return;
- }
- if(ip->daddr != inaddr.s_addr) {
- dprint("packet destined for another host, ignoring...\n");
- return;
- }
-
- sport = dport = 0;
- if(ip->protocol == IPPROTO_TCP) {
- strncpy(proto, "tcp", sizeof(proto));
- tcp = (struct tcphdr*)((u_char*)ip + (ip->ihl * 4));
- sport = ntohs(tcp->source);
- dport = ntohs(tcp->dest);
- }
- if(ip->protocol == IPPROTO_UDP) {
- strncpy(proto, "udp", sizeof(proto));
- udp = (struct udphdr*)((u_char*)ip + (ip->ihl * 4));
- sport = ntohs(udp->source);
- dport = ntohs(udp->dest);
+ if (vers == 4) {
+ if (ip->daddr != my_inaddr.s_addr) {
+ dprint("packet destined for another host, ignoring...\n");
+ return;
+ }
+ if(ip->protocol == IPPROTO_TCP) {
+ strncpy(proto, "tcp", sizeof(proto));
+ tcp = (struct tcphdr*)((u_char*)ip + (ip->ihl * 4));
+ sport = ntohs(tcp->source);
+ dport = ntohs(tcp->dest);
+ }
+ if(ip->protocol == IPPROTO_UDP) {
+ strncpy(proto, "udp", sizeof(proto));
+ udp = (struct udphdr*)((u_char*)ip + (ip->ihl * 4));
+ sport = ntohs(udp->source);
+ dport = ntohs(udp->dest);
+ }
+ } else {
+ if (memcmp(&ip6->ip6_dst, &my_in6addr, sizeof(ip6->ip6_dst))) {
+ dprint("packet destined for another host, ignoring...\n");
+ return;
+ }
+ if(ip6->ip6_nxt == IPPROTO_TCP) {
+ strncpy(proto, "tcp", sizeof(proto));
+ tcp = (struct tcphdr*)((u_char*)ip6 + sizeof(struct ip6_hdr));
+ sport = ntohs(tcp->source);
+ dport = ntohs(tcp->dest);
+ }
+ if(ip6->ip6_nxt == IPPROTO_UDP) {
+ strncpy(proto, "udp", sizeof(proto));
+ udp = (struct udphdr*)((u_char*)ip6 + sizeof(struct ip6_hdr));
+ sport = ntohs(udp->source);
+ dport = ntohs(udp->dest);
+ }
}
/* get the date/time */
@@ -1234,12 +1355,21 @@
pkt_tm->tm_sec);
/* convert IPs from binary to string */
- inaddr.s_addr = ip->saddr;
- strncpy(srcIP, inet_ntoa(inaddr), sizeof(srcIP)-1);
- srcIP[sizeof(srcIP)-1] = '\0';
- inaddr.s_addr = ip->daddr;
- strncpy(dstIP, inet_ntoa(inaddr), sizeof(dstIP)-1);
- dstIP[sizeof(dstIP)-1] = '\0';
+ if (vers == 4) {
+ inaddr.s_addr = ip->saddr;
+ inet_ntop(AF_INET, &inaddr, srcIP, sizeof(srcIP));
+ srcIP[sizeof(srcIP)-1] = '\0';
+ inaddr.s_addr = ip->daddr;
+ inet_ntop(AF_INET, &inaddr, dstIP, sizeof(dstIP));
+ dstIP[sizeof(dstIP)-1] = '\0';
+ } else {
+ memcpy(&in6addr, &ip6->ip6_src, sizeof(in6addr));
+ inet_ntop(AF_INET6, &in6addr, srcIP, sizeof(srcIP));
+ srcIP[sizeof(srcIP)-1] = '\0';
+ memcpy(&in6addr, &ip6->ip6_dst, sizeof(in6addr));
+ inet_ntop(AF_INET6, &in6addr, dstIP, sizeof(dstIP));
+ dstIP[sizeof(dstIP)-1] = '\0';
+ }
dprint("%s %s: %s: %s:%d -> %s:%d %d bytes\n", pkt_date, pkt_time,
proto, srcIP, sport, dstIP, dport, hdr->len);
@@ -1297,7 +1427,8 @@
/* if tcp, check the flags to ignore the packets we don't want
* (don't even use it to cancel sequences)
*/
- if(ip->protocol == IPPROTO_TCP) {
+ if((vers == 4 && ip->protocol == IPPROTO_TCP)
+ || (vers == 6 && ip6->ip6_nxt == IPPROTO_TCP)) {
if(attempt->door->flag_fin != DONT_CARE) {
if(attempt->door->flag_fin == SET && tcp->fin != 1) {
dprint("packet is not FIN, ignoring...\n");
@@ -1359,8 +1490,9 @@
}
}
}
- if(flagsmatch && ip->protocol == attempt->door->protocol[attempt->stage] &&
- dport == attempt->door->sequence[attempt->stage]) {
+ if(flagsmatch && dport == attempt->door->sequence[attempt->stage] &&
+ ((vers == 4 && ip->protocol == attempt->door->protocol[attempt->stage])
+ || (vers == 6 && ip6->ip6_nxt == attempt->door->protocol[attempt->stage])) ) {
/* level up! */
attempt->stage++;
if(attempt->srchost) {
@@ -1451,7 +1583,8 @@
for(lp = doors; lp; lp = lp->next) {
opendoor_t *door = (opendoor_t*)lp->data;
/* if we're working with TCP, try to match the flags */
- if(ip->protocol == IPPROTO_TCP){
+ if((vers == 4 && ip->protocol == IPPROTO_TCP) ||
+ (vers == 6 && ip6->ip6_nxt == IPPROTO_TCP)) {
if(door->flag_fin != DONT_CARE) {
if(door->flag_fin == SET && tcp->fin != 1) {dprint("packet is not FIN, ignoring...\n");continue;}
if(door->flag_fin == NOT_SET && tcp->fin == 1) {dprint("packet is not !FIN, ignoring...\n");continue;}
@@ -1478,7 +1611,9 @@
}
}
- if(ip->protocol == door->protocol[0] && dport == door->sequence[0]) {
+ if (dport == door->sequence[0] &&
+ ((vers == 4 && ip->protocol == door->protocol[0]) ||
+ (vers == 6 && ip6->ip6_nxt == door->protocol[0])) ) {
struct hostent *he;
/* create a new entry */
attempt = (knocker_t*)malloc(sizeof(knocker_t));
@@ -1490,10 +1625,17 @@
strcpy(attempt->src, srcIP);
/* try a reverse lookup if enabled */
if (o_lookup) {
- inaddr.s_addr = ip->saddr;
- he = gethostbyaddr((void *)&inaddr, sizeof(inaddr), AF_INET);
- if(he) {
- attempt->srchost = strdup(he->h_name);
+ if (vers == 4) {
+ inaddr.s_addr = ip->saddr;
+ he = gethostbyaddr((void *)&inaddr, sizeof(inaddr), AF_INET);
+ if(he)
+ attempt->srchost = strdup(he->h_name);
+ } else {
+ memcpy(&in6addr, &ip6->ip6_src, sizeof(in6addr));
+ he = gethostbyaddr((void *)&in6addr, sizeof(in6addr), AF_INET6);
+ if(he) {
+ attempt->srchost = strdup(he->h_name);
+ }
}
}
signature.asc
Description: Digital signature

