Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 May 2008 18:51:40 GMT
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 141815 for review
Message-ID:  <200805181851.m4IIpewo052849@repoman.freebsd.org>

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

Change 141815 by rpaulo@rpaulo_epsilon on 2008/05/18 18:50:47

	Add missing headers.
	Fix a few bugs, namely, check the return of memcmp, don't use
	inet_ntoa() more than once on the same context.
	Add more debugging.
	Add more TCP FSM processing.

Affected files ...

.. //depot/projects/soc2008/rpaulo-tcpad/handler.c#3 edit

Differences ...

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

@@ -23,14 +23,16 @@
  * 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#2 $
+ * $P4: //depot/projects/soc2008/rpaulo-tcpad/handler.c#3 $
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/queue.h>
+#include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
@@ -56,6 +58,7 @@
 	const struct tcphdr *tcp;
 	int linkhlen;
 	conn_t *cp;
+	conn_t *rcp;
 
 	linkhlen = (int)*user;
 
@@ -65,6 +68,9 @@
 
 	cp = find_conn(ip->ip_src, ip->ip_dst, tcp->th_sport,
 	    tcp->th_dport);
+	rcp = find_conn(ip->ip_dst, ip->ip_src, tcp->th_dport,
+	    tcp->th_sport);
+
 	if ((tcp->th_flags & TH_FLAGS) == TH_SYN) {
 		if (cp) {
 			DPRINTF("connection already being tracked!\n");
@@ -79,8 +85,9 @@
 		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));
+		DPRINTF("tracking (syn) connection between %s and ",
+		    inet_ntoa(cp->sv4addr));
+		DPRINTF("%s\n",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)) {
@@ -91,28 +98,51 @@
 			free(cp);
 		}
 		cp = malloc(sizeof(*cp));
-		cp->tcpstate = TCPAD_SYN_RECEIVED;
+		cp->tcpstate = TCPS_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));
+		DPRINTF("tracking (syn/ack) connection between %s and ",
+		    inet_ntoa(cp->sv4addr));
+		DPRINTF("%s\n",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");
+		if (cp) {
+			if (cp->tcpstate == TCPS_SYN_SENT ||
+			    cp->tcpstate == TCPS_SYN_RECEIVED) {
+				cp->tcpstate = TCPS_ESTABLISHED;
+				rcp->tcpstate = TCPS_ESTABLISHED;
+				DPRINTF("established\n");
+				print_packet(bytes, linkhlen);
+			}
+			if (cp->tcpstate == TCPS_FIN_WAIT_1) {
+				cp->tcpstate = TCPS_FIN_WAIT_2;
+				rcp->tcpstate = TCPS_CLOSE_WAIT;
+				print_packet(bytes, linkhlen);
+			}
+		}
+	} else if ((tcp->th_flags & TH_FLAGS) == (TH_FIN|TH_ACK)) {
+		if (cp) {
+			if (cp->tcpstate == TCPS_ESTABLISHED) {
+				cp->tcpstate = TCPS_FIN_WAIT_1;
+				rcp->tcpstate = TCPS_CLOSE_WAIT;
+				DPRINTF("fin_wait_1\n");
+				print_packet(bytes, linkhlen);
+			}
+		}
+	} else if ((tcp->th_flags & TH_FLAGS) == (TH_RST|TH_ACK)) {
+		if (rcp && rcp->tcpstate == TCPS_SYN_SENT) {
+			DPRINTF("stopped tracking connection (rst) between"
+			    " %s and ", inet_ntoa(rcp->sv4addr));
+			DPRINTF("%s\n",inet_ntoa(rcp->dv4addr));
 			print_packet(bytes, linkhlen);
+			LIST_REMOVE(rcp, entries);
+			free(rcp);
 		}
-		DPRINTF("removing connection\n");
-		print_packet(bytes, linkhlen);
-		LIST_REMOVE(cp, entries);
-		free(cp);
 	}
 }
 
@@ -123,12 +153,12 @@
 	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)
+		if (memcmp(&cp->sv4addr, &ipsrc, sizeof(struct in_addr)) == 0 &&
+		    memcmp(&cp->dv4addr, &ipdst, sizeof(struct in_addr)) == 0 &&
+		    cp->sport == sport && cp->dport == dport) {
 			return (cp);
+		}
 	}
-
 	return (NULL);
 }
 
@@ -142,11 +172,10 @@
 	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);
+	printf("IP %s.%d > ", inet_ntoa(ip->ip_src),
+		ntohs(tcp->th_sport));
+	printf("%s.%d: ", inet_ntoa(ip->ip_dst),
+	    ntohs(tcp->th_dport));
 	
 	if (tcp->th_flags & TH_FIN)
 		printf("F");



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