PERFORCE change 141815 for review
Rui Paulo
rpaulo at FreeBSD.org
Sun May 18 18:51:41 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=141815
Change 141815 by rpaulo at 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");
More information about the p4-projects
mailing list