PERFORCE change 141607 for review
Rui Paulo
rpaulo at FreeBSD.org
Wed May 14 21:38:38 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=141607
Change 141607 by rpaulo at 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);
}
}
More information about the p4-projects
mailing list