Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 May 2008 21:38:37 GMT
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 141607 for review
Message-ID:  <200805142138.m4ELcbGO048587@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=141607

Change 141607 by rpaulo@rpaulo_epsilon on 2008/05/14 21:38:02

	Add initial processing of the 3WHS.

Affected files ...

.. //depot/projects/soc2008/rpaulo-tcpad/handler.c#2 edit
.. //depot/projects/soc2008/rpaulo-tcpad/main.c#3 edit
.. //depot/projects/soc2008/rpaulo-tcpad/tcpad.h#1 add

Differences ...

==== //depot/projects/soc2008/rpaulo-tcpad/handler.c#2 (text+ko) ====

@@ -23,52 +23,144 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/soc2008/rpaulo-tcpad/handler.c#1 $
+ * $P4: //depot/projects/soc2008/rpaulo-tcpad/handler.c#2 $
  */
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/socket.h>
+#include <sys/queue.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
 #include <arpa/inet.h>
 #include <pcap.h>
 
+#include "tcpad.h"
 #include "linkhdr.h"
 #include "handler.h"
 #include "debug.h"
 
+
+static conn_t *	find_conn(struct in_addr ipsrc, struct in_addr ipdst,
+    unsigned short sport, unsigned short dport);
+static void	print_packet(const unsigned char *bytes, const int linkhlen);
+
 void
-tcpad_pcaphandler(unsigned char *user __unused,
-    const struct pcap_pkthdr *h __unused,
+tcpad_pcaphandler(unsigned char *user, const struct pcap_pkthdr *h __unused,
     const unsigned char *bytes)
 {
 	const struct ip *ip;
 	const struct tcphdr *tcp;
+	int linkhlen;
+	conn_t *cp;
+
+	linkhlen = (int)*user;
 
-	ip = (const struct ip *)linkhdr_remove(bytes, 4);
+	ip = (const struct ip *)linkhdr_remove(bytes, linkhlen);
 	tcp = (const struct tcphdr *)linkhdr_remove(bytes,
-	    4 + sizeof(struct ip));
+	    linkhlen + sizeof(struct ip));
+
+	cp = find_conn(ip->ip_src, ip->ip_dst, tcp->th_sport,
+	    tcp->th_dport);
+	if ((tcp->th_flags & TH_FLAGS) == TH_SYN) {
+		if (cp) {
+			DPRINTF("connection already being tracked!\n");
+			print_packet(bytes, linkhlen);
+			LIST_REMOVE(cp, entries);
+			free(cp);
+		}
+		cp = malloc(sizeof(*cp));
+		cp->tcpstate = TCPS_SYN_SENT;
+		cp->dport = tcp->th_dport;
+		cp->sport = tcp->th_sport;
+		cp->isv6  = 0;
+		memcpy(&cp->sv4addr, &ip->ip_src, sizeof(struct in_addr));
+		memcpy(&cp->dv4addr, &ip->ip_dst, sizeof(struct in_addr));
+		DPRINTF("tracking connection (syn) between %s and %s\n",
+			inet_ntoa(cp->sv4addr), inet_ntoa(cp->dv4addr));
+		LIST_INSERT_HEAD(&chead, cp, entries);
+		print_packet(bytes, linkhlen);
+	} else if ((tcp->th_flags & TH_FLAGS) == (TH_SYN|TH_ACK)) {
+		if (cp) {
+			DPRINTF("connection already being tracked!\n");
+			print_packet(bytes, linkhlen);
+			LIST_REMOVE(cp, entries);
+			free(cp);
+		}
+		cp = malloc(sizeof(*cp));
+		cp->tcpstate = TCPAD_SYN_RECEIVED;
+		cp->dport = tcp->th_dport;
+		cp->sport = tcp->th_sport;
+		cp->isv6  = 0;
+		memcpy(&cp->sv4addr, &ip->ip_src, sizeof(struct in_addr));
+		memcpy(&cp->dv4addr, &ip->ip_dst, sizeof(struct in_addr));
+		DPRINTF("tracking connection (syn/ack) between %s and %s\n",
+			inet_ntoa(cp->sv4addr), inet_ntoa(cp->dv4addr));
+		LIST_INSERT_HEAD(&chead, cp, entries);
+		print_packet(bytes, linkhlen);
+	} else if ((tcp->th_flags & TH_FLAGS) == TH_ACK) {
+
+	} else if ((tcp->th_flags & TH_FLAGS) == TH_RST ||
+		(tcp->th_flags & TH_FLAGS) == TH_FIN) {
+		if (!cp) {
+			DPRINTF("connection not found, ignoring\n");
+			print_packet(bytes, linkhlen);
+		}
+		DPRINTF("removing connection\n");
+		print_packet(bytes, linkhlen);
+		LIST_REMOVE(cp, entries);
+		free(cp);
+	}
+}
+
+static conn_t *
+find_conn(struct in_addr ipsrc, struct in_addr ipdst, unsigned short
+    sport, unsigned short dport)
+{
+	conn_t *cp;
+
+	LIST_FOREACH(cp, &chead, entries) {
+		if (memcmp(&cp->sv4addr, &ipsrc, sizeof(struct in_addr)) &&
+		    memcmp(&cp->dv4addr, &ipdst, sizeof(struct in_addr)) &&
+		    cp->sport == sport && cp->dport == dport)
+			return (cp);
+	}
+
+	return (NULL);
+}
 
-	DPRINTF("IP (tos 0x%x, ttl %d, id %d, offset %d, flags XX, "
-		"proto TCP (%d), length %d) %s.%d > %s.%d: ", ip->ip_tos,
-		ip->ip_ttl, htons(ip->ip_id), ip->ip_off, ip->ip_p,
-		htons(ip->ip_len), inet_ntoa(ip->ip_src), tcp->th_sport, 
-		inet_ntoa(ip->ip_dst), tcp->th_dport);
+static void
+print_packet(const unsigned char *bytes, const int linkhlen)
+{
+	const struct ip *ip;
+	const struct tcphdr *tcp;
+	
+	ip = (const struct ip *)linkhdr_remove(bytes, linkhlen);
+	tcp = (const struct tcphdr *)linkhdr_remove(bytes,
+	    linkhlen + sizeof(struct ip));
 
+	printf("IP (tos 0x%x, ttl %d, id %d, offset %d, flags XX, "
+	    "proto TCP (%d), length %d) %s.%d > %s.%d: ", ip->ip_tos,
+	    ip->ip_ttl, htons(ip->ip_id), ip->ip_off, ip->ip_p,
+	    htons(ip->ip_len), inet_ntoa(ip->ip_src), tcp->th_sport, 
+	    inet_ntoa(ip->ip_dst), tcp->th_dport);
+	
 	if (tcp->th_flags & TH_FIN)
-		DPRINTF("F");
+		printf("F");
 	if (tcp->th_flags & TH_SYN)
-		DPRINTF("S");
+		printf("S");
 	if (tcp->th_flags & TH_RST)
-		DPRINTF("R");
+		printf("R");
 	if (tcp->th_flags & TH_ACK)
-		DPRINTF(".");
+		printf(".");
 	if (tcp->th_flags & TH_URG)
-		DPRINTF("U");
+		printf("U");
 	if (tcp->th_flags & TH_PUSH)
-		DPRINTF("P");
+		printf("P");
 	if (tcp->th_flags & TH_ECE)
-		DPRINTF("E");
-	DPRINTF("\n");
+		printf("E");
+	printf("\n");
 }

==== //depot/projects/soc2008/rpaulo-tcpad/main.c#3 (text+ko) ====

@@ -23,7 +23,7 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/soc2008/rpaulo-tcpad/main.c#2 $
+ * $P4: //depot/projects/soc2008/rpaulo-tcpad/main.c#3 $
  */
 
 #include <err.h>
@@ -31,7 +31,9 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <pcap.h>
+#include <sys/queue.h>
 
+#include "tcpad.h"
 #include "device.h"
 #include "linkhdr.h"
 #include "handler.h"
@@ -56,6 +58,7 @@
 	pcap_t *p;
 	struct bpf_program fp;
 	char filter[] = "ip proto \\tcp";
+	int linkhlen;
 	
 	promisc = 1;
 	snaplen = 100;
@@ -96,8 +99,13 @@
 		errx(1, "pcap_compile: %s", pcap_geterr(p));
 
 	pcap_setfilter(p, &fp);
+	linkhlen = linkhdr_headerlen(pcap_datalink(p));
+	if (linkhlen == -1)
+		errx(1, "interface type not recognized");
 
+	LIST_INIT(&chead);
 	for (;;) {
-		pcap_dispatch(p, -1, tcpad_pcaphandler, NULL);
+		pcap_dispatch(p, -1, tcpad_pcaphandler,
+		    (unsigned char *)&linkhlen);
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200805142138.m4ELcbGO048587>