--- /dev/null
+PREFIX=../local
+
+INCLUDEDIR=$(PREFIX)/include
+LIBDIR=$(PREFIX)/lib
+BINDIR=$(PREFIX)/bin
+
+NBD_OBJS = v3_nbd.o
+
+CFLAGS = -I$(INCLUDEDIR)
+VTLFLAGS = -L$(LIBDIR) -Bstatic -lvtl -lnet -Bdynamic -lpcap -lssl
+
+CXX=g++
+CC=/usr/bin/gcc
+AR=ar
+RANLAB=ranlib
+
+CXXFLAGS = $(DEBUG) -g -gstabs+ -Wall $(CFLAGS) -I/usr/kerberos/include
+#CXXFLAGS = -Wall -I/usr/kerberos/include
+LDFLAGS = $(VTLFLAGS)
+
+all: v3_nbd
+
+v3_nbd: $(NBD_OBJS)
+ $(CXX) $(CXXFLAGS) $(NBD_OBJS) $(LDFLAGS) -o v3_nbd
+
+%.o : %.cc
+ $(CXX) $(CXXFLAGS) -c $< -o $(@F)
+
+depend:
+ $(CXX) $(CXXFLAGS) -MM $(NBD_OBJS:.o=.cc) > .dependencies
+
+clean:
+ rm -f $(NBD_OBJS)
+ rm -f v3_nbd
+ rm -f *.log
+
+
+
+
+include .dependencies
+
+
+
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <sstream>
+
+
+
+nbd_config_t g_nbd_conf;
+
+using namespace std;
+//using namespace __gnu_cxx;
+
+
+
+config_t g_config;
+
+int __main (int argc, char ** argv);
+
+#ifdef linux
+
+int main(int argc, char ** argv) {
+ return __main(argc, argv);
+}
+
+#elif WIN32
+
+void main() {
+ __main(0, NULL);
+}
+
+#endif
+
+int __main (int argc, char ** argv) {
+ string config_file;
+ SOCK vnet_sock = 0;
+ struct vnet_config vnet_info;
+ iface_t * iface;
+ if (argc > 2) {
+ usage();
+ exit(0);
+ }
+
+ if (argc == 2) {
+ config_file = string(argv[1]);
+ } else {
+ config_file = VIDS_CONF_FILE;
+ }
+
+
+ int * foo;
+ int num_ports = GetOpenUdpPorts(&foo);
+ int i;
+ for (i = 0; i < num_ports; i++) {
+ printf("port %d open\n", foo[i]);
+ }
+
+
+ // g_conf.log_file = "./vids.log";
+
+ if (config_vids(config_file) == -1) {
+ cerr << "Configuration Error" << endl;
+ exit(-1);
+ }
+
+ // JRL DEBUG
+ debug_init(g_config[LOGFILE_TAG].c_str());
+ JRLDBG("testing...\n");
+
+
+
+ // Configure pcap filter...
+
+ vids_loop(iface, vnet_sock, &vnet_info);
+
+ return 0;
+}
+
+
+#ifdef linux
+int vids_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
+ fd_set all_set, read_set;
+ int max_fd = -1;
+ RawEthernetPacket pkt;
+
+ FD_ZERO(&all_set);
+ FD_SET(vnet_sock, &all_set);
+ max_fd = vnet_sock;
+
+
+ while (1) {
+ int nready = 0;
+ read_set = all_set;
+ nready = select(max_fd + 1, &read_set, NULL, NULL, NULL);
+
+
+ if (nready == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ perror("Select returned error: ");
+ break;
+ }
+ }
+
+
+ if (FD_ISSET(vnet_sock, &read_set)) {
+ //vnet_recv();
+
+
+ }
+ }
+
+ return 0;
+}
+
+#elif WIN32
+int vids_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
+ int ret;
+ RawEthernetPacket pkt;
+ WSANETWORKEVENTS net_events;
+ WSAEVENT events[2];
+ DWORD event_i;
+
+ events[VNET_EVENT] = WSACreateEvent();
+
+ WSAEventSelect(vnet_sock, events[VNET_EVENT], FD_READ | FD_CLOSE);
+ events[IF_EVENT] = if_get_event(iface);
+
+ while (1) {
+ event_i = WSAWaitForMultipleEvents(2, events, false, WSA_INFINITE, false);
+ cout << "Wait returned" << endl;
+
+ if (event_i == WAIT_FAILED) {
+ cout << "ERROR: " << GetLastError() << endl;
+ exit(-1);
+ }
+ event_i -= WAIT_OBJECT_0;
+
+ if (event_i == VNET_EVENT) {
+
+ if (WSAEnumNetworkEvents(vnet_sock, events[event_i], &net_events) == SOCKET_ERROR) {
+ cout << "EnumEventsError: " << WSAGetLastError() << endl;
+ exit(-1);
+ }
+ if (net_events.lNetworkEvents & FD_READ) {
+
+ JRLDBG("Receied VNET Packet\n");
+ // we received data
+
+ if (vnet_info->link_type == TCP_LINK) {
+ pkt.Unserialize(vnet_sock);
+ } else if (vnet_info->link_type == UDP_LINK) {
+ pkt.UdpUnserialize(vnet_sock);
+ }
+
+ process_outbound_pkt(&pkt);
+
+ if_write_pkt(iface, &pkt);
+
+ } else if (net_events.lNetworkEvents & FD_CLOSE) {
+ CLOSE(vnet_sock);
+ return 0;
+ }
+
+ }
+ }
+
+ return 0;
+}
+#endif
+
+
+
+int config_vids(string conf_file_name) {
+ if (read_config(conf_file_name, &g_config) != 0) {
+ return -1;
+ }
+
+ if (g_config.count(VIDS_SERVER_TAG) > 0) {
+ g_vids_conf.server_addr = ToIPAddress(g_config[VIDS_SERVER_TAG].c_str());
+ } else {
+ printf("Must specify VIDS server address\n");
+ return -1;
+ }
+
+ if (g_config.count(VIDS_SERVER_PORT_TAG) > 0) {
+ g_vids_conf.server_port = atoi(g_config[VIDS_SERVER_PORT_TAG].c_str());
+ } else {
+ printf("Must specify VIDS server port\n");
+ return -1;
+ }
+
+ if (g_config.count(TCP_PORTS_TAG) > 0) {
+ istringstream port_stream(g_config[TCP_PORTS_TAG], istringstream::in);
+ int port;
+ int i = 0;
+
+ while (port_stream >> port) {
+ if (i >= MAX_PORTS) {
+ cerr << "You specified too many ports to forward, truncating..." << endl;
+ break;
+ }
+
+ g_vids_conf.tcp_ports[i] = port;
+ i++;
+ }
+
+ g_vids_conf.num_tcp_ports = i;
+ }
+
+
+
+ if (g_config.count(VIRTUAL_MAC_TAG) > 0) {
+ string_to_mac(g_config[VIRTUAL_MAC_TAG].c_str(), g_vids_conf.virtual_mac);
+ }
+
+ if (g_config.count(LOGFILE_TAG) == 0) {
+ g_config[LOGFILE_TAG] = DEFAULT_LOG_FILE;
+ }
+
+ if (GetLocalMacAddress(g_config[INTERFACE_TAG], g_vids_conf.local_mac) == -1) {
+ cerr << "Could not get local mac address" << endl;
+ return -1;
+ }
+
+
+ return 0;
+}
+
+
+int read_config(string conf_file_name) {
+ fstream conf_file(conf_file_name.c_str(), ios::in);
+ char line[MAX_STRING_SIZE];
+
+ while ((conf_file.getline(line, MAX_STRING_SIZE))) {
+ string conf_line = line;
+ string tag;
+ string value;
+ int offset, ltrim_index, rtrim_index;
+
+ if (conf_line[0] == '#') {
+ continue;
+ }
+
+ offset = conf_line.find(":", 0);
+ tag = conf_line.substr(0,offset);
+
+ // kill white space
+ istringstream tag_stream(tag, istringstream::in);
+ tag_stream >> tag;
+
+ if (tag.empty()) {
+ continue;
+ }
+
+ // basic whitespace trimming, we assume that the config handlers will deal with
+ // tokenizing and further formatting
+ value = conf_line.substr(offset + 1, conf_line.length() - offset);
+ ltrim_index = value.find_first_not_of(" \t");
+ rtrim_index = value.find_last_not_of(" \t");
+ value = value.substr(ltrim_index, (rtrim_index + 1) - ltrim_index);
+
+ g_config[tag] = value;
+ }
+ return 0;
+}
+
+
+void usage() {
+ cout << "Usage: vids [config_file]" << endl;
+ return;
+}
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __V3_NBD_H__
+#define __V3_NBD_H__
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+#include <sstream>
+
+#ifdef linux
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#elif defined(WIN32) && !defined(__CYGWIN__)
+
+#endif
+
+
+using namespace std;
+
+
+
+#define DEFAULT_LOG_FILE "./status.log"
+#define VIDS_CONF_FILE "v3_nbd.ini"
+#define MAX_STRING_SIZE 1024
+
+
+typedef struct nbd_config {
+ unsigned long server_addr;
+ int server_port;
+
+
+} nbd_config_t;
+
+
+
+void usage();
+int config_nbd(string conf_file_name);
+
+
+
+#define VIDS_SERVER_TAG "vids_server"
+
+
+#endif // !__VIDS_H
--- /dev/null
+DISTDIR= ../dist
+PREFIX=../local
+DEBUG=-DDEBUG
+#DEBUG=
+#PROFILER=-pg
+PROFILER=
+
+INCLUDEDIR=$(PREFIX)/include
+LIBDIR=$(PREFIX)/lib
+BINDIR=$(PREFIX)/bin
+
+VTL_OBJS = vtl_util.o if.o socks.o util.o net_util.o raw_ethernet_packet.o vtl_model.o config.o
+TOR_VTL_OBJS = vtl_socks5.o tor_vtl.o vtl_dns.o
+
+VTL_HDRS = vtl.h vtl_util.h util.h socks.h if.h net_util.h vtl_model.h raw_ethernet_packet.h debug.h config.h vtl_harness.h
+
+DISTFILES = config.cc config.h debug.h if.cc if.h net_util.cc net_util.h raw_ethernet_packet.cc raw_ethernet_packet.h socks.cc socks.h util.cc util.h vtl.h vtl_harness.h vtl_model.cc vtl_model.h vtl_util.cc vtl_util.h Makefile .dependencies
+
+LIBNETLDFLAGS = -L$(LIBDIR) -lnet
+SSLFLAGS = -lssl
+#LIBNETLDFLAGS =
+#SSLFLAGS =
+PCAPCFLAGS = -I$(INCLUDEDIR)
+PCAPLDFLAGS = -L$(LIBDIR) -lpcap
+
+
+CXX=g++
+CC=/usr/bin/gcc
+AR=ar
+RANLIB=ranlib
+
+#CXXFLAGS = -DDEBUG -g -gstabs+ -Wall $(PCAPCFLAGS) -I/usr/kerberos/include
+CXXFLAGS = $(DEBUG) -Wall -g -gstabs+ -DUSE_SSL $(PCAPCFLAGS) -I/usr/kerberos/include
+LDFLAGS = -L$(LIBDIR) $(PCAPLDFLAGS) $(LIBNETLDFLAGS) $(SSLFLAGS)
+
+
+all: vtl
+
+#vtl_test: $(VTL_OBJS) vtl_test.o
+# $(CXX) $(CXXFLAGS) $(VTL_OBJS) vtl_test.o $(LDFLAGS) -o vtl_test
+
+#vtl_ack_test: vtl_ack_test.o $(VTL_OBJS) libvtl.a
+# $(CXX) $(CXXFLAGS) -L. vtl_ack_test.o -Bstatic -lvtl -Bdynamic $(LDFLAGS) -o vtl_ack_test
+
+
+vtl: $(VTL_OBJS)
+ $(AR) rcs libvtl.a $(VTL_OBJS)
+
+
+%.o : %.cc
+ $(CXX) $(CXXFLAGS) -c $< -o $(@F) $(PROFILER)
+
+depend:
+ $(CXX) $(CXXFLAGS) -MM $(VNET_OBJS:.o=.cc) > .dependencies
+
+clean:
+ rm -f *.o
+ rm -f $(VTL_OBJS) libvtl.a
+# rm -f vtl_ack_test
+
+install: vtl
+ mkdir -p $(BINDIR)
+ mkdir -p $(LIBDIR)
+ mkdir -p $(INCLUDEDIR)
+ cp libvtl.a $(LIBDIR)/libvtl.a
+ cp $(VTL_HDRS) $(INCLUDEDIR)/
+
+
+dist: $(DISTFILES)
+ mkdir -p $(DISTDIR)/vtl
+ cp $(DISTFILES) $(DISTDIR)/vtl
+
+include .dependencies
+
+
+
--- /dev/null
+#include "config.h"
+
+
+int read_config(string conf_file_name, config_t * config) {
+ fstream conf_file(conf_file_name.c_str(), ios::in);
+ char line[MAX_CONFIG_LINE_SIZE];
+
+ if (!conf_file.is_open()) {
+ return -1;
+ }
+
+ while ((conf_file.getline(line, MAX_CONFIG_LINE_SIZE))) {
+ string conf_line = line;
+ string tag;
+ string value;
+ int offset, ltrim_index, rtrim_index;
+
+ if (conf_line[0] == '#') {
+ continue;
+ }
+
+ offset = conf_line.find(":", 0);
+ tag = conf_line.substr(0,offset);
+
+ // kill white space
+ istringstream tag_stream(tag, istringstream::in);
+ tag_stream >> tag;
+
+ if (tag.empty()) {
+ continue;
+ }
+
+ // basic whitespace trimming, we assume that the config handlers will deal with
+ // tokenizing and further formatting
+ value = conf_line.substr(offset + 1, conf_line.length() - offset);
+ ltrim_index = value.find_first_not_of(" \t");
+ rtrim_index = value.find_last_not_of(" \t");
+ value = value.substr(ltrim_index, (rtrim_index + 1) - ltrim_index);
+
+ (*config)[tag] = value;
+ }
+ return 0;
+}
--- /dev/null
+#ifndef _config
+#define _config
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <sstream>
+
+using namespace std;
+
+#define MAX_CONFIG_LINE_SIZE 1024
+
+
+struct eqstr {
+ bool operator()(const string s1, const string s2) const {
+ return strcmp(s1.c_str(), s2.c_str()) < 0;
+ }
+};
+
+typedef map<const string, string, eqstr> config_t;
+
+
+int read_config(string conf_file_name, config_t * config);
+
+
+
+#endif
--- /dev/null
+#ifndef __DEBUG_H
+#define __DEBUG_H 1
+
+
+
+
+#ifdef DEBUG
+
+#define ASSERT(exp) assert(exp)
+
+/*
+ *
+ *
+ */
+
+#ifdef linux
+
+extern FILE * logfile;
+extern time_t dbgt;
+extern char dmsg[1024];
+
+#define DEBUG_DECLARE() FILE * logfile; time_t dbgt; char dmsg[1024];
+#define JRLDBG( ...) time(&dbgt); sprintf(dmsg,"%s: ",ctime(&dbgt)); *(dmsg + strlen(dmsg) -3) = ' '; fprintf(logfile, dmsg); sprintf(dmsg,__VA_ARGS__); fprintf(logfile,dmsg); fflush(logfile);
+#define debug_init(logfilename) logfile = fopen(logfilename,"w+")
+
+#elif defined(WIN32)
+
+#define DEBUG_DECLARE()
+#define JRLDBG printf
+#define debug_init(logfilename)
+
+#endif
+
+/*
+ *
+ *
+ */
+
+#else //!DEBUG
+
+#ifdef WIN32
+
+#define ASSERT(exp)
+#define DEBUG_DECLARE()
+#define JRLDBG()
+#define debug_init(logfilename)
+
+#elif defined(linux)
+
+#define ASSERT(exp)
+#define DEBUG_DECLARE(...)
+#define JRLDBG(...)
+#define debug_init(logfilename)
+
+#endif
+
+#endif
+
+
+
+#endif
--- /dev/null
+#include "if.h"
+
+iface_t * if_connect(string if_name, char mode) {
+ char pcap_errbuf[PCAP_ERRBUF_SIZE];
+
+ iface_t * iface = (iface_t *)malloc(sizeof(iface_t));
+ iface->name = new string();
+
+ cout << "device name : " << if_name << endl;
+
+ *(iface->name) = if_name;
+ iface->mode = mode;
+
+
+
+ // mode is relevant only under linux
+#ifdef linux
+ if (mode & IF_RD) {
+ if ((iface->pcap_interface = pcap_open_live((char*)if_name.c_str(), 65536, 1, 1, pcap_errbuf)) == NULL) {
+ JRLDBG("Could not initialize pcap\n");
+ return NULL;
+ }
+
+ iface->pcap_fd = pcap_fileno(iface->pcap_interface);
+ }
+
+ if (mode & IF_WR) {
+ char libnet_errbuf[LIBNET_ERRORBUF_SIZE];
+
+ if ((iface->net_interface = libnet_init(LIBNET_LINK_ADV, (char *)if_name.c_str(), libnet_errbuf)) == NULL) {
+ JRLDBG("Could not initialize libnet\n");
+ return NULL;
+ }
+ }
+
+#elif defined(WIN32)
+ if ((iface->pcap_interface = pcap_open_live((char*)if_name.c_str(), 65536, 1, 1, pcap_errbuf)) == NULL) {
+ JRLDBG("Could not initialize pcap\n");
+ return NULL;
+ }
+
+ pcap_setmintocopy(iface->pcap_interface, 40);
+ iface->pcap_event = pcap_getevent(iface->pcap_interface);
+#endif
+
+ return iface;
+}
+
+void if_disconnect(iface_t * iface) {
+ free(iface->name);
+ pcap_close(iface->pcap_interface);
+
+}
+
+#ifdef WIN32
+HANDLE if_get_event(iface_t * iface) {
+ return iface->pcap_event;
+ // return pcap_getevent(iface->pcap_interface);
+}
+#endif
+
+#ifdef linux
+int if_get_fd(iface_t * iface) {
+ return iface->pcap_fd;
+}
+#endif
+
+
+int if_loop(iface_t * iface, RawEthernetPacket * pkt) {
+ int ret;
+
+ ret = pcap_loop(iface->pcap_interface, 1, pkt_handler, (u_char*)pkt);
+
+ if (ret == 0) {
+ return IF_PACKET;
+ } else if (ret == -2) {
+ return IF_BREAK;
+ } else if (ret == -1) {
+ return IF_CONT;
+ } else {
+ return -1;
+ }
+}
+
+void if_break_loop(iface_t * iface) {
+ pcap_breakloop(iface->pcap_interface);
+}
+
+void pkt_handler(u_char * pkt, const struct pcap_pkthdr * pkt_header, const u_char * pkt_data) {
+ RawEthernetPacket pkt2((const char *)pkt_data, (unsigned)(pkt_header->len));
+ *(RawEthernetPacket *)pkt = pkt2;
+ ((RawEthernetPacket*)pkt)->set_type("et");
+}
+
+
+int if_read_pkt(iface_t * iface, RawEthernetPacket * pkt) {
+ struct pcap_pkthdr header;
+ const u_char * pcap_pkt;
+
+ pcap_pkt = pcap_next(iface->pcap_interface, &header);
+
+ if (pcap_pkt == NULL) {
+ return -1;
+ }
+
+ RawEthernetPacket pkt2((const char *)pcap_pkt, (unsigned)(header.len));
+ *pkt = pkt2;
+
+ pkt->set_type("et");
+
+ return 0;
+}
+
+
+
+int if_write_pkt(iface_t * iface, RawEthernetPacket * pkt) {
+ ASSERT((iface != NULL) && (pkt != NULL) && (iface->net_interface != NULL));
+
+#ifdef linux
+ JRLDBG("Writing pkt size(%d)\n", pkt->get_size());
+ if (libnet_adv_write_link(iface->net_interface,
+ (u_char *)(pkt->get_data()),
+ pkt->get_size()) < 0) {
+ JRLDBG("Libnet could not inject packet size (%d)\n", pkt->get_size());
+ return -1;
+ }
+
+#elif defined(WIN32)
+ if (pcap_sendpacket(iface->pcap_interface,
+ (u_char *)(pkt->get_data()),
+ pkt->get_size()) < 0) {
+ JRLDBG("PCAP could not inject packet\n");
+ return -1;
+ }
+
+#endif
+
+ return 0;
+}
+
+int if_setup_filter(iface_t * iface, string bpf_str) {
+ struct bpf_program fcode;
+ bpf_u_int32 netmask;
+ bpf_u_int32 network;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ char * filter_buf;
+
+
+ filter_buf = (char *)malloc(bpf_str.length());
+ strcpy(filter_buf, bpf_str.c_str());
+ cout << "Setting Getting interface info for " << iface->name << endl;
+ if (pcap_lookupnet(iface->name->c_str(), &network, &netmask, errbuf) == -1) {
+ JRLDBG("Error looking up the network info\n");
+ return -1;
+ }
+
+ netmask=0xffffffff;
+ cout << bpf_str << endl;
+ if (pcap_compile(iface->pcap_interface, &fcode, filter_buf, 1, netmask) < 0) {
+ JRLDBG("Could not compile bpf filter\n");
+ return -1;
+ }
+
+ if (pcap_setfilter(iface->pcap_interface, &fcode) < 0) {
+ JRLDBG("Could not insert bpf filter\n");
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef __IF_H
+#define __IF_H 1
+
+#include "util.h"
+#include "debug.h"
+#include "raw_ethernet_packet.h"
+
+
+
+#ifdef linux
+#include <libnet.h>
+#define LIBNET_ERRORBUF_SIZE 256
+#elif defined(WIN32)
+#define WPCAP
+#endif
+
+#include <pcap.h>
+
+#ifdef WIN32
+#include <Packet32.h>
+#endif
+
+
+typedef struct iface {
+ string *name;
+
+ pcap_t * pcap_interface;
+
+ char mode;
+
+#ifdef linux
+ int pcap_fd;
+
+ libnet_t * net_interface;
+#elif defined(WIN32)
+ HANDLE pcap_event;
+#endif
+
+} iface_t;
+
+#define IF_PACKET 1
+#define IF_BREAK 2
+#define IF_CONT 3
+
+
+#define IF_RD 0x1
+#define IF_WR 0x2
+#define IF_RW 0x3
+
+
+iface_t * if_connect(string if_name, char mode = IF_RW);
+int if_setup_filter(iface_t * iface, string bpf_str);
+
+#ifdef linux
+int if_get_fd(iface_t * iface);
+#elif WIN32
+HANDLE if_get_event(iface_t * iface);
+#endif
+
+int if_loop(iface_t * iface, RawEthernetPacket * pkt);
+void pkt_handler(u_char * pkt, const struct pcap_pkthdr * pkt_header, const u_char * pkt_data);
+
+int if_write_pkt(iface_t * iface, RawEthernetPacket * pkt);
+int if_read_pkt(iface_t * iface, RawEthernetPacket * pkt);
+
+
+#endif // !__IF_H
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "net_util.h"
+
+
+void do_string_to_ipaddress(unsigned char * ip, IPADDRESS & ipaddress) {
+
+}
+
+unsigned long do_ipaddress_to_unsigned_long(IPADDRESS & ipaddress) {
+ return 0;
+}
+
+// ip address conversion functions
+void do_binary_to_ipaddress(unsigned char* ip,IPADDRESS& ipaddress) {
+ ipaddress.a1 = ip[0];
+ ipaddress.a2 = ip[1];
+ ipaddress.a3 = ip[2];
+ ipaddress.a4 = ip[3];
+}
+
+
+// ip address conversion functions
+void do_binary_to_string(unsigned char* ip,char* buffer) {
+ IPADDRESS ipaddress;
+ do_binary_to_ipaddress(ip, ipaddress);
+ do_ipaddress_to_string(ipaddress, buffer);
+}
+
+void do_ipaddress_to_string(IPADDRESS ipaddress, char* buffer) {
+ sprintf(buffer,"%d.%d.%d.%d", ipaddress.a1, ipaddress.a2, ipaddress.a3, ipaddress.a4);
+}
+
+/*
+// this function returns the ip protocol string based on the ip protocol number
+char* return_ip_protocol(unsigned char protocol) {
+
+ if(protocol == 0x1) {
+ return "ICMP";
+ } else if(protocol == 0x6) {
+ return "TCP";
+ } else if(protocol == 17) {
+ return "UDP";
+ } else if(protocol == 121) {
+ return "SMP";
+ } else {
+ return "Unknown";
+ }
+
+ return 0;
+}
+*/
--- /dev/null
+#ifndef __NET_UTIL_H
+#define __NET_UTIL_H 1
+
+#ifdef linux
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#elif WIN32
+
+#endif
+
+// 14 (ethernet frame) + 20 bytes
+struct HEADERS {
+ char ethernetdest[6];
+ char ethernetsrc[6];
+ unsigned char ethernettype[2]; // indicates layer 3 protocol type
+ char ip[20];
+};
+
+struct IPHEADER {
+ unsigned char junk[9];
+ unsigned char protocol[1];
+ unsigned char checksum[2];
+
+ union {
+ // for getting the address information both in binary format and long format
+ unsigned char src[4];
+ unsigned long srcl;
+ };
+
+ union {
+ unsigned char dest[4];
+ unsigned long destl;
+ };
+
+};
+
+// this is used to extract the IP address from the IP header in conventional form
+struct IPADDRESS {
+ unsigned char a1,a2,a3,a4;
+};
+
+
+void do_binary_to_string(unsigned char* ip,char* buffer);
+void do_ipaddress_to_string(IPADDRESS ipaddress,char* buffer);
+void do_binary_to_ipaddress(unsigned char* ip,IPADDRESS& ipaddress);
+//char* return_ip_protocol(unsigned char protocol);
+
+
+
+#endif
--- /dev/null
+#include <malloc.h>
+#include <string.h>
+
+#ifdef linux
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#include "raw_ethernet_packet.h"
+#include "util.h"
+#include "debug.h"
+
+
+
+
+RawEthernetPacket::RawEthernetPacket(){
+ type = pkt;
+ size = (size_t*)(pkt + (sizeof(char) * 2));
+ data = pkt + (sizeof(char) * 2) + sizeof(size_t);
+}
+
+
+RawEthernetPacket::RawEthernetPacket(const RawEthernetPacket &rhs)
+{
+ this->type = pkt;
+ this->size = (size_t*)(pkt + (sizeof(char) * 2));
+ this->data = pkt + (sizeof(char) * 2) + sizeof(size_t);
+ // *(this->size)=*(rhs.size);
+ this->set_size(rhs.get_size());
+ memcpy(this->type, rhs.type, sizeof(char) * 2);
+ memcpy(this->data,rhs.data,*(this->size));
+}
+
+RawEthernetPacket::RawEthernetPacket(const char *data, const size_t size)
+{
+ this->type = pkt;
+ this->size = (size_t*)(pkt + (sizeof(char) * 2));
+ this->data = pkt + (sizeof(char) * 2) + sizeof(size_t);
+ this->set_size(size);
+ memcpy(this->data,data,size);
+}
+
+
+const RawEthernetPacket & RawEthernetPacket::operator= (const RawEthernetPacket &rhs)
+{
+ this->type = pkt;
+ this->size = (size_t*)(pkt + (sizeof(char) * 2));
+ this->data = pkt + (sizeof(char) * 2) + sizeof(size_t);
+ this->set_size(rhs.get_size());
+ memcpy(data, rhs.data, *(size_t*)(this->size));
+
+ return *this;
+}
+
+
+RawEthernetPacket::~RawEthernetPacket()
+{}
+
+
+size_t RawEthernetPacket::get_size() const {
+ size_t t_size;
+ memcpy(&t_size, pkt+2, sizeof(size_t));
+ return t_size;
+}
+
+void RawEthernetPacket::set_size(size_t new_size) {
+ memcpy(this->pkt + (sizeof(char) * 2), &new_size, sizeof(size_t));
+}
+
+char * RawEthernetPacket::get_type() {
+ return pkt;
+}
+
+void RawEthernetPacket::set_type (const char * new_type) {
+ memcpy(this->pkt, new_type, sizeof(char) * 2);
+}
+
+char * RawEthernetPacket::get_data() {
+ return this->pkt + (sizeof(char) * 2) + sizeof(size_t);
+}
+
+
+#ifdef USE_SSL
+int RawEthernetPacket::Serialize(const SOCK fd, SSL * ssl) const {
+ int length = (sizeof(char)*2) + this->get_size() + sizeof(size_t);
+ int ret = 0;
+
+ ret = Send(fd, ssl, pkt, length, true);
+ if (ret != (int)length) {
+ return -1;
+ }
+ return ret;
+}
+
+
+int RawEthernetPacket::Unserialize(const SOCK fd, SSL * ssl) {
+ int ret;
+
+ ret = Receive(fd, ssl, pkt, sizeof(char) * 2 + sizeof(size_t), true);
+ if (ret == 0) {
+ JRLDBG("TCP socket closed\n");
+ return 0;
+ } else if (ret != (sizeof(char) * 2 + sizeof(size_t))) {
+ JRLDBG("Error unserializing packet header from tcp socket\n");
+ return -1;
+ }
+
+ JRLDBG("Receiving TCP data. size=%d, offset=%d\n", this->get_size(), *(pkt + 2));
+
+ ret = Receive(fd, ssl, data, this->get_size(), true);
+ if (ret == 0) {
+ JRLDBG("TCP Socket closed\n");
+ return 0;
+ } else if (ret != (int)this->get_size()) {
+ JRLDBG("Error unserializing packet from tcp socket\n");
+ return -1;
+ }
+
+ return ret;
+}
+#endif
+int RawEthernetPacket::Serialize(const SOCK fd) const {
+ int length = (sizeof(char)*2) + this->get_size() + sizeof(size_t);
+ int ret = 0;
+
+ ret = Send(fd, pkt, length, true);
+ if (ret != (int)length) {
+ return -1;
+ }
+ return ret;
+}
+
+
+int RawEthernetPacket::Unserialize(const SOCK fd) {
+ int ret;
+
+ ret = Receive(fd, pkt, sizeof(char) * 2 + sizeof(size_t), true);
+ if (ret == 0) {
+ JRLDBG("TCP socket closed\n");
+ return 0;
+ } else if (ret != (sizeof(char) * 2 + sizeof(size_t))) {
+ JRLDBG("Error unserializing packet header from tcp socket\n");
+ return -1;
+ }
+
+ JRLDBG("Receiving TCP data. size=%d, offset=%d\n", this->get_size(), *(pkt + 2));
+
+ ret = Receive(fd, data, this->get_size(), true);
+ if (ret == 0) {
+ JRLDBG("TCP Socket closed\n");
+ return 0;
+ } else if (ret != (int)this->get_size()) {
+ JRLDBG("Error unserializing packet from tcp socket\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+
+
+/* SRC_ROUTING: We need to add a long * to the arguments that we will
+ write the client address (int form) into */
+int RawEthernetPacket::UdpUnserialize(const SOCK fd) {
+ struct sockaddr_in clientaddr; /*the client address strcuture */
+ int clientlen = sizeof(clientaddr);
+
+ int length = 2 + sizeof(size_t)+ ETHERNET_PACKET_LEN;
+ int rcvd = 0;
+
+ rcvd = recvfrom(fd, pkt,length,0,(struct sockaddr *)&clientaddr,(socklen_t *)&clientlen);
+
+ return rcvd;
+}
+
+int RawEthernetPacket::UdpSerialize(const SOCK fd, struct sockaddr * serveraddr) const {
+ int len = sizeof(*serveraddr);
+ int length;
+
+ int sent = 0;
+ length = sizeof(char)* 2 + this->get_size() + sizeof(size_t);
+
+ sent = sendto(fd,pkt,length,0,serveraddr,len);
+
+ return sent;
+}
+
+// JRL VTP
+int RawEthernetPacket::VtpUnserialize(const SOCK fd, struct in_addr * serveraddr) {
+ int ret;
+ this->set_size((unsigned int)(-1));
+
+ ret = Receive(fd, pkt, sizeof(char) * 2, true);
+ if (ret == 0) {
+ JRLDBG("VTP connection has Closed\n");
+ return 0;
+ } else if (ret != (int)sizeof(char) * 2) {
+ JRLDBG("Could not read type from VTP packet\n");
+ return -1;
+ }
+
+ ret = Receive(fd, (char *)serveraddr, sizeof(struct in_addr), true);
+ if (ret == 0) {
+ JRLDBG("VTP connection has closed\n");
+ return 0;
+ } else if (ret != (int)sizeof(struct in_addr)) {
+ JRLDBG("Could not read VTP address info\n");
+ return -1;
+ }
+
+ ret = Receive(fd, (char *)size, sizeof(size_t), true);
+ if (ret == 0) {
+ JRLDBG("VTP connection has closed\n");
+ return 0;
+ } else if (ret != sizeof(size_t)) {
+ JRLDBG("Could not read VTP size\n");
+ return -1;
+ }
+
+ ret = Receive(fd, data, this->get_size(), true);
+ if (ret == 0) {
+ JRLDBG("VTP connection has closed\n");
+ return 0;
+ } else if (ret != (int)this->get_size()) {
+ JRLDBG("Could not read VTP packet data\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+int RawEthernetPacket::VtpSerialize(const SOCK fd, struct in_addr * serveraddr ) const {
+ int length;
+ int ret;
+
+ ret = Send(fd, type, sizeof(char) * 2, true);
+ if (ret != sizeof(char) * 2) {
+ JRLDBG("Error writing type to VTP socket\n");
+ return -1;
+ }
+
+ ret = Send(fd, (char *)serveraddr, sizeof(struct in_addr), true);
+ if (ret != sizeof(struct in_addr)) {
+ JRLDBG("Error writing dest addr to VTP socket\n");
+ return -1;
+ }
+
+ length = this->get_size() + sizeof(size_t);
+
+ ret = Send(fd, pkt + (sizeof(char) * 2), length, true);
+ if (ret != (int)length) {
+ JRLDBG("ERROR writing packet length and data to VTP socket\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+// END JRL
+
+
+
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+
+void RawEthernetPacket::Print(unsigned size, FILE *out) const
+{
+ fprintf(out,"raw_ethernet_packet: size %-4u first %u bytes: ", *(this->size), MIN(*(this->size),size));
+ printhexbuffer(out, data, MIN(*(this->size),size));
+ fprintf(out,"\n");
+}
+
+ostream & RawEthernetPacket::Print(ostream &os) const
+{
+ char buf[10240];
+ unsigned n;
+ unsigned i;
+
+ snprintf(buf,2048,"RawEthernetPacket(size=%u, bytes=", this->get_size());
+ n=strlen(buf);
+ for (i=0;i<this->get_size();i++) {
+ bytetohexbyte(data[i],&(buf[n+2*i]));
+ }
+ buf[n+2*i]=0;
+ os<<(char*)buf;
+ os<<", text=\"";
+ for (i=0;i<this->get_size();i++) {
+ char c= data[i];
+ if (c>=32 && c<=126) {
+ os<<c;
+ } else {
+ os<<'.';
+ }
+ }
+ os << "\")";
+
+ return os;
+}
+
--- /dev/null
+#ifndef _raw_ethernet_packet
+#define _raw_ethernet_packet
+#include <iostream>
+#include <stdio.h>
+
+#include "socks.h"
+
+#ifdef linux
+#include <sys/socket.h>
+#include <netinet/in.h>
+#elif defined(WIN32)
+
+
+#endif
+
+
+
+#ifdef USE_SSL
+extern "C" {
+#define OPENSSL_NO_KRB5
+#include <openssl/ssl.h>
+}
+#endif
+
+class Packet;
+
+using namespace std;
+
+
+#define ETHERNET_HEADER_LEN 14
+#define ETHERNET_DATA_MIN 46
+#define ETHERNET_DATA_MAX 1500
+
+#define ETHERNET_PACKET_LEN (ETHERNET_HEADER_LEN+ETHERNET_DATA_MAX)
+
+
+#define SERIALIZATION_CLOSED -1
+#define SERIALIZATION_ERROR -2
+
+struct RawEthernetPacket {
+
+ char pkt[2 + 4 + ETHERNET_PACKET_LEN];
+ char * type;
+ size_t * size;
+ char * data;
+
+ size_t get_size() const;
+ void set_size(size_t new_size);
+
+ char * get_type();
+ void set_type(const char * new_type);
+
+ char * get_data();
+
+ int length() const { return sizeof(pkt);}
+
+
+ RawEthernetPacket();
+ RawEthernetPacket(const RawEthernetPacket &rhs);
+ RawEthernetPacket(const char *data, const size_t size);
+ const RawEthernetPacket & operator= (const RawEthernetPacket &rhs);
+ virtual ~RawEthernetPacket();
+
+ int SerializeToBuf(char ** buf) const;
+ void UnserializeFromBuf(char * buf);
+
+#ifdef USE_SSL
+ int Serialize(const SOCK fd, SSL *ssl) const;
+ int Unserialize(const SOCK fd, SSL *ssl);
+#endif
+ int Serialize(const SOCK fd) const;
+ int Unserialize(const SOCK fd);
+
+ int UdpSerialize(const SOCK fd,struct sockaddr *serveraddr) const;
+ int UdpUnserialize(const SOCK fd);
+
+ int VtpSerialize(const SOCK fd, struct in_addr * serveraddr) const;
+ int VtpUnserialize(const SOCK fd, struct in_addr * serveraddr);
+
+
+
+
+ void Print(unsigned size=ETHERNET_PACKET_LEN, FILE *out=stdout) const;
+ ostream & Print(ostream &os) const;
+};
+
+inline ostream & operator<<(ostream &os, const RawEthernetPacket &p) {
+ return p.Print(os);
+}
+#endif
--- /dev/null
+#include "socks.h"
+#include <signal.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+#if defined(__sparc__)
+#include <sys/filio.h>
+#endif
+
+#if defined(__sparc__) || (defined(WIN32) && !defined(__CYGWIN__))
+#define SOCKOPT_TYPE char *
+#else
+#define SOCKOPT_TYPE void *
+#endif
+
+#if defined(linux)
+#define SOCKOPT_LEN_TYPE unsigned
+#else
+#define SOCKOPT_LEN_TYPE int
+#endif
+
+
+
+template <typename A, typename B> bool MIN(const A &a, const B &b) {
+ return ((a < b) ? a : b);
+}
+
+
+int GetSockType(const SOCK fd) {
+ int type;
+ SOCKOPT_LEN_TYPE len = sizeof(int);
+
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (SOCKOPT_TYPE)&type, &len)) {
+ return -1;
+ } else {
+ return type;
+ }
+}
+
+
+int IsSocket(const SOCK fd) {
+ return (GetSockType(fd) >= 0);
+}
+
+int IsStreamSocket(const SOCK fd) {
+ return (GetSockType(fd) == SOCK_STREAM);
+}
+
+int IsDatagramSocket(const SOCK fd) {
+ return (GetSockType(fd) == SOCK_DGRAM);
+}
+
+#ifdef linux
+int IsVirtualSocket(const SOCK fd) {
+ struct stat mystat;
+ fstat(fd, &mystat);
+
+ return S_ISFIFO(mystat.st_mode);
+}
+#endif
+
+int IsValidIPMulticastAddress(const unsigned adx) {
+
+ //int x=(ntohl(port)>>24)&0xff;
+ int x = (adx >> 24) & 0xff;
+
+ if ((x < 224) || (x > 239)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+void IPToHostname(const unsigned ip, char *name, const int namesize) {
+ struct in_addr ia;
+ struct hostent * he;
+
+ ia.s_addr = ip;
+
+ he = gethostbyaddr((const char *)&ia, sizeof(ia), AF_INET);
+
+ strncpy(name, he ? he->h_name : "UNKNOWN HOST", namesize - 1);
+}
+
+
+void PrintIPAddress(const unsigned adx, FILE *out) {
+ fprintf(out,"%3d.%3d.%3d.%3d",
+ (adx >> 24) & 0xff,
+ (adx >> 16) & 0xff,
+ (adx >> 8) & 0xff,
+ (adx) & 0xff);
+}
+
+unsigned ToIPAddress(const char * hostname) {
+ unsigned x;
+
+ if ((x = inet_addr(hostname)) != INADDR_NONE) {
+ return ntohl(x);
+ } else {
+ struct hostent * he;
+
+ if ((he = gethostbyname(hostname)) == NULL) {
+ return INADDR_NONE;
+ } else {
+ memcpy(&x, he->h_addr, 4);
+ x = ntohl(x);
+ return x;
+ }
+ }
+}
+
+unsigned long GetRemoteSockAddress(SOCK sock) {
+ struct sockaddr_in remote_addr;
+ unsigned long remote_ip;
+
+ if (GetRemoteSockAddress(sock, (struct sockaddr *)&remote_addr) == -1) {
+ return 0;
+ }
+
+ assert(remote_addr.sin_family == AF_INET);
+ remote_ip = ntohl(remote_addr.sin_addr.s_addr);
+ return remote_ip;
+}
+
+int GetRemoteSockAddress(SOCK sock, struct sockaddr * addr) {
+ SOCKOPT_LEN_TYPE addr_len = sizeof(struct sockaddr);
+
+ if (addr == NULL) {
+ return -1;
+ }
+
+ if (getpeername(sock, addr, &addr_len) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+unsigned long GetLocalSockAddress(SOCK sock) {
+ struct sockaddr_in local_addr;
+ unsigned long local_ip;
+
+ if (GetLocalSockAddress(sock, (struct sockaddr *)&local_addr) == -1) {
+ return 0;
+ }
+
+ assert(local_addr.sin_family == AF_INET);
+ local_ip = ntohl(local_addr.sin_addr.s_addr);
+ return local_ip;
+}
+
+int GetLocalSockAddress(SOCK sock, struct sockaddr * addr) {
+ SOCKOPT_LEN_TYPE addr_len = sizeof(struct sockaddr);
+
+ if (addr == NULL) {
+ return -1;
+ }
+
+ if (getsockname(sock, addr, &addr_len) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int GetLocalMacAddress(const string dev_name, char * buf) {
+ return GetLocalMacAddress(dev_name.c_str(), buf);
+}
+
+int GetLocalMacAddress(const char * dev_name, char * buf) {
+#ifdef linux
+ struct ifreq mac_req;
+ SOCK fd = socket(AF_INET, SOCK_STREAM, 0);
+
+ snprintf(mac_req.ifr_name, IF_NAMESIZE, "%s", dev_name);
+
+ if (ioctl(fd, SIOCGIFHWADDR, &mac_req) < 0) {
+ cerr << "Error Could not get the local MAC Address" << endl;
+ perror("perror: ");
+ return -1;
+ }
+
+ memcpy(buf, mac_req.ifr_hwaddr.sa_data, 6);
+#elif WIN32
+ char temp_dev_name[256];
+ PIP_ADAPTER_INFO temp_adapter;
+ IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information
+ // for up to 16 NICs
+ DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer
+
+ DWORD dwStatus = GetAdaptersInfo(AdapterInfo, // [out] buffer to receive data
+ &dwBufLen); // [in] size of receive data buffer
+
+ assert(dwStatus == ERROR_SUCCESS); // Verify return value
+
+ temp_adapter = AdapterInfo;
+
+ while(temp_adapter) {
+ sprintf(temp_dev_name, "\\Device\\NPF_%s", temp_adapter->AdapterName);
+
+ if (strcmp(dev_name, temp_dev_name) == 0) {
+ memcpy(buf, temp_adapter->Address, 6);
+ break;
+ }
+ temp_adapter = temp_adapter->Next;
+ }
+#endif
+ return 0;
+}
+
+
+int GetOpenTcpPorts(int ** ports) {
+#ifdef linux
+ int proc_fd;
+ int num_ports = 0;
+ unsigned long rxq, txq, time_len, retr, inode, local_addr, rem_addr;
+ int d, local_port, rem_port, scan_num, timer_run, uid, timeout, state;
+ string proc_str;
+ char more[512];
+
+
+ enum {
+ TCP_ESTABLISHED = 1,
+ TCP_SYN_SENT,
+ TCP_SYN_RECV,
+ TCP_FIN_WAIT1,
+ TCP_FIN_WAIT2,
+ TCP_TIME_WAIT,
+ TCP_CLOSE,
+ TCP_CLOSE_WAIT,
+ TCP_LAST_ACK,
+ TCP_LISTEN,
+ TCP_CLOSING /* now a valid state */
+ };
+
+ /*
+ We do this because we use realloc,
+ so the first ptr-value must be null or we will realloc on some randome address
+ */
+ *ports = NULL;
+
+ proc_fd = open("/proc/net/tcp", O_RDONLY);
+ if (proc_fd == -1) {
+
+ return -1;
+ }
+ /* This supports IPv6 which we will ignore for now...
+ num = sscanf(line,
+ "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
+ &d, local_addr, &local_port, rem_addr, &rem_port, &state,
+ &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
+ */
+ GetLine(proc_fd, proc_str);
+
+ while (GetLine(proc_fd, proc_str)) {
+
+ // We pretty much stole this from netstat.c in the net-tools package
+ scan_num = sscanf(proc_str.c_str(),
+ "%d: %lX:%X %lX:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
+ &d, &local_addr, &local_port, &rem_addr, &rem_port, &state,
+ &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
+
+ if (state == TCP_LISTEN) {
+ //printf("%s (%d)\n", ip_to_string(ntohl(local_addr)), local_port);
+ *ports = (int *)realloc((*ports), sizeof(int) * (num_ports + 1));
+
+ (*ports)[num_ports] = local_port;
+
+ num_ports++;
+ }
+ }
+
+ close(proc_fd);
+ return num_ports;
+#elif WIN32
+ LPVOID error_msg;
+ DWORD table_size = 0;
+ PMIB_TCPTABLE tcp_table;
+ DWORD dwError;
+
+ // WINXP and higher
+ // AllocateAndGetTcpExTableFromStack(&tcp_table, TRUE, GetProcessHeap(), 2, 2);
+
+ dwError = GetTcpTable(NULL, &table_size, TRUE);
+ if (dwError != ERROR_INSUFFICIENT_BUFFER) {
+ cerr << "Error: " <<dwError << endl;
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &error_msg, 0, NULL );
+ cerr << (char *)error_msg << endl;
+ return -1;
+ }
+
+ tcp_table = (PMIB_TCPTABLE)malloc(table_size);
+
+ if (GetTcpTable(tcp_table, &table_size, TRUE)) {
+ return -1;
+ }
+
+ *ports = (int *)malloc(sizeof(int) * tcp_table->dwNumEntries);
+
+ for (unsigned int i = 0; i < tcp_table->dwNumEntries; i++) {
+ //cerr << htons((WORD)tcp_table->table[i].dwLocalPort) << endl;
+ (*ports)[i] = ntohs((WORD)tcp_table->table[i].dwLocalPort);
+ }
+
+ return tcp_table->dwNumEntries;
+#endif
+}
+
+int GetOpenUdpPorts(int ** ports) {
+#ifdef linux
+ int proc_fd;
+ int num_ports = 0;
+ char more[512];
+ int local_port, rem_port, d, state, timer_run, uid, timeout;
+ unsigned long local_addr, rem_addr;
+ unsigned long rxq, txq, time_len, retr, inode;
+ int scan_num;
+ string proc_str;
+ /*
+ We do this because we use realloc,
+ so the first ptr-value must be null or we will realloc on some randome address
+ */
+ *ports = NULL;
+
+ proc_fd = open("/proc/net/udp", O_RDONLY);
+ if (proc_fd == -1) {
+
+ return -1;
+ }
+
+ GetLine(proc_fd, proc_str);
+
+ while (GetLine(proc_fd, proc_str)) {
+
+ // We pretty much stole this from netstat.c in the net-tools package
+ scan_num = sscanf(proc_str.c_str(),
+ "%d: %lX:%X %lX:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
+ &d, &local_addr, &local_port,
+ &rem_addr, &rem_port, &state,
+ &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
+
+
+
+ //printf("%s (%d)\n", ip_to_string(ntohl(local_addr)), local_port);
+ if (state == 0x07) {
+ *ports = (int *)realloc((*ports), sizeof(int) * (num_ports + 1));
+
+ (*ports)[num_ports] = local_port;
+
+ num_ports++;
+ }
+ }
+
+ close(proc_fd);
+ return num_ports;
+#elif WIN32
+ LPVOID error_msg;
+ DWORD table_size = 0;
+ PMIB_UDPTABLE udp_table;
+ DWORD dwError;
+
+ // WINXP and higher
+ // AllocateAndGetTcpExTableFromStack(&tcp_table, TRUE, GetProcessHeap(), 2, 2);
+
+ dwError = GetUdpTable(NULL, &table_size, TRUE);
+ if (dwError != ERROR_INSUFFICIENT_BUFFER) {
+ cerr << "Error: " <<dwError << endl;
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &error_msg, 0, NULL );
+ cerr << (char *)error_msg << endl;
+ return -1;
+ }
+
+ udp_table = (PMIB_UDPTABLE)malloc(table_size);
+
+ if (GetUdpTable(udp_table, &table_size, TRUE)) {
+ return -1;
+ }
+
+ *ports = (int *)malloc(sizeof(int) * udp_table->dwNumEntries);
+
+ for (unsigned int i = 0; i < udp_table->dwNumEntries; i++) {
+ //cerr << htons((WORD)udp_table->table[i].dwLocalPort) << endl;
+ (*ports)[i] = ntohs((WORD)udp_table->table[i].dwLocalPort);
+ }
+
+ return udp_table->dwNumEntries;
+#endif
+}
+
+
+
+#define WELL_KNOWN_HOST ((char*)"www.cnn.com")
+#define WELL_KNOWN_PORT 80
+
+unsigned GetMyIPAddress() {
+ static unsigned adx = 0;
+ //static bool setup = false;
+ char * host;
+ short port;
+ SOCK fd;
+
+ host = getenv("RPS_WELL_KNOWN_HOST") ? getenv("RPS_WELL_KNOWN_HOST") : WELL_KNOWN_HOST;
+ port = getenv("RPS_WELL_KNOWN_PORT") ? atoi(getenv("RPS_WELL_KNOWN_PORT")) : WELL_KNOWN_PORT;
+
+ // if (setup) {
+ // return adx;
+ // } else {
+ // Connect to a well known machine and check out our socket's address
+ if ((fd = CreateAndSetupTcpSocket()) == -1) {
+ return adx;
+ } else {
+ if (ConnectToHost(fd, host, port) == -1) {
+ CLOSE(fd);
+ return adx;
+ }
+
+ adx = GetLocalSockAddress(fd);
+
+ CLOSE(fd);
+ return adx;
+ }
+ //}
+}
+
+SOCK CreateAndSetupUdpSocket(const int bufsize, const bool nonblocking) {
+ SOCK mysocket;
+ int val = 0;
+
+ // create socket for connections
+ if ((mysocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ return -1;
+ }
+
+ // set reuseaddr to avoid binding problems
+ if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(int))) {
+ return -1;
+ }
+
+ val = bufsize;
+
+ if (setsockopt(mysocket, SOL_SOCKET, SO_SNDBUF,
+ (const char*) &val, sizeof(val)) < 0) {
+ CLOSE(mysocket);
+ return -1;
+ }
+
+ val = bufsize;
+
+ if (setsockopt(mysocket, SOL_SOCKET, SO_RCVBUF,
+ (const char*)&val, sizeof(val)) < 0) {
+ CLOSE(mysocket);
+ return -1;
+ }
+
+ if (nonblocking) {
+ val = 1;
+ if (IOCTL(mysocket, FIONBIO, &val)) {
+ CLOSE(mysocket);
+ return -1;
+ }
+ }
+
+ return mysocket;
+}
+
+
+SOCK CreateAndSetupTcpSocket(const int bufsize, const bool nodelay, const bool nonblocking) {
+ SOCK mysocket;
+ int val = 1;
+
+ // create socket for connections
+ if ((mysocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ return -1;
+ }
+
+ // set reuseaddr to avoid binding problems
+ if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(int))) {
+ return -1;
+ }
+
+ // Set nodelay so that our messages get
+ if (nodelay) {
+ val = 1;
+ if (setsockopt(mysocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, sizeof(int))) {
+ CLOSE(mysocket);
+ return -1;
+ }
+ }
+
+ val = bufsize;
+
+ if (setsockopt(mysocket, SOL_SOCKET, SO_SNDBUF,
+ (const char*) &val, sizeof(val)) < 0) {
+ CLOSE(mysocket);
+ return -1;
+ }
+
+ val = bufsize;
+
+ if (setsockopt(mysocket, SOL_SOCKET, SO_RCVBUF,
+ (const char*)&val, sizeof(val)) < 0) {
+ CLOSE(mysocket);
+ return -1;
+ }
+
+ if (nonblocking) {
+ val = 1;
+ if (IOCTL(mysocket, FIONBIO, &val)) {
+ CLOSE(mysocket);
+ return -1;
+ }
+ }
+
+ return mysocket;
+}
+
+
+SOCK CreateAndSetupUnixDomainSocket(const int bufsize, const bool nonblocking) {
+ SOCK mysocket;
+ int val;
+
+ // create socket for connections
+ if ((mysocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ return -1;
+ }
+
+ // set reuseaddr to avoid binding problems
+ if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(int))) {
+ return -1;
+ }
+
+ val = bufsize;
+
+ if (setsockopt(mysocket, SOL_SOCKET, SO_SNDBUF,
+ (const char*)&val, sizeof(val)) < 0) {
+ CLOSE(mysocket);
+ return -1;
+ }
+
+ val = bufsize;
+
+ if (setsockopt(mysocket, SOL_SOCKET, SO_RCVBUF,
+ (const char*)&val, sizeof(val)) < 0) {
+ CLOSE(mysocket);
+ return -1;
+ }
+
+ if (nonblocking) {
+ val = 1;
+ if (IOCTL(mysocket, FIONBIO, &val)) {
+ CLOSE(mysocket);
+ return -1;
+ }
+ }
+
+ return mysocket;
+}
+
+
+int SetNoDelaySocket(const SOCK fd, const bool nodelay) {
+ int val = nodelay == true;
+
+ // Set nodelay so that our messages get
+ return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, sizeof(int));
+}
+
+
+int BindSocket(const SOCK mysocket, const unsigned adx, const int myport) {
+ struct sockaddr_in my_sa;
+
+ memset(&my_sa, 0, sizeof(my_sa));
+ my_sa.sin_port = htons(myport);
+ my_sa.sin_addr.s_addr = htonl(adx);
+ my_sa.sin_family = AF_INET;
+
+ if (bind(mysocket, (struct sockaddr *)&my_sa, sizeof(my_sa))) {
+ return -1;
+ }
+ return 0;
+}
+
+int BindSocket(const SOCK mysocket, const int myport) {
+ return BindSocket(mysocket, (unsigned)INADDR_ANY, myport);
+}
+
+int BindSocket(const SOCK mysocket, const char *host_or_ip, const int myport) {
+ return BindSocket(mysocket, ToIPAddress(host_or_ip), myport);
+}
+
+int BindSocket(const SOCK mysocket, const char *pathname) {
+#if defined(WIN32) && !defined(__CYGWIN__)
+ return -1;
+#else
+ struct sockaddr_un my_sa;
+ int len;
+
+ memset(&my_sa, 0, sizeof(my_sa));
+ my_sa.sun_family = AF_UNIX;
+ strcpy(my_sa.sun_path, pathname);
+ len = strlen(my_sa.sun_path) + sizeof(my_sa.sun_family);
+
+ if (bind(mysocket, (struct sockaddr *)&my_sa,len)) {
+ return -1;
+ }
+ return 0;
+#endif
+}
+
+
+int ListenSocket(const SOCK mysocket, const int maxc) {
+ int maxcon = MIN(maxc, SOMAXCONN);
+ return listen(mysocket, maxcon);
+}
+
+int ConnectToHost(const SOCK mysocket, const int hostip, const int port) {
+ struct sockaddr_in sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_port = htons(port);
+ sa.sin_addr.s_addr = htonl(hostip);
+ sa.sin_family = AF_INET;
+
+ return connect(mysocket, (struct sockaddr *)&sa, sizeof(sa));
+}
+
+
+int ConnectToHost(const SOCK mysocket, const char *host, const int port) {
+ return ConnectToHost(mysocket, ToIPAddress(host), port);
+}
+
+
+int ConnectToPath(const SOCK mysocket, const char *pathname) {
+#if defined(WIN32) && !defined(__CYGWIN__)
+ return -1;
+#else
+ struct sockaddr_un my_sa;
+ int len;
+
+ memset(&my_sa, 0, sizeof(my_sa));
+ my_sa.sun_family = AF_UNIX;
+ strcpy(my_sa.sun_path, pathname);
+ len = strlen(my_sa.sun_path) + sizeof(my_sa.sun_family);
+
+ if (connect(mysocket, (struct sockaddr *)&my_sa,len)) {
+ return -1;
+ }
+ return 0;
+#endif
+}
+
+
+
+int JoinMulticastGroup(const SOCK mysocket, const unsigned adx) {
+ if (!IsValidIPMulticastAddress(adx)) {
+ return -1;
+ }
+
+ struct ip_mreq req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.imr_multiaddr.s_addr = htonl(adx);
+ req.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if (setsockopt(mysocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (const char*)&req, sizeof(req)) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int JoinMulticastGroup(const SOCK mysocket, const char *IP) {
+ return JoinMulticastGroup(mysocket, ToIPAddress(IP));
+}
+
+
+int LeaveMulticastGroup(const SOCK mysocket, const unsigned adx) {
+ if (!IsValidIPMulticastAddress(adx)) {
+ return -1;
+ }
+
+ struct ip_mreq req;
+
+ memset(&req, 0, sizeof(req));
+
+ req.imr_multiaddr.s_addr = htonl(adx);
+ req.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if (setsockopt(mysocket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (const char *) &req, sizeof(req)) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int LeaveMulticastGroup(const SOCK mysocket, const char *IP) {
+ return LeaveMulticastGroup(mysocket, ToIPAddress(IP));
+}
+
+
+
+int SetMulticastTimeToLive(const SOCK mysocket, const unsigned char ttl) {
+ if (setsockopt(mysocket, IPPROTO_IP, IP_MULTICAST_TTL,
+ (SOCKOPT_TYPE)&ttl, (SOCKOPT_LEN_TYPE)sizeof(ttl)) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int SendTo(const SOCK mysocket,
+ const unsigned ip, const int port,
+ const char *buf, const int len, const bool sendall) {
+ struct sockaddr_in sa;
+
+ memset(&sa, 0, sizeof(sockaddr_in));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = htonl(ip);
+ sa.sin_port = htons(port);
+
+ if (!sendall) {
+ return sendto(mysocket, buf, len, 0, (struct sockaddr *)&sa, sizeof(sockaddr_in));
+ } else {
+ int left = len;
+ int sent;
+ while (left > 0) {
+ sent = sendto(mysocket, &(buf[len - left]), left, 0, (struct sockaddr *)&sa, sizeof(sockaddr_in));
+ if (sent < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ } else {
+ left -= sent;
+ }
+ }
+ return len;
+ }
+}
+
+
+int ReceiveFrom(const SOCK mysocket,
+ const unsigned ip, const int port,
+ char *buf, const int len,
+ const bool recvall)
+{
+ struct sockaddr_in sa;
+ SOCKOPT_LEN_TYPE size = sizeof(sockaddr_in);
+
+ memset(&sa, 0, sizeof(sockaddr_in));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = htonl(ip);
+ sa.sin_port = htons(port);
+
+ if (!recvall) {
+ return recvfrom(mysocket, buf, len, 0, (struct sockaddr *)&sa, &size);
+ } else {
+ int left = len;
+ int received;
+ while (left > 0) {
+ received = recvfrom(mysocket, &(buf[len - left]), left, 0, (struct sockaddr *)&sa, &size);
+ if (received < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ } else if (received == 0) {
+ break;
+ } else {
+ left -= received;
+ }
+ }
+ return len - left;
+ }
+}
+
+int SendTo(const SOCK mysocket,
+ const char *host_or_ip, const int port,
+ const char *buf, const int len, const bool sendall) {
+ return SendTo(mysocket, ToIPAddress(host_or_ip), port, buf, len, sendall);
+}
+
+int ReceiveFrom(const SOCK mysocket,
+ const char *host_or_ip, const int port,
+ char *buf, const int len, const bool recvall) {
+ return ReceiveFrom(mysocket, ToIPAddress(host_or_ip), port, buf, len, recvall);
+}
+
+
+#if defined(USE_SSL)
+
+int Send(SOCK fd, SSL *ssl, const char *buf, const int len, const bool sendall) {
+ if (!sendall) {
+ if (ssl != NULL) {
+ return SSL_write(ssl, buf, len);
+ } else {
+ return write(fd, buf, len);
+ }
+ } else {
+ int left = len;
+ int sent;
+ while (left > 0) {
+ if (ssl != NULL) {
+ sent = SSL_write(ssl, &(buf[len - left]), left);
+ } else {
+ sent = write(fd, &(buf[len - left]), left);
+ }
+
+ if (sent < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ } else if (sent == 0) {
+ break;
+ } else {
+ left -= sent;
+ }
+ }
+ return len - left;
+ }
+}
+
+int Receive(SOCK fd, SSL *ssl, char *buf, const int len, const bool recvall) {
+ if (!recvall) {
+ if (ssl != NULL) {
+ return SSL_read(ssl, buf, len);
+ } else {
+ return read(fd, buf, len);
+ }
+ } else {
+ int left = len;
+ int received;
+
+ while (left > 0) {
+ if (ssl != NULL) {
+ received = SSL_read(ssl, &(buf[len - left]), left);
+ } else {
+ received = read(fd, &(buf[len - left]), left);
+ }
+
+ if (received < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ } else if (received == 0) {
+ return 0;
+ } else {
+ left -= received;
+ }
+ }
+ return len - left;
+ }
+}
+
+
+int GetLine(SOCK fd, SSL *ssl, string &s) {
+ char c;
+ s.erase(s.begin(), s.end());
+ while (1) {
+ int rc = Receive(fd, ssl, &c, 1, true);
+ if (rc < 0) {
+ return rc;
+ }
+ if ((rc == 0) || (c == '\n')) {
+ return s.size();
+ }
+ s += c;
+ }
+}
+
+
+int PutLine(SOCK fd, SSL *ssl, const string &s) {
+ string s2 = s;
+ s2 += '\n';
+ return (Send(fd, ssl, s2.c_str(), s2.size(), true) - 1);
+}
+#endif
+
+int Send(SOCK fd, const char *buf, const int len, const bool sendall) {
+ if (!sendall) {
+ return WRITE(fd, buf, len);
+ } else {
+ int left = len;
+ int sent;
+ while (left > 0) {
+ sent = WRITE(fd, &(buf[len - left]), left);
+
+ if (sent < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ } else if (sent == 0) {
+ break;
+ } else {
+ left -= sent;
+ }
+ }
+ return len - left;
+ }
+}
+
+int Receive(SOCK fd, char *buf, const int len, const bool recvall) {
+ if (!recvall) {
+ return READ(fd, buf, len);
+ } else {
+ int left = len;
+ int received;
+
+ while (left > 0) {
+ received = READ(fd, &(buf[len - left]), left);
+
+ if (received < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ } else if (received == 0) {
+ return 0;
+ } else {
+ left -= received;
+ }
+ }
+ return len - left;
+ }
+}
+
+
+int GetLine(SOCK fd, string &s) {
+ char c;
+ s.erase(s.begin(), s.end());
+
+ while (1) {
+ int rc = Receive(fd, &c, 1, true);
+
+ if (rc < 0) {
+ return rc;
+ }
+
+ if ((rc == 0) || (c == '\n')) {
+ return s.size();
+ }
+
+ s += c;
+ }
+}
+
+
+int PutLine(SOCK fd, const string &s) {
+ string s2 = s;
+ s2 += '\n';
+ return (Send(fd, s2.c_str(), s2.size(), true) - 1);
+}
+
+
+
+
+int SetSignalHandler(const int signum, void (*handler)(int), const bool oneshot)
+{
+#if defined(WIN32) || defined(CYGWIN) // cygwin does not appear to have sigaction, so...
+ signal(signum,handler); //notice that this is oneshot
+ return 0;
+#else
+ struct sigaction sa;
+
+#if defined(__sparc__)
+ sa.sa_handler= (void (*)(...)) handler; // SUN FREAKS
+#else
+ sa.sa_handler=handler;
+#endif
+
+ sigemptyset(&(sa.sa_mask));
+#if defined(linux)
+#define SIGHAND_ONESHOT SA_ONESHOT
+#endif
+#if defined(__osf__) || defined(__FreeBSD__) || defined(__sparc__)
+#define SIGHAND_ONESHOT SA_RESETHAND
+#endif
+
+ sa.sa_flags = ((oneshot == true) ? SIGHAND_ONESHOT : 0);
+#if defined(linux)
+ sa.sa_restorer = 0;
+#endif
+
+ return sigaction(signum, &sa, 0);
+#endif
+}
+
+
+int IgnoreSignal(const int signum)
+{
+ return SetSignalHandler(signum, SIG_IGN);
+}
+
+int ListenToSignal(const int signum)
+{
+ return SetSignalHandler(signum, SIG_DFL);
+}
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+
+class SockInit {
+public:
+ SockInit() {
+ WSADATA foo;
+ WSAStartup(MAKEWORD(2,0),&foo);
+ }
+ ~SockInit() {
+ if (WSAIsBlocking()) {
+ WSACancelBlockingCall();
+ }
+ WSACleanup();
+ }
+};
+
+SockInit thesockinit; // constructor should get called on startup.
+#endif
+
+
--- /dev/null
+#ifndef _socks
+#define _socks
+
+#include "util.h"
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include <ws2tcpip.h>
+#include <Iphlpapi.h>
+#include <winsock2.h>
+#include <windows.h>
+#else
+extern "C" {
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <netinet/tcp.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/if_ether.h>
+
+#if defined(USE_SSL)
+#define OPENSSL_NO_KRB5
+#include <openssl/ssl.h>
+#endif // USE_SSL
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+}
+#endif
+
+#include <string>
+
+using namespace std;
+
+
+#define TCP 0
+#define UDP 1
+
+#define SND_RCV_SOCKET_BUF_SIZE 65536
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include <io.h>
+#define WRITE(fd,buf,len) send(fd,buf,len,0)
+#define READ(fd,buf,len) recv(fd,buf,len,0)
+//#define WRITE(fd,buf,len) _write(_open_osfhandle(fd, 0),buf,len)
+//#define READ(fd,buf,len) _read(_open_osfhandle(fd, 0),buf,len)
+
+#define SOCK SOCKET
+
+#define CLOSE(x) closesocket(x)
+#define IOCTL(x,y,z) ioctlsocket((SOCKET)x,(long)y,(unsigned long *)z)
+#else
+
+#define SOCK int
+
+#if defined(USE_SSL)
+#define WRITE(ssl,buf,len) write(ssl, buf, len)
+#else
+#define WRITE(fd,buf,len) write(fd, buf, len)
+#endif
+
+#define READ(fd,buf,len) read(fd, buf, len)
+#define CLOSE(x) close(x)
+#define IOCTL(x,y,z) ioctl(x, y, z)
+#endif
+
+
+SOCK CreateAndSetupTcpSocket(const int bufsize=SND_RCV_SOCKET_BUF_SIZE,
+ const bool nodelay=true,
+ const bool nonblocking=false);
+
+SOCK CreateAndSetupUdpSocket(const int bufsize=SND_RCV_SOCKET_BUF_SIZE,
+ const bool nonblocking=false);
+
+SOCK CreateAndSetupUnixDomainSocket(const int bufsize=SND_RCV_SOCKET_BUF_SIZE,
+ const bool nonblocking=false);
+
+int SetNoDelaySocket(const SOCK fd, const bool nodelay=true);
+
+int IsSocket(const SOCK fd);
+int IsStreamSocket(const SOCK fd);
+int IsDatagramSocket(const SOCK fd);
+
+#ifdef linux
+int IsVirtualSocket(const int fd);
+#endif
+
+int BindSocket(const SOCK mysocket, const int myport);
+int BindSocket(const SOCK mysocket, const unsigned adx, const int myport);
+int BindSocket(const SOCK mysocket, const char *host_or_ip, const int myport);
+int BindSocket(const SOCK mysocket, const char *pathname);
+
+int ListenSocket(const SOCK mysocket, const int max=SOMAXCONN);
+
+int ConnectToHost(const SOCK mysocket, const int hostip, const int port);
+int ConnectToHost(const SOCK mysocket, const char *host, const int port);
+int ConnectToPath(const SOCK mysocket, const char *pathname);
+
+#if defined(USE_SSL)
+int Send(const SOCK fd, SSL *ssl, const char *buf, const int len, bool sendall=true);
+int Receive(const SOCK fd, SSL *ssl, char *buf, const int len, bool recvall=true);
+#endif
+int Send(const SOCK fd, const char *buf, const int len, bool sendall=true);
+int Receive(const SOCK fd, char *buf, const int len, bool recvall=true);
+
+
+
+int SendTo(const SOCK mysocket,
+ const unsigned ip, const int port,
+ const char *buf, const int len, bool sendall=true);
+int ReceiveFrom(const SOCK mysocket,
+ const unsigned ip, const int port,
+ char *buf, const int len, const bool recvall=true);
+int SendTo(const SOCK mysocket,
+ const char *host_or_ip, const int port,
+ const char *buf, const int len, const bool sendall=true);
+int ReceiveFrom(const SOCK mysocket,
+ const char *host_or_ip, const int port,
+ char *buf, const int len, const bool recvall=true);
+
+
+int JoinMulticastGroup(const SOCK mysocket, const char *IP);
+int JoinMulticastGroup(const SOCK mysocket, const unsigned adx);
+int LeaveMulticastGroup(const SOCK mysocket, const char *IP);
+int LeaveMulticastGroup(const SOCK mysocket, const unsigned adx);
+int SetMulticastTimeToLive(const SOCK mysocket, const unsigned char ttl);
+
+
+
+unsigned long GetRemoteSockAddress(SOCK sock);
+int GetRemoteSockAddress(SOCK sock, struct sockaddr * addr);
+
+unsigned long GetLocalSockAddress(SOCK sock);
+int GetLocalSockAddress(SOCK sock, struct sockaddr * addr);
+int GetLocalMacAddress(const string dev_name, char * buf);
+int GetLocalMacAddress(const char * dev_name, char * buf);
+unsigned GetMyIPAddress();
+unsigned ToIPAddress(const char *hostname);
+void PrintIPAddress(const unsigned adx, FILE *out=stderr);
+void IPToHostname(const unsigned ip, char *name, const int namesize);
+int IsValidIPMulticastAddress(const unsigned ipadx);
+
+
+int GetOpenTcpPorts(int ** ports);
+int GetOpenUdpPorts(int ** ports);
+int IsPortOpen(int port_num, int proto = TCP);
+
+
+int SetSignalHandler(const int signum, void (*handler)(int), const bool oneshot=false);
+int IgnoreSignal(const int signum);
+int ListenToSignal(const int signum);
+
+#if defined(USE_SSL)
+int GetLine(SOCK fd, SSL *ssl, string &s);
+int PutLine(SOCK fd, SSL *ssl, const string &s);
+#endif
+
+int GetLine(SOCK fd, string &s);
+int PutLine(SOCK fd, const string &s);
+
+
+#endif
--- /dev/null
+#include "vtl_ack.h"
+
+
+int make_ack_pkt(tcp_model_t * model, RawEthernetPacket * data_pkt, RawEthernetPacket * ack_pkt) {
+ unsigned long * seq_num_ptr ;
+ unsigned long seq_num = 0;
+ unsigned long rem_seq_num = 0;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned long ack = 0;
+ unsigned long local_ts = 0;
+ unsigned short tcp_cksum = 0;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short ip_pkt_len = *(unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ unsigned short ack_ip_pkt_len = *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 2);
+ unsigned char ack_ip_hdr_len = IP_HDR_LEN(ack_pkt->data);
+
+ ip_pkt_len = ntohs(ip_pkt_len);
+ ack_ip_pkt_len = ntohs(ack_ip_pkt_len);
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Sequence Number = %lu\n", seq_num);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+
+ if (is_syn_pkt(pkt) == 1) {
+ ack = seq_num + 1;
+ } else {
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
+ JRLDBG("Payload Length = %lu\n", payload_len);
+
+ ack = seq_num + payload_len;
+ JRLDBG("Ack Num = %lu\n", ack);
+ }
+
+ // Set IP id
+ g_vtp_cons[vcon_i].ip_id--;
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 4) = htons(g_vtp_cons[vcon_i].ip_id);
+
+ // Recompute IP checksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = 0;
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = get_ip_checksum(ack_pkt);
+
+ //return 0;
+ // Set Sequence Number
+ rem_seq_num = htonl(g_vtp_cons[vcon_i].rem_seq_num);
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 4) = rem_seq_num;
+
+ // Set ACK Number
+ ack = htonl(ack);
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 8) = ack;
+
+ // Set TCP Timestamp option
+ local_ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 20, tcp_hdr_len - 20);
+
+ /* We use this for debugging:
+ * If the TCPDump trace shows timestamps with the value of '5' then they are our packets
+ */
+
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 24) = g_vtp_cons[vcon_i].tcp_timestamp;
+ //*(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ip_hdr_len + 24) = htonl(5);
+
+
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 28) = local_ts;
+
+ // Zero TCP chksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = 0;
+
+ // Get TCP chksum
+ tcp_cksum = get_tcp_checksum(ack_pkt, ack_ip_pkt_len - ack_ip_hdr_len);
+
+ // Set TCP chksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = tcp_cksum;
+
+
+}
--- /dev/null
+#ifndef VTL_ACK_H
+#define VTL_ACK_H
+
+#include "vtl.h"
+
+
+int make_ack_pkt(RawEthernetPacket * data_pkt, RawEthernetPacket * ack_pkt);
+
+
+
+#endif
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+
+#include "vtl.h"
+#include "vtl_harness.h"
+
+DEBUG_DECLARE();
+
+
+
+/* Connection List Handling */
+struct VTL_CON g_vtl_cons[MAX_VTL_CONS];
+int g_first_vtl;
+int g_last_vtl;
+int g_num_vtl_cons;
+
+int add_vtl_con(RawEthernetPacket * pkt);
+int find_vtl_con(RawEthernetPacket * pkt);
+
+/* Packet Handlers */
+int handle_local_tcp_pkt(RawEthernetPacket * pkt, iface_t * dev);
+int handle_remote_tcp_pkt(RawEthernetPacket * pkt);
+
+/* Packet functions */
+int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i);
+int init_ack_template(RawEthernetPacket * pkt);
+
+
+unsigned short ip_id_ctr = 1;
+
+int main(int argc, char ** argv) {
+ RawEthernetPacket pkt;
+ RawEthernetPacket ack_pkt;
+ int i = 0;
+ iface_t * dev;
+ unsigned long src_addr;
+
+ debug_init("./vtl.log");
+
+ JRLDBG("Starting VTP Daemon\n");
+
+ for (i = 0; i < MAX_VTL_CONS; i++) {
+ g_vtl_cons[i].con_model.type = TCP_MODEL;
+ g_vtl_cons[i].in_use = false;
+ g_vtl_cons[i].next = -1;
+ g_vtl_cons[i].prev = -1;
+ }
+
+ g_last_vtl = -1;
+ g_first_vtl = -1;
+
+ g_num_vtl_cons = 0;
+
+ src_addr = ToIPAddress(argv[2]);
+ dev = if_connect(argv[1]);
+
+ while (if_read_pkt(dev, &pkt) != -1) {
+
+
+
+ if (is_tcp_pkt(&pkt)) {
+ if (GET_IP_SRC(pkt.data) == src_addr) {
+ handle_local_tcp_pkt(&pkt, dev);
+ } else if (GET_IP_DST(pkt.data) == src_addr) {
+ if (GET_IP_ID(pkt.data) == ip_id_ctr -1) {
+ continue;
+ }
+ handle_remote_tcp_pkt(&pkt);
+ printf("Remote tcp packet\n");
+ }
+ }
+ }
+
+
+ fclose(logfile);
+
+
+ return(0);
+}
+
+
+int handle_local_tcp_pkt(RawEthernetPacket * pkt, iface_t * dev) {
+ printf("local tcp pkt\n");
+ RawEthernetPacket ack_pkt;
+
+ int index = find_vtl_con(pkt);
+
+ if (index != -1) {
+ // packet in the system
+ sync_model(&(g_vtl_cons[index].con_model), pkt);
+
+
+ // dbg_dump_model(&(g_vtl_cons[index].con_model));
+ if (GET_TCP_DATA_LEN(pkt->data) > 0) {
+ create_empty_pkt(&(g_vtl_cons[index].con_model), &ack_pkt, INBOUND_PKT);
+ dbg_print_pkt_info(&ack_pkt);
+ if_write_pkt(dev, &ack_pkt);
+
+ }
+ } else {
+ if (is_syn_pkt(pkt)) {
+ int index = -1;
+
+ index = add_vtl_con(pkt);
+ printf("Connection added at %d\n", index);
+
+
+ }
+ }
+
+ return 0;
+
+}
+
+int handle_remote_tcp_pkt(RawEthernetPacket * pkt) {
+ int index;
+
+ index = find_vtl_con(pkt);
+
+ if (index != -1) {
+ sync_model(&(g_vtl_cons[index].con_model), pkt);
+ g_vtl_cons[index].con_model.model.ip_model.dst.ip_id = ip_id_ctr++;
+ }
+
+ return 0;
+}
+
+
+
+int find_vtl_con(RawEthernetPacket * pkt) {
+ int index = -1;
+ int i = 0;
+
+
+ FOREACH_VTL_CON(i,g_vtl_cons) {
+ if (is_model_pkt(&(g_vtl_cons[i].con_model), pkt)) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+}
+
+
+
+int add_vtl_con(RawEthernetPacket * pkt) {
+ int i;
+
+ for (i = 0; i < MAX_VTL_CONS; i++) {
+ if (!(g_vtl_cons[i].in_use)) {
+ JRLDBG("Adding connection in slot %d\n", i);
+
+ initialize_model(&(g_vtl_cons[i].con_model), pkt);
+ g_vtl_cons[i].in_use = true;
+
+ dbg_dump_model(&(g_vtl_cons[i].con_model));
+
+ if (g_first_vtl == -1)
+ g_first_vtl = i;
+
+ g_vtl_cons[i].prev = g_last_vtl;
+ g_vtl_cons[i].next = -1;
+
+ if (g_last_vtl != -1) {
+ g_vtl_cons[g_last_vtl].next = i;
+ }
+
+ g_last_vtl = i;
+
+ g_num_vtl_cons++;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+
+/*
+
+
+int handle_tcp_pkt(RawEthernetPacket *pkt) {
+
+
+ unsigned short ip_pkt_len = 0;
+ // unsigned char ip_hdr_len = (*(pkt->data + ETH_HDR_LEN) & 0x0f) << 2;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ ip_pkt_len = ntohs(*ip_pkt_len_ptr);
+
+ JRLDBG("IP Header Length = %d(%x)\n", ip_hdr_len, *(pkt->data + ETH_HDR_LEN));
+ JRLDBG("IP Packet Length = %hu\n", ip_pkt_len);
+
+ if (is_syn_pkt(pkt) == 0) {
+ // we don't mess with connection establishment
+ int vcon_i;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ struct in_addr tmp;
+
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ if ((payload_len == 0) && (is_ack_pkt(pkt) == 1)) {
+ // we just kill empty acks.
+ //return 0;
+ }
+
+ vcon_i = find_remote_vtp_con(pkt);
+
+ // Create ACK and send it.
+ make_ack_pkt(pkt, vcon_i);
+
+ g_vtl_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp);
+
+ } else {
+ if(is_ack_pkt(pkt) == 1) {
+ int vcon_i = find_remote_vtp_con(pkt);
+ struct in_addr tmp;
+ make_ack_pkt(pkt, vcon_i);
+
+ g_vtl_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp);
+ }
+#ifdef DEBUG
+ unsigned long * seq_num_ptr ;
+ unsigned long seq_num = 0;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned long ack = 0;
+
+ JRLDBG("Packet is a Syn Packet\n");
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Sequence Number = %lu\n", seq_num);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
+ JRLDBG("Payload Length = %lu\n", payload_len);
+
+
+
+ ack = (payload_len > 0) ? (seq_num + payload_len) : (seq_num + 1);
+ JRLDBG("Ack Num = %lu\n", ack);
+#endif
+ }
+
+ return 0;
+}
+
+int handle_rem_tcp_pkt(RawEthernetPacket * pkt) {
+ unsigned long * seq_num_ptr;
+ unsigned long seq_num;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Received Packet, SeqNum = %lu\n", seq_num);
+
+ if (is_syn_pkt(pkt) == 1) {
+ // syn packet
+ seq_num++;
+ add_vtp_con(pkt, seq_num);
+ JRLDBG("Received Syn Packet, SeqNum = %lu\n", seq_num);
+ } else {
+ unsigned short ip_pkt_len = 0;
+ unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ int i_vcon = find_vtp_con(pkt);
+
+ ip_pkt_len = ntohs(*ip_pkt_len_ptr);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+
+ if (tcp_hdr_len > 20) {
+ unsigned long ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ip_hdr_len + 20, tcp_hdr_len - 20);
+ JRLDBG("TCP Timestamp = %lu(%lu)\n", ts, (unsigned long)ntohl(ts));
+ g_vtl_cons[i_vcon].tcp_timestamp = ts;
+ }
+
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+ seq_num += payload_len;
+ JRLDBG("Received Data Packet, SeqNum = %lu\n", seq_num);
+ g_vtl_cons[i_vcon].rem_seq_num = seq_num;
+ JRLDBG("Remote Sequence Number (con: %d) = %lu\n", i_vcon, seq_num);
+
+#if 0
+ {
+ int offset = 0;
+ unsigned short tcp_cksum = 0;
+ // Zero Ack Field
+ *(unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 8) = 0;
+
+ // Zero Ack Flag
+ offset = ETH_HDR_LEN + ip_hdr_len + 13;
+ *(pkt->data + offset) &= 0xef;
+
+ // Zero TCP chksum
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = 0;
+
+ // Get TCP chksum
+ tcp_cksum = get_tcp_checksum(pkt, ip_pkt_len - ip_hdr_len);
+
+ // Set TCP chksum
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = tcp_cksum;
+ }
+#endif
+
+
+ }
+ return 0;
+}
+
+
+
+int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i) {
+ unsigned long * seq_num_ptr ;
+ unsigned long seq_num = 0;
+ unsigned long rem_seq_num = 0;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned long ack = 0;
+ unsigned long local_ts = 0;
+ unsigned short tcp_cksum = 0;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short ip_pkt_len = *(unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ RawEthernetPacket * ack_pkt = &(g_vtl_cons[vcon_i].ack_template);
+ unsigned short ack_ip_pkt_len = *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 2);
+ unsigned char ack_ip_hdr_len = IP_HDR_LEN(ack_pkt->data);
+
+ ip_pkt_len = ntohs(ip_pkt_len);
+ ack_ip_pkt_len = ntohs(ack_ip_pkt_len);
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Sequence Number = %lu\n", seq_num);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+
+ if (is_syn_pkt(pkt) == 1) {
+ ack = seq_num + 1;
+ } else {
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
+ JRLDBG("Payload Length = %lu\n", payload_len);
+
+ ack = seq_num + payload_len;
+ JRLDBG("Ack Num = %lu\n", ack);
+ }
+
+ // Set IP id
+ g_vtl_cons[vcon_i].ip_id--;
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 4) = htons(g_vtl_cons[vcon_i].ip_id);
+
+ // Recompute IP checksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = 0;
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = get_ip_checksum(ack_pkt);
+
+ //return 0;
+ // Set Sequence Number
+ rem_seq_num = htonl(g_vtl_cons[vcon_i].rem_seq_num);
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 4) = rem_seq_num;
+
+ // Set ACK Number
+ ack = htonl(ack);
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 8) = ack;
+
+ // Set TCP Timestamp option
+ local_ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 20, tcp_hdr_len - 20);
+
+ // We use this for debugging:
+ // If the TCPDump trace shows timestamps with the value of '5' then they are our packets
+ //
+
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 24) = g_vtl_cons[vcon_i].tcp_timestamp;
+// *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ip_hdr_len + 24) = htonl(5);
+
+
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 28) = local_ts;
+
+ // Zero TCP chksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = 0;
+
+ // Get TCP chksum
+ tcp_cksum = get_tcp_checksum(ack_pkt, ack_ip_pkt_len - ack_ip_hdr_len);
+
+ // Set TCP chksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = tcp_cksum;
+
+ return 0;
+}
+
+
+
+
+
+// Connection List Handling //
+
+
+
+int init_ack_template(RawEthernetPacket * pkt) {
+ // We assume here that the ethernet and ip headers are ok, except for ip pkt length
+ // TCP is mostly right because its pulled off of a syn packet
+ // we need to zero the data, and reset the syn flag.
+
+ unsigned short IP_PACKET_LEN = 52;
+ unsigned short TCP_HEADER_LEN = 32;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short ip_pkt_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned short payload_len = 0;
+ unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ unsigned int offset = 0;
+ unsigned short ip_chksum = 0;
+
+ JRLDBG("--> Initializing ACK Template <--\n");
+
+ ip_pkt_len = ntohs(*ip_pkt_len_ptr);
+ JRLDBG("ip_pkt_len = %hu\n", ip_pkt_len);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+ JRLDBG("tcp_hdr_len = %hu\n", tcp_hdr_len);
+ JRLDBG("payload_len = %hu\n", payload_len);
+
+ // set only the ack flags
+ offset = ETH_HDR_LEN + ip_hdr_len + 13;
+ *(pkt->data + offset) |= 0x10;
+ *(pkt->data + offset) &= 0xd0;
+
+ // set up tcp options
+ offset = ETH_HDR_LEN + ip_hdr_len + 20;
+ *(pkt->data + offset) = 0x01;
+ offset++;
+ *(pkt->data + offset) = 0x01;
+ offset++;
+ *(pkt->data + offset) = 0x08;
+ offset++;
+ *(pkt->data + offset) = 0x0a;
+
+ // Set Header Lengths
+ // IP HEADER = 20 (same)
+ // IP PACKET LEN = 52
+ // TCP Header len = 32
+
+ ip_pkt_len = htons(IP_PACKET_LEN);
+ memcpy(pkt->data + ETH_HDR_LEN + 2, &ip_pkt_len, 2);
+ tcp_hdr_len = (TCP_HEADER_LEN << 2);
+ *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) &= 0x0f;
+ *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) |= tcp_hdr_len;
+
+ JRLDBG("Setting TEMPLATE TCPLEN = %2x\n", *(pkt->data + ETH_HDR_LEN +ip_hdr_len + 12));
+
+ // Set IP Header chksum
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = 0;
+ ip_chksum = get_ip_checksum(pkt);
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = ip_chksum;
+
+
+ // Set RawEthernetPacket size
+ pkt->set_size(IP_PACKET_LEN + ETH_HDR_LEN);
+ pkt->set_type("et");
+
+ JRLDBG("--> ACK Template Initialized <--\n");
+
+
+ return 0;
+}
+
+*/
--- /dev/null
+#include "vtl_util.h"
+#include "if.h"
+#include "debug.h"
+
+
+#define IFACE_NAME "vmnet1"
+
+DEBUG_DECLARE();
+
+int main(int argc, char ** argv) {
+ RawEthernetPacket pkt;
+
+ char * iface_name = IFACE_NAME;
+
+ if (argc == 2) {
+ iface_name = argv[1];
+ }
+ iface_t * iface = if_connect(iface_name, IF_RW);
+
+ debug_init("./vtp.log");
+
+ while (if_read_pkt(iface, &pkt) == 0) {
+
+ printf("READ packet\n");
+ if (is_tcp_pkt(&pkt)) {
+ printf("TCP!!\n");
+ }
+
+
+
+
+ }
+
+}
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef linux
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#endif
+
+#include "vtl_harness.h"
+
+DEBUG_DECLARE();
+
+
+#define F_NONE 0
+#define F_LOCAL_ACK 1
+
+unsigned short g_fflags;
+
+
+int g_do_local_ack = 0;
+/* IP Address utility functions */
+
+
+
+/* Global Pipe Descriptors */
+int vtp_in_fd, vtp_out_fd;
+
+
+/* Connection List Handling */
+struct VTP_CON g_vtp_cons[MAX_VTP_CONS];
+int g_first_vtp;
+int g_last_vtp;
+int g_num_vtp_cons;
+
+int add_vtp_con(RawEthernetPacket * pkt, unsigned long seq_num);
+int find_vtp_con(RawEthernetPacket * pkt);
+int find_remote_vtp_con(RawEthernetPacket * pkt);
+
+/* Packet Handlers */
+int handle_fifo_pkt(RawEthernetPacket * pkt, struct in_addr server_addr);
+int handle_tcp_pkt(RawEthernetPacket * pkt, struct in_addr server_addr);
+int handle_rem_tcp_pkt(RawEthernetPacket * pkt);
+int handle_control_pkt(RawEthernetPacket * pkt, struct in_addr server_addr);
+int handle_config_pkt(RawEthernetPacket * pkt);
+
+/* Packet functions */
+int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i);
+int init_ack_template(RawEthernetPacket * pkt);
+
+
+int main(int argc, char ** argv) {
+
+ fd_set all_set, rset;
+ int maxfd = 0;
+ int conns;
+ timeval timeout;
+ timeval * tm_ptr;
+ RawEthernetPacket pkt;
+ RawEthernetPacket * recv_pkts;
+ int vtp_socket;
+ int i = 0;
+
+ debug_init("/tmp/vtp.1");
+
+ JRLDBG("Starting VTP Daemon\n");
+
+ for (i = 0; i < MAX_VTP_CONS; i++) {
+ g_vtp_cons[i].rem_seq_num = 0;
+ g_vtp_cons[i].dest_ip = 0;
+ g_vtp_cons[i].src_ip = 0;
+ g_vtp_cons[i].src_port = 0;
+ g_vtp_cons[i].dest_port = 0;
+ g_vtp_cons[i].tcp_timestamp = 0;
+ g_vtp_cons[i].in_use = false;
+ g_vtp_cons[i].next = -1;
+ g_vtp_cons[i].prev = -1;
+ }
+
+ g_last_vtp = -1;
+ g_first_vtp = -1;
+
+ g_num_vtp_cons = 0;
+
+ vtp_in_fd = open(VTP_FIFO_RECVFILE, O_WRONLY);
+ JRLDBG("Opened RECVFILE pipe\n");
+
+ vtp_out_fd = open(VTP_FIFO_SENDFILE, O_RDONLY);
+ JRLDBG("Opened SENDFILE pipe\n");
+
+
+ if ((vtp_socket = vtp_init()) < 0) {
+ JRLDBG("VTP Transport Layer failed to initialize\n");
+ exit(-1);
+ }
+
+ FD_ZERO(&all_set);
+ FD_SET(vtp_out_fd, &all_set);
+
+ if (vtp_socket > 0) {
+ FD_SET(vtp_socket, &all_set);
+
+ maxfd = (vtp_out_fd > vtp_socket) ? vtp_out_fd : vtp_socket ;
+
+ // block indefinately, because we have all the socks in the FDSET
+ tm_ptr = NULL;
+ } else {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ tm_ptr = &timeout;
+ }
+
+
+ while(1) {
+ int n_pkts_recvd = 0;
+ rset = all_set;
+
+ conns = select(maxfd + 1, &rset, NULL, NULL, tm_ptr);
+ if ((conns > 0) && (FD_ISSET(vtp_out_fd, &rset))) {
+ struct in_addr server_addr;
+ JRLDBG("Reception on vtp_out_fd\n");
+ // we got a packet on the FIFO
+ if (pkt.VtpUnserialize(vtp_out_fd, &server_addr) <= 0) {
+ JRLDBG("VNET Connection has closed. We are exiting\n");
+ exit(0);
+ }
+ handle_fifo_pkt(&pkt, server_addr);
+ }
+
+ //JRLDBG("Calling VTP Receive routine\n");
+ if ((vtp_socket == 0) || ((conns > 0) && (vtp_socket > 0) && FD_ISSET(vtp_socket, &rset))) {
+ if ((n_pkts_recvd = vtp_recv(&recv_pkts)) > 0) {
+ int i = 0;
+ struct in_addr tmp;
+ JRLDBG("Receive returned %d packets\n", n_pkts_recvd);
+
+ for (i = 0; i < n_pkts_recvd; i++) {
+
+ if (is_tcp_pkt(&(recv_pkts[i])) == 1) {
+ JRLDBG("Received a TCP packet\n");
+ if (g_do_local_ack == 1) {
+ handle_rem_tcp_pkt(&(recv_pkts[i]));
+ }
+ }
+
+ JRLDBG("Serializing packet %d to VNET\n", i);
+ recv_pkts[i].VtpSerialize(vtp_in_fd, &tmp);
+ usleep(50000);
+ }
+
+ //delete recv_pkts;
+ }
+ }
+ }
+
+ fclose(logfile);
+ close(vtp_in_fd);
+ close(vtp_out_fd);
+
+ return(0);
+}
+
+int handle_fifo_pkt(RawEthernetPacket * pkt, struct in_addr server_addr) {
+ JRLDBG("Received a packet\n");
+ // if (strncmp(pkt->type,"et",2) == 0) {
+ if ((pkt->type[0] == 'e') && (pkt->type[1] == 't')) {
+ JRLDBG("Packet is Ethernet\n");
+ if (is_tcp_pkt(pkt) == 0) {
+ JRLDBG("Packet is a non-TCP Packet\n");
+ vtp_send(pkt, server_addr);
+ } else {
+ JRLDBG("Packet is a TCP Packet\n");
+ handle_tcp_pkt(pkt, server_addr);
+ }
+
+ } else if (strncmp(pkt->type,"lc",2) == 0) {
+ JRLDBG("Packet is a Link Control Packet\n");
+ handle_control_pkt(pkt, server_addr);
+ } else if (strncmp(pkt->type, "cf", 2) == 0) {
+ JRLDBG("Packet is a Configuration packet\n");
+ handle_config_pkt(pkt);
+ }
+ return 0;
+}
+
+
+int handle_config_pkt(RawEthernetPacket * pkt) {
+
+ return 0;
+}
+
+
+int handle_control_pkt(RawEthernetPacket* pkt, struct in_addr server_addr) {
+ if (strncmp(pkt->data,"con",3) == 0) {
+ struct in_addr con_addr;
+ unsigned short con_port = 0;
+ unsigned int offset = 3;
+#ifdef DEBUG
+ char ip[256];
+ do_binary_to_string((unsigned char*)(&server_addr),ip);
+ JRLDBG("Control Message: Connect to %s\n", ip);
+#endif
+ memcpy(&con_addr, pkt->data + offset,sizeof(struct in_addr));
+ offset += sizeof(struct in_addr);
+ con_port = *((unsigned short *)(pkt->data + offset));
+
+ vtp_connect(con_addr, con_port);
+ } else if (strncmp(pkt->data, "gwc", 3) == 0) {
+ struct in_addr con_addr;
+ unsigned short con_port;
+ unsigned int offset = 3;
+
+ memcpy(&con_addr, pkt->data + offset, sizeof(struct in_addr));
+ offset += sizeof(struct in_addr);
+ con_port = *((unsigned short *)(pkt->data + offset));
+
+ vtp_connect(con_addr, con_port);
+
+ } else if (strncmp(pkt->data, "stop", 4) == 0) {
+ exit(0);
+ }
+
+ return 0;
+}
+
+
+int handle_tcp_pkt(RawEthernetPacket *pkt, struct in_addr server_addr) {
+
+ if (g_do_local_ack == 1) {
+ unsigned short ip_pkt_len = 0;
+ // unsigned char ip_hdr_len = (*(pkt->data + ETH_HDR_LEN) & 0x0f) << 2;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ ip_pkt_len = ntohs(*ip_pkt_len_ptr);
+
+ JRLDBG("IP Header Length = %d(%x)\n", ip_hdr_len, *(pkt->data + ETH_HDR_LEN));
+ JRLDBG("IP Packet Length = %hu\n", ip_pkt_len);
+
+ if (is_syn_pkt(pkt) == 0) {
+ // we don't mess with connection establishment
+ int vcon_i;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ struct in_addr tmp;
+
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ if ((payload_len == 0) && (is_ack_pkt(pkt) == 1)) {
+ // we just kill empty acks.
+ //return 0;
+ }
+
+ vcon_i = find_remote_vtp_con(pkt);
+
+ // Create ACK and send it.
+ make_ack_pkt(pkt, vcon_i);
+
+ g_vtp_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp);
+
+ } else {
+ if(is_ack_pkt(pkt) == 1) {
+ int vcon_i = find_remote_vtp_con(pkt);
+ struct in_addr tmp;
+ make_ack_pkt(pkt, vcon_i);
+
+ g_vtp_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp);
+ }
+#ifdef DEBUG
+ unsigned long * seq_num_ptr ;
+ unsigned long seq_num = 0;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned long ack = 0;
+
+ JRLDBG("Packet is a Syn Packet\n");
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Sequence Number = %lu\n", seq_num);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
+ JRLDBG("Payload Length = %lu\n", payload_len);
+
+
+
+ ack = (payload_len > 0) ? (seq_num + payload_len) : (seq_num + 1);
+ JRLDBG("Ack Num = %lu\n", ack);
+#endif
+ }
+
+ }
+
+ vtp_send(pkt, server_addr);
+
+ return 0;
+}
+
+int handle_rem_tcp_pkt(RawEthernetPacket * pkt) {
+ unsigned long * seq_num_ptr;
+ unsigned long seq_num;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Received Packet, SeqNum = %lu\n", seq_num);
+
+ if (is_syn_pkt(pkt) == 1) {
+ // syn packet
+ seq_num++;
+ add_vtp_con(pkt, seq_num);
+ JRLDBG("Received Syn Packet, SeqNum = %lu\n", seq_num);
+ } else {
+ unsigned short ip_pkt_len = 0;
+ unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ int i_vcon = find_vtp_con(pkt);
+
+ ip_pkt_len = ntohs(*ip_pkt_len_ptr);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+
+ if (tcp_hdr_len > 20) {
+ unsigned long ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ip_hdr_len + 20, tcp_hdr_len - 20);
+ JRLDBG("TCP Timestamp = %lu(%lu)\n", ts, (unsigned long)ntohl(ts));
+ g_vtp_cons[i_vcon].tcp_timestamp = ts;
+ }
+
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+ seq_num += payload_len;
+ JRLDBG("Received Data Packet, SeqNum = %lu\n", seq_num);
+ g_vtp_cons[i_vcon].rem_seq_num = seq_num;
+ JRLDBG("Remote Sequence Number (con: %d) = %lu\n", i_vcon, seq_num);
+
+#if 0
+ {
+ int offset = 0;
+ unsigned short tcp_cksum = 0;
+ // Zero Ack Field
+ *(unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 8) = 0;
+
+ // Zero Ack Flag
+ offset = ETH_HDR_LEN + ip_hdr_len + 13;
+ *(pkt->data + offset) &= 0xef;
+
+ // Zero TCP chksum
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = 0;
+
+ // Get TCP chksum
+ tcp_cksum = get_tcp_checksum(pkt, ip_pkt_len - ip_hdr_len);
+
+ // Set TCP chksum
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = tcp_cksum;
+ }
+#endif
+
+
+ }
+ return 0;
+}
+
+
+
+int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i) {
+ unsigned long * seq_num_ptr ;
+ unsigned long seq_num = 0;
+ unsigned long rem_seq_num = 0;
+ unsigned long payload_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned long ack = 0;
+ unsigned long local_ts = 0;
+ unsigned short tcp_cksum = 0;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short ip_pkt_len = *(unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ RawEthernetPacket * ack_pkt = &(g_vtp_cons[vcon_i].ack_template);
+ unsigned short ack_ip_pkt_len = *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 2);
+ unsigned char ack_ip_hdr_len = IP_HDR_LEN(ack_pkt->data);
+
+ ip_pkt_len = ntohs(ip_pkt_len);
+ ack_ip_pkt_len = ntohs(ack_ip_pkt_len);
+
+ seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
+ seq_num = ntohl(*seq_num_ptr);
+ JRLDBG("Sequence Number = %lu\n", seq_num);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+
+ if (is_syn_pkt(pkt) == 1) {
+ ack = seq_num + 1;
+ } else {
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+
+ JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
+ JRLDBG("Payload Length = %lu\n", payload_len);
+
+ ack = seq_num + payload_len;
+ JRLDBG("Ack Num = %lu\n", ack);
+ }
+
+ // Set IP id
+ g_vtp_cons[vcon_i].ip_id--;
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 4) = htons(g_vtp_cons[vcon_i].ip_id);
+
+ // Recompute IP checksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = 0;
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = get_ip_checksum(ack_pkt);
+
+ //return 0;
+ // Set Sequence Number
+ rem_seq_num = htonl(g_vtp_cons[vcon_i].rem_seq_num);
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 4) = rem_seq_num;
+
+ // Set ACK Number
+ ack = htonl(ack);
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 8) = ack;
+
+ // Set TCP Timestamp option
+ local_ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 20, tcp_hdr_len - 20);
+
+ /* We use this for debugging:
+ * If the TCPDump trace shows timestamps with the value of '5' then they are our packets
+ */
+
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 24) = g_vtp_cons[vcon_i].tcp_timestamp;
+ //*(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ip_hdr_len + 24) = htonl(5);
+
+
+ *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 28) = local_ts;
+
+ // Zero TCP chksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = 0;
+
+ // Get TCP chksum
+ tcp_cksum = get_tcp_checksum(ack_pkt, ack_ip_pkt_len - ack_ip_hdr_len);
+
+ // Set TCP chksum
+ *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = tcp_cksum;
+
+ return 0;
+}
+
+
+
+
+
+/* Connection List Handling */
+
+int find_vtp_con(RawEthernetPacket * pkt) {
+ int index = -1;
+ int i = 0;
+ unsigned long * src_addr;
+ unsigned long * dest_addr;
+ unsigned short * src_port;
+ unsigned short * dest_port;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+
+ src_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 12);
+ dest_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 16);
+ src_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len);
+ dest_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 2);
+
+ // for (i = 0; i < MAX_CONS; i++) {
+ FOREACH_VTP_CON(i,g_vtp_cons) {
+ if ((g_vtp_cons[i].dest_ip == *dest_addr) && (g_vtp_cons[i].src_ip == *src_addr) &&
+ (g_vtp_cons[i].dest_port = *dest_port) && (g_vtp_cons[i].src_port == *src_port)) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+}
+
+
+/* An received packet has the header fields reversed wrt src/dest
+ * So we have to be able to index remote packets as well
+ */
+int find_remote_vtp_con(RawEthernetPacket * pkt) {
+ int index = -1;
+ int i = 0;
+ unsigned long * src_addr;
+ unsigned long * dest_addr;
+ unsigned short * src_port;
+ unsigned short * dest_port;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+
+ src_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 12);
+ dest_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 16);
+ src_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len);
+ dest_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 2);
+
+ // for (i = 0; i < MAX_CONS; i++) {
+ FOREACH_VTP_CON(i,g_vtp_cons) {
+ if ((g_vtp_cons[i].src_ip == *dest_addr) && (g_vtp_cons[i].dest_ip == *src_addr) &&
+ (g_vtp_cons[i].src_port = *dest_port) && (g_vtp_cons[i].dest_port == *src_port)) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+}
+
+
+int add_vtp_con(RawEthernetPacket * pkt, unsigned long seq_num) {
+ int i;
+ unsigned long * src_addr;
+ unsigned long * dest_addr;
+ unsigned short * src_port;
+ unsigned short * dest_port;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+
+ src_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 12);
+ dest_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 16);
+ src_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len);
+ dest_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 2);
+
+ for (i = 0; i < MAX_VTP_CONS; i++) {
+ if (!(g_vtp_cons[i].in_use)) {
+ JRLDBG("Adding connection in slot %d\n", i);
+ g_vtp_cons[i].rem_seq_num = seq_num;
+
+ // ADD PACKET CONNECTION INFO
+ g_vtp_cons[i].dest_ip = *dest_addr;
+ g_vtp_cons[i].src_ip = *src_addr;
+ g_vtp_cons[i].src_port = *src_port;
+ g_vtp_cons[i].dest_port = *dest_port;
+ g_vtp_cons[i].ack_template = *pkt;
+ g_vtp_cons[i].ip_id = ntohs(*(unsigned short *)(pkt->data + ETH_HDR_LEN + 4));
+
+ init_ack_template(&(g_vtp_cons[i].ack_template));
+
+ if (tcp_hdr_len > 20) {
+ unsigned long ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ip_hdr_len + 20, tcp_hdr_len - 20);
+ JRLDBG("TCP Timestamp = %lu(%lu)\n", ts, (unsigned long)ntohl(ts));
+ g_vtp_cons[i].tcp_timestamp = ts;
+ }
+
+ g_vtp_cons[i].in_use = true;
+
+ if (g_first_vtp == -1)
+ g_first_vtp = i;
+
+ g_vtp_cons[i].prev = g_last_vtp;
+ g_vtp_cons[i].next = -1;
+
+ if (g_last_vtp != -1) {
+ g_vtp_cons[g_last_vtp].next = i;
+ }
+
+ g_last_vtp = i;
+
+ g_num_vtp_cons++;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+int init_ack_template(RawEthernetPacket * pkt) {
+ // We assume here that the ethernet and ip headers are ok, except for ip pkt length
+ // TCP is mostly right because its pulled off of a syn packet
+ // we need to zero the data, and reset the syn flag.
+
+ unsigned short IP_PACKET_LEN = 52;
+ unsigned short TCP_HEADER_LEN = 32;
+ unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
+ unsigned short ip_pkt_len = 0;
+ unsigned short tcp_hdr_len = 0;
+ unsigned short payload_len = 0;
+ unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
+ unsigned int offset = 0;
+ unsigned short ip_chksum = 0;
+
+ JRLDBG("--> Initializing ACK Template <--\n");
+
+ ip_pkt_len = ntohs(*ip_pkt_len_ptr);
+ JRLDBG("ip_pkt_len = %hu\n", ip_pkt_len);
+
+ tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len);
+ JRLDBG("tcp_hdr_len = %hu\n", tcp_hdr_len);
+ JRLDBG("payload_len = %hu\n", payload_len);
+
+ // set only the ack flags
+ offset = ETH_HDR_LEN + ip_hdr_len + 13;
+ *(pkt->data + offset) |= 0x10;
+ *(pkt->data + offset) &= 0xd0;
+
+ // set up tcp options
+ offset = ETH_HDR_LEN + ip_hdr_len + 20;
+ *(pkt->data + offset) = 0x01;
+ offset++;
+ *(pkt->data + offset) = 0x01;
+ offset++;
+ *(pkt->data + offset) = 0x08;
+ offset++;
+ *(pkt->data + offset) = 0x0a;
+
+ // Set Header Lengths
+ // IP HEADER = 20 (same)
+ // IP PACKET LEN = 52
+ // TCP Header len = 32
+
+ ip_pkt_len = htons(IP_PACKET_LEN);
+ memcpy(pkt->data + ETH_HDR_LEN + 2, &ip_pkt_len, 2);
+ tcp_hdr_len = (TCP_HEADER_LEN << 2);
+ *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) &= 0x0f;
+ *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) |= tcp_hdr_len;
+
+ JRLDBG("Setting TEMPLATE TCPLEN = %2x\n", *(pkt->data + ETH_HDR_LEN +ip_hdr_len + 12));
+
+ // Set IP Header chksum
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = 0;
+ ip_chksum = get_ip_checksum(pkt);
+ *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = ip_chksum;
+
+
+ // Set RawEthernetPacket size
+ pkt->set_size(IP_PACKET_LEN + ETH_HDR_LEN);
+ pkt->set_type("et");
+
+ JRLDBG("--> ACK Template Initialized <--\n");
+
+
+ return 0;
+}
+
--- /dev/null
+#include "vtl_util.h"
+#include "if.h"
+#include "debug.h"
+
+
+
+#define IFACE_NAME "vmnet1"
+
+DEBUG_DECLARE();
+
+int main(int argc, char ** argv) {
+ RawEthernetPacket pkt;
+
+ char * iface_name = IFACE_NAME;
+
+ if (argc == 2) {
+ iface_name = argv[1];
+ }
+ iface_t * iface = if_connect(iface_name, IF_RW);
+
+ debug_init("./vtp.log");
+
+ while (if_read_pkt(iface, &pkt) == 0) {
+
+ printf("READ packet\n");
+ if (is_tcp_pkt(&pkt)) {
+ printf("TCP!!\n");
+ }
+
+ }
+
+}
--- /dev/null
+#include "vtp_util.h"
+#include "if.h"
+#include "debug.h"
+
+#define IFACE_NAME "vmnet1"
+
+DEBUG_DECLARE();
+
+int main(int argc, char ** argv) {
+ RawEthernetPacket pkt;
+
+ char * iface_name = IFACE_NAME;
+
+ if (argc == 2) {
+ iface_name = argv[1];
+ }
+ iface_t * iface = if_connect(iface_name, IF_RW);
+
+ debug_init("./vtp.log");
+
+ while (if_read_pkt(iface, &pkt) == 0) {
+
+ printf("READ packet\n");
+ if (is_tcp_pkt(&pkt)) {
+ printf("TCP!!\n");
+ }
+
+ }
+
+}
--- /dev/null
+
+#include "util.h"
+#include <ctype.h>
+
+#include <string.h>
+
+
+#if defined(USE_SSL)
+//SSL specific include libraries
+#include <openssl/ssl.h>
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#endif
+
+int compare_nocase(const string& s1, const string& s2)
+{
+ string::const_iterator p1 = s1.begin();
+ string::const_iterator p2 = s2.begin();
+
+ while((p1 != s1.end()) && (p2 != s2.end())) {
+ if (toupper(*p1) != toupper(*p2)) {
+ return (toupper(*p1) < toupper(*p2)) ? -1 : 1;
+ }
+
+ p1++;
+ p2++;
+ }
+
+ /* This is a two layer tri op */
+ return((s2.size() == s1.size()) ? 0 :
+ (s1.size() < s2.size()) ? -1 : 1);
+}
+
+void ConvertHexEthernetAddressToBinary(const char* string, char address[6]) {
+ for(int k = 0; k < 6; k++) {
+ hexbytetobyte(&(string[2 * k]), address + k);
+ }
+}
+
+void ConvertBinaryEthernetAddressToHex(char address[6], char * string) {
+ for (int j = 0; j < 6; j++) {
+ bytetohexbyte(address[j], &(string[2 * j]));
+ }
+}
+
+void string_to_mac(string str, char mac[6]) {
+ for(int k = 0; k < 6; k++) {
+ hexbytetobyte(&(str[(2 * k) + k]), mac + k);
+ }
+}
+
+void string_to_mac(const char * str, char mac[6]) {
+ for(int k = 0; k < 6; k++) {
+ hexbytetobyte(&(str[(2 * k) + k]), mac + k);
+ }
+}
+
+void mac_to_string(char address[6], char * buf) {
+ for (int i = 0; i < 6; i++) {
+ bytetohexbyte(address[i], &(buf[3 * i]));
+ buf[(3 * i) + 2] = ':';
+ }
+ buf[17] = 0;
+}
+
+void mac_to_string(char address[6], string * str) {
+ EthernetAddrString buf;
+
+ mac_to_string(address, buf);
+ *str = buf;
+}
+
+void ip_to_string(unsigned long addr, string * str) {
+ struct in_addr addr_st;
+
+ addr_st.s_addr = htonl(addr);
+ *str = inet_ntoa(addr_st);
+}
+
+
+void ip_to_string(unsigned long addr, char * buf) {
+ struct in_addr addr_st;
+ char * tmp_str;
+
+ addr_st.s_addr = htonl(addr);
+ tmp_str = inet_ntoa(addr_st);
+
+ memcpy(buf, tmp_str, strlen(tmp_str));
+}
+
+const char * ip_to_string(unsigned long addr) {
+ struct in_addr addr_st;
+
+ addr_st.s_addr = htonl(addr);
+ return inet_ntoa(addr_st);
+}
+
+
+#if defined(USE_SSL)
+int readall(const int fd, SSL *ssl, char *buf, const int len, const int oneshot, const int awaitblock) {
+ int rc;
+ int left;
+
+
+ left = len;
+
+ while (left > 0) {
+ if (ssl != NULL) {
+ rc = SSL_read(ssl, &(buf[len - left]), left);
+ } else {
+ rc = read(fd, &(buf[len - left]), left);
+ }
+
+ if (oneshot) {
+ return rc;
+ }
+
+ if (rc <= 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ if ((errno == EWOULDBLOCK) && awaitblock) {
+ continue;
+ }
+ return rc;
+ } else {
+ left -= rc;
+ }
+ }
+ return len;
+}
+
+int writeall(const int fd, SSL *ssl, const char *buf, const int len, const int oneshot, const int awaitblock)
+{
+ int rc;
+ int left;
+
+
+ left = len;
+
+ while (left > 0) {
+ if(ssl != NULL) {
+ rc = SSL_write(ssl, &(buf[len - left]), left);
+ } else {
+ rc = write(fd, &(buf[len - left]), left);
+ }
+ if (oneshot) {
+ return rc;
+ }
+ if (rc <= 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ if ((errno == EWOULDBLOCK) && awaitblock) {
+ continue;
+ }
+ return rc;
+ } else {
+ left -= rc;
+ }
+ }
+ return len;
+}
+#endif
+
+int readall(const int fd, char *buf, const int len, const int oneshot, const int awaitblock) {
+ int rc;
+ int left;
+
+ left = len;
+
+ while (left > 0) {
+ rc = read(fd, &(buf[len - left]), left);
+
+ if (oneshot) {
+ return rc;
+ }
+
+ if (rc <= 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+
+ if ((errno == EWOULDBLOCK) && awaitblock) {
+ continue;
+ }
+
+ return rc;
+ } else {
+ left -= rc;
+ }
+ }
+ return len;
+}
+
+int writeall(const int fd, const char *buf, const int len, const int oneshot, const int awaitblock)
+{
+ int rc;
+ int left;
+
+
+ left = len;
+ while (left > 0) {
+ rc = write(fd, &(buf[len - left]), left);
+
+ if (oneshot) {
+ return rc;
+ }
+
+ if (rc <= 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ if ((errno == EWOULDBLOCK) && awaitblock) {
+ continue;
+ }
+ return rc;
+ } else {
+ left -= rc;
+ }
+ }
+ return len;
+}
+
+
+
+void printhexnybble(FILE *out,const char lower) {
+ fputc( (lower >= 10) ? (lower - 10 + 'A') : (lower + '0'),
+ out);
+}
+
+void printhexbyte(FILE *out,const char h) {
+ char upper=(h >> 4) & 0xf;
+ char lower=h & 0xf;
+
+ printhexnybble(out, upper);
+ printhexnybble(out, lower);
+}
+
+void printhexbuffer(FILE *out, const char *buf, const int len) {
+ int i;
+ for (i = 0; i < len; i++) {
+ printhexbyte(out, buf[i]);
+ }
+}
+
+void printhexshort(FILE *out, const short s) {
+ printhexbuffer(out, (char*)&s, 2);
+}
+
+void printhexint(FILE *out, const int i) {
+ printhexbuffer(out, (char*)&i, 4);
+}
+
+
+char hexnybbletonybble(const char hexnybble) {
+ char x = toupper(hexnybble);
+ if ((x >= '0') && (x <= '9')) {
+ return x - '0';
+ } else {
+ return 10 + (x - 'A');
+ }
+}
+
+void hexbytetobyte(const char hexbyte[2], char *byte) {
+ *byte = ((hexnybbletonybble(hexbyte[0]) << 4) +
+ (hexnybbletonybble(hexbyte[1]) & 0xf));
+}
+
+char nybbletohexnybble(const char nybble) {
+ return (nybble >= 10) ? (nybble - 10 + 'A') : (nybble + '0');
+}
+
+void bytetohexbyte(const char byte, char hexbyte[2]) {
+ hexbyte[0] = nybbletohexnybble((byte >> 4) & 0xf);
+ hexbyte[1] = nybbletohexnybble(byte & 0xf);
+}
+
+EthernetAddr::EthernetAddr() {
+ memset(addr, 0, 6);
+}
+
+
+EthernetAddr::EthernetAddr(const EthernetAddr &rhs) {
+ memcpy(addr, rhs.addr, 6);
+}
+
+EthernetAddr::EthernetAddr(const EthernetAddrString rhs) {
+ SetToString(rhs);
+}
+
+
+const EthernetAddr & EthernetAddr::operator=(const EthernetAddr &rhs) {
+ memcpy(addr, rhs.addr, 6);
+ return *this;
+}
+
+bool EthernetAddr::operator==(const EthernetAddr &rhs) const {
+ return (memcmp(addr, rhs.addr, 6) == 0);
+}
+
+
+
+void EthernetAddr::SetToString(const EthernetAddrString s) {
+ int i,j;
+
+ for (i = 0, j = 0; i < 6; i++, j += 3) {
+ hexbytetobyte(&(s[j]), &(addr[i]));
+ }
+
+}
+
+void EthernetAddr::GetAsString(EthernetAddrString s) const {
+ int i,j;
+
+ for (i = 0, j = 0; i < 6; i++, j += 3) {
+ bytetohexbyte(addr[i], &(s[j]));
+ if (i < 5) {
+ s[j + 2] = ':';
+ } else {
+ s[j + 2] = 0;
+ }
+ }
+}
+
+
+ostream & EthernetAddr::Print(ostream &os) const {
+ EthernetAddrString s;
+
+ GetAsString(s);
+ os << "EthernetAddr(" << (char*)s << ")";
+ return os;
+}
+
+#if defined(USE_SSL)
+void EthernetAddr::Serialize(const int fd, SSL *ssl) const {
+ if (writeall(fd, ssl, addr, 6, 0, 1) != 6) {
+ throw SerializationException();
+ }
+}
+
+void EthernetAddr::Unserialize(const int fd, SSL *ssl) {
+ if (readall(fd, ssl, addr, 6, 0, 1) != 6) {
+ throw SerializationException();
+ }
+}
+
+#endif
+void EthernetAddr::Serialize(const int fd) const {
+ if (writeall(fd, addr, 6, 0, 1) != 6) {
+ throw SerializationException();
+ }
+}
+
+void EthernetAddr::Unserialize(const int fd) {
+ if (readall(fd, addr, 6, 0, 1) != 6) {
+ throw SerializationException();
+ }
+}
+
--- /dev/null
+#ifndef _util
+#define _util
+
+
+#include <stdio.h>
+#include <iostream>
+#include <string>
+
+
+#ifdef linux
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#elif defined(WIN32)
+
+#include <io.h>
+#include <Winsock2.h>
+#define read _read
+#define write _write
+
+#define EWOULDBLOCK WSAEWOULDBLOCK
+
+typedef int socklen_t;
+#endif
+
+
+
+
+
+#define ETHERNET_HEADER_LEN 14
+#define ETHERNET_DATA_MIN 46
+#define ETHERNET_DATA_MAX 1500
+
+#define ETHERNET_PACKET_LEN (ETHERNET_HEADER_LEN+ETHERNET_DATA_MAX)
+
+
+#if defined(USE_SSL)
+extern "C" {
+#define OPENSSL_NO_KRB5
+#include <openssl/ssl.h>
+}
+#endif
+
+using namespace std;
+
+#if defined(USE_SSL)
+int readall(const int fd, SSL * ssl, char * buf, const int len, const int oneshot = 0, const int awaitblock = 1);
+int writeall(const int fd, SSL * ssl, const char * buf, const int len, const int oneshot = 0, const int awaitblock = 1);
+#endif
+int readall(const int fd, char * buf, const int len, const int oneshot = 0, const int awaitblock = 1);
+int writeall(const int fd, const char * buf, const int len, const int oneshot = 0, const int awaitblock = 1);
+
+
+
+#if defined(WIN32)
+#define snprintf _snprintf
+#endif
+
+
+int compare_nocase(const string &s1, const string &s2);
+
+struct SerializationException {};
+
+void printhexnybble(FILE * out,const char lower);
+void printhexbyte(FILE * out,const char h);
+void printhexshort(FILE * out,const short h);
+void printhexint(FILE * out,const int h);
+void printhexbuffer(FILE * out, const char * buf, const int len);
+
+void hexbytetobyte(const char hexbyte[2], char * byte);
+void bytetohexbyte(const char byte, char hexbyte[2]);
+
+void ConvertHexEthernetAddressToBinary(const char * string, char address[6]);
+void ConvertBinaryEthernetAddressToHex(char address[6], char * string);
+
+// How about a function that you might actually use...
+void mac_to_string(char address[6], char * buf);
+void mac_to_string(char address[6], string * str);
+void string_to_mac(string str, char mac[6]);
+void string_to_mac(const char * str, char mac[6]);
+
+void ip_to_string(unsigned long addr, string * str);
+void ip_to_string(unsigned long addr, char * buf);
+const char * ip_to_string(unsigned long addr);
+
+typedef char EthernetAddrString[(2 * 6) + 6];
+
+
+struct EthernetAddr {
+ char addr[6];
+
+ EthernetAddr();
+ EthernetAddr(const EthernetAddr &rhs);
+ EthernetAddr(const EthernetAddrString rhs);
+ const EthernetAddr & operator=(const EthernetAddr &rhs);
+
+ bool operator==(const EthernetAddr &rhs) const;
+
+ void SetToString(const EthernetAddrString s);
+ void GetAsString(EthernetAddrString s) const;
+
+#if defined(USE_SSL)
+ void Serialize(const int fd, SSL * ssl) const;
+ void Unserialize(const int fd,SSL * ssl);
+#endif
+ void Serialize(const int fd) const;
+ void Unserialize(const int fd);
+
+
+ ostream & Print(ostream &os) const;
+};
+
+inline ostream & operator<<(ostream &os, const EthernetAddr &e)
+{
+ return e.Print(os);
+}
+
+#endif
--- /dev/null
+#ifndef __VTL_H
+#define __VTL_H
+
+#include "vtl_util.h"
+#include "vtl_model.h"
+#include "util.h"
+#include "config.h"
+#include "net_util.h"
+#include "raw_ethernet_packet.h"
+#include "debug.h"
+#include "if.h"
+
+#endif
--- /dev/null
+#ifndef VTL_HARNESS_H
+#define VTL_HARNESS_H
+
+#include "vtl.h"
+
+#ifdef linux
+#include <fcntl.h>
+#define POLL_TIMEOUT 0
+#define MAX_VTL_CONS 100
+
+#define HOME "./"
+#define VTP_FIFO_SENDFILE HOME "vtp_fifo_send"
+#define VTP_FIFO_RECVFILE HOME "vtp_fifo_recv"
+#endif
+
+struct VTL_CON {
+ /* unsigned long rem_seq_num;
+ unsigned long dest_ip;
+ unsigned long src_ip;
+ unsigned short src_port;
+ unsigned short dest_port;
+ RawEthernetPacket ack_template;
+ unsigned short ip_id;
+ unsigned long tcp_timestamp;
+ */
+
+ vtl_model_t con_model;
+
+ bool in_use;
+ int next;
+ int prev;
+};
+
+#define FOREACH_VTL_CON(iter, cons) for (iter = g_first_vtl; iter != -1; iter = cons[iter].next)
+
+
+
+/* Sending Layers Need to implement these */
+int vtl_init();
+int vtl_send(RawEthernetPacket * p, unsigned long serv_addr);
+int vtl_recv(RawEthernetPacket ** p);
+int vtl_connect(unsigned long serv_addr, unsigned short serv_port);
+int vtl_close(unsigned long serv_addr);
+
+
+int register_fd(SOCK fd);
+int unregister_fd(SOCK fd);
+
+#endif
--- /dev/null
+#include "vtl_model.h"
+
+
+
+/* VTL Models */
+
+
+
+
+
+vtl_model_t * new_vtl_model(model_type_t type) {
+ vtl_model_t * model = (vtl_model_t *)malloc(sizeof(vtl_model_t));
+
+ model->type = type;
+
+ return model;
+}
+
+
+int initialize_ethernet_model(ethernet_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ printf("initializing ethernet model\n");
+ if (dir == OUTBOUND_PKT) {
+ GET_ETH_DST(pkt->data, model->dst.addr);
+ GET_ETH_SRC(pkt->data, model->src.addr);
+ } else if (dir == INBOUND_PKT) {
+ GET_ETH_DST(pkt->data, model->src.addr);
+ GET_ETH_SRC(pkt->data, model->dst.addr);
+ } else {
+ return -1;
+ }
+
+ model->type = GET_ETH_TYPE(pkt->data);
+
+ return 0;
+}
+
+int initialize_ip_model(ip_model_t * model, RawEthernetPacket * pkt, int dir) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ if (!is_ip_pkt(pkt)) {
+ return -1;
+ }
+
+ if (dir == OUTBOUND_PKT) {
+ model->src.addr = GET_IP_SRC(pkt->data);
+ model->dst.addr = GET_IP_DST(pkt->data);
+ model->dst.ip_id = 1;
+ model->src.ip_id = GET_IP_ID(pkt->data);
+ model->src.ttl = GET_IP_TTL(pkt->data);
+ model->dst.ttl = 1;
+ } else if (dir == INBOUND_PKT) {
+ model->src.addr = GET_IP_DST(pkt->data);
+ model->dst.addr = GET_IP_SRC(pkt->data);
+ model->src.ip_id = 1;
+ model->dst.ip_id = GET_IP_ID(pkt->data);
+ model->src.ttl = 1;
+ model->dst.ttl = GET_IP_TTL(pkt->data);
+ } else {
+ return -1;
+ }
+
+ model->version = GET_IP_VERSION(pkt->data);
+ model->proto = GET_IP_PROTO(pkt->data);
+
+ if (initialize_ethernet_model(&(model->ethernet), pkt, dir) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int initialize_tcp_model(tcp_model_t * model, RawEthernetPacket * pkt, int dir) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ tcp_opts_t options;
+
+ if (!is_tcp_pkt(pkt)) {
+ return -1;
+ }
+
+ parse_tcp_options(&options, pkt);
+
+ if (dir == OUTBOUND_PKT) {
+ model->src.port = GET_TCP_SRC_PORT(pkt->data);
+ model->dst.port = GET_TCP_DST_PORT(pkt->data);
+ model->src.seq_num = compute_next_tcp_seq_num(pkt);
+ model->src.last_ack = GET_TCP_ACK_NUM(pkt->data);
+ model->src.win = GET_TCP_WIN(pkt->data);
+ model->src.mss = options.mss;
+ model->src.ts = options.local_ts;
+ model->dst.mss = 0;
+ model->dst.ts = 0;
+ } else if (dir == INBOUND_PKT) {
+ model->src.port = GET_TCP_DST_PORT(pkt->data);
+ model->dst.port = GET_TCP_SRC_PORT(pkt->data);
+ model->dst.last_ack = GET_TCP_ACK_NUM(pkt->data);
+ model->src.seq_num = 1;
+ model->dst.seq_num = compute_next_tcp_seq_num(pkt);
+ model->dst.win = GET_TCP_WIN(pkt->data);
+ model->dst.mss = options.mss;
+ model->dst.ts = options.local_ts;
+ model->src.mss = 0;
+ model->src.ts = 0;
+ } else {
+ return -1;
+ }
+
+ if (initialize_ip_model(&(model->ip), pkt, dir) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int initialize_udp_model(udp_model_t * model, RawEthernetPacket * pkt, int dir) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ if (!is_udp_pkt(pkt)) {
+ return -1;
+ }
+
+ if (dir == OUTBOUND_PKT) {
+ model->src.port = GET_UDP_SRC_PORT(pkt->data);
+ model->dst.port = GET_UDP_DST_PORT(pkt->data);
+ } else if (dir == INBOUND_PKT) {
+ model->src.port = GET_UDP_DST_PORT(pkt->data);
+ model->dst.port = GET_UDP_SRC_PORT(pkt->data);
+ } else {
+ return -1;
+ }
+
+ if (initialize_ip_model(&(model->ip), pkt, dir) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+int initialize_model(vtl_model_t * model, RawEthernetPacket * pkt, int dir) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ if (model->type == TCP_MODEL) {
+ return initialize_tcp_model(&(model->model.tcp_model), pkt, dir);
+ } else if (model->type == UDP_MODEL) {
+ return initialize_udp_model(&(model->model.udp_model), pkt, dir);
+ } else if (model->type == IP_MODEL) {
+ } else if (model->type == ETHERNET_MODEL) {
+ }
+
+ return -1;
+}
+
+
+
+int is_ethernet_model_pkt(ethernet_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ if ((memcmp(model->src.addr, ETH_SRC(pkt->data), 6) == 0) &&
+ (memcmp(model->dst.addr, ETH_DST(pkt->data), 6) == 0)) {
+ return OUTBOUND_PKT;
+ } else if ((memcmp(model->src.addr, ETH_DST(pkt->data), 6) == 0) &&
+ (memcmp(model->dst.addr, ETH_SRC(pkt->data), 6) == 0)) {
+ return INBOUND_PKT;
+ }
+
+ return INVALID_PKT;
+}
+
+int is_ip_model_pkt(ip_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ if (!is_ip_pkt(pkt)) {
+ return INVALID_PKT;
+ }
+
+ if ((model->src.addr == GET_IP_SRC(pkt->data)) &&
+ (model->dst.addr == GET_IP_DST(pkt->data))) {
+ return OUTBOUND_PKT;
+ } else if ((model->src.addr == GET_IP_DST(pkt->data)) &&
+ (model->dst.addr == GET_IP_SRC(pkt->data))) {
+ return INBOUND_PKT;
+ }
+
+ return INVALID_PKT;
+}
+
+
+int is_tcp_model_pkt(tcp_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+ int ip_ret;
+
+ if (!is_tcp_pkt(pkt)) {
+ return INVALID_PKT;
+ }
+
+ if ((ip_ret = is_ip_model_pkt(&(model->ip), pkt)) == INVALID_PKT) {
+ return INVALID_PKT;
+ }
+
+
+ if (ip_ret == OUTBOUND_PKT) {
+ if ((model->src.port == GET_TCP_SRC_PORT(pkt->data)) &&
+ (model->dst.port == GET_TCP_DST_PORT(pkt->data))) {
+ return OUTBOUND_PKT;
+ }
+ } else if (ip_ret == INBOUND_PKT) {
+ if ((model->src.port == GET_TCP_DST_PORT(pkt->data)) &&
+ (model->dst.port == GET_TCP_SRC_PORT(pkt->data))) {
+ return INBOUND_PKT;
+ }
+ }
+ return INVALID_PKT;
+}
+
+int is_udp_model_pkt(udp_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+ int ip_ret;
+
+ if (!is_udp_pkt(pkt)) {
+ return INVALID_PKT;
+ }
+
+ if ((ip_ret = is_ip_model_pkt(&(model->ip), pkt)) == INVALID_PKT) {
+ return INVALID_PKT;
+ }
+
+ if (ip_ret == OUTBOUND_PKT) {
+ if ((model->src.port == GET_UDP_SRC_PORT(pkt->data)) &&
+ (model->dst.port == GET_UDP_DST_PORT(pkt->data))) {
+ return OUTBOUND_PKT;
+ }
+ } else if (ip_ret == INBOUND_PKT) {
+ if ((model->src.port == GET_UDP_DST_PORT(pkt->data)) &&
+ (model->dst.port == GET_UDP_SRC_PORT(pkt->data))) {
+ return INBOUND_PKT;
+ }
+ }
+
+ return INBOUND_PKT;
+}
+
+int is_model_pkt(vtl_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ if (model->type == TCP_MODEL) {
+ return is_tcp_model_pkt(&(model->model.tcp_model), pkt);
+ }
+
+ return INVALID_PKT;
+}
+
+
+int sync_ip_model(ip_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+
+ int ip_ret;
+
+ ip_ret = is_ip_model_pkt(model, pkt);
+
+ if (ip_ret == OUTBOUND_PKT) {
+ model->src.ip_id = GET_IP_ID(pkt->data);
+ model->src.ttl = GET_IP_TTL(pkt->data);
+ } else if (ip_ret == INBOUND_PKT) {
+ model->dst.ip_id = GET_IP_ID(pkt->data);
+ model->dst.ttl = GET_IP_TTL(pkt->data);
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int sync_tcp_model(tcp_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+ int tcp_ret;
+ tcp_opts_t options;
+ int has_opts = 0;
+
+ tcp_ret = is_tcp_model_pkt(model, pkt);
+
+ has_opts = parse_tcp_options(&options, pkt);
+
+ if (tcp_ret == OUTBOUND_PKT) {
+ model->src.seq_num = compute_next_tcp_seq_num(pkt);
+ model->src.last_ack = GET_TCP_ACK_NUM(pkt->data);
+ model->src.win = GET_TCP_WIN(pkt->data);
+ if (has_opts == 0) {
+ model->src.mss = options.mss;
+ model->src.ts = options.local_ts;
+ }
+ } else if (tcp_ret == INBOUND_PKT) {
+ model->dst.last_ack = GET_TCP_ACK_NUM(pkt->data);
+ model->dst.seq_num = compute_next_tcp_seq_num(pkt);
+ model->dst.win = GET_TCP_WIN(pkt->data);
+ if (has_opts == 0) {
+ model->dst.mss = options.mss;
+ model->dst.ts = options.local_ts;
+ }
+ } else {
+ return -1;
+ }
+
+ if (sync_ip_model(&(model->ip), pkt) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int sync_udp_model(udp_model_t * model, RawEthernetPacket * pkt) {
+ ASSERT((model != NULL) && (pkt != NULL));
+ int udp_ret;
+
+ udp_ret = is_udp_model_pkt(model, pkt);
+
+ if (udp_ret == INVALID_PKT) {
+ return -1;
+ }
+
+ if (sync_ip_model(&(model->ip), pkt) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int sync_model(vtl_model_t * model, RawEthernetPacket * pkt) {
+
+ if (model->type == TCP_MODEL) {
+ return sync_tcp_model(&(model->model.tcp_model), pkt);
+ } else if (model->type == IP_MODEL) {
+ return sync_ip_model(&(model->model.ip_model), pkt);
+ }
+ return -1;
+}
+
+int create_empty_ethernet_pkt(ethernet_model_t * model, RawEthernetPacket * pkt, int dir) {
+ if (dir == OUTBOUND_PKT) {
+ SET_ETH_SRC(pkt->data, model->src.addr);
+ SET_ETH_DST(pkt->data, model->dst.addr);
+ } else if (dir == INBOUND_PKT) {
+ SET_ETH_SRC(pkt->data, model->dst.addr);
+ SET_ETH_DST(pkt->data, model->src.addr);
+ }
+ SET_ETH_TYPE(pkt->data, model->type);
+ pkt->set_size(ETH_HDR_LEN);
+
+ return 0;
+}
+
+
+int create_empty_ip_pkt(ip_model_t * model, RawEthernetPacket * pkt, int dir) {
+ create_empty_ethernet_pkt(&(model->ethernet), pkt, dir);
+
+ SET_IP_VERSION(pkt->data, model->version);
+ SET_IP_HDR_LEN(pkt->data, 20);
+ SET_IP_SVC_TYPE(pkt->data, 0);
+ SET_IP_TOTAL_LEN(pkt->data, 20); // WE ARE JUST AN EMPTY PACKET HERE
+ SET_IP_FLAGS(pkt->data, 0);
+ SET_IP_FRAG(pkt->data, 0);
+ SET_IP_PROTO(pkt->data, model->proto);
+
+
+ if (dir == OUTBOUND_PKT) {
+ SET_IP_ID(pkt->data, model->src.ip_id + 1);
+ SET_IP_TTL(pkt->data, model->src.ttl);
+ SET_IP_SRC(pkt->data, model->src.addr);
+ SET_IP_DST(pkt->data, model->dst.addr);
+ } else if (dir == INBOUND_PKT) {
+ SET_IP_ID(pkt->data, model->dst.ip_id + 1);
+ SET_IP_TTL(pkt->data, model->dst.ttl);
+ // SET_IP_TTL(pkt->data, 5);
+ SET_IP_SRC(pkt->data, model->dst.addr);
+ SET_IP_DST(pkt->data, model->src.addr);
+ }
+
+ compute_ip_checksum(pkt);
+ pkt->set_size(compute_pkt_size(pkt));
+
+ return 0;
+}
+
+int create_empty_tcp_pkt(tcp_model_t * model, RawEthernetPacket * pkt, int dir) {
+ create_empty_ip_pkt(&(model->ip), pkt, dir);
+
+ SET_TCP_HDR_LEN(pkt->data, 20);
+ SET_TCP_RSVD(pkt->data, 0);
+ SET_TCP_FLAGS(pkt->data, 0);
+ SET_TCP_URG_PTR(pkt->data, 0);
+
+ if (dir == OUTBOUND_PKT) {
+ SET_TCP_SRC_PORT(pkt->data, model->src.port);
+ SET_TCP_DST_PORT(pkt->data, model->dst.port);
+ SET_TCP_SEQ_NUM(pkt->data, model->src.seq_num);
+
+ // This is kind of weird
+ // We set the ack number to last ack that was sent on the actual channel
+ // We want to insert packets into the connection without messing things up
+ // So we don't want to ack data that hasn't necessarily been received
+ // Since we're blowing away the seq_num sequence anyway, this might not matter
+ // SET_TCP_ACK_NUM(pkt->data, model->src.last_ack);
+ SET_TCP_ACK_NUM(pkt->data, model->dst.seq_num);
+ SET_TCP_ACK_FLAG(pkt->data);
+
+ SET_TCP_WIN(pkt->data, model->src.win);
+
+ } else if (dir == INBOUND_PKT) {
+ SET_TCP_SRC_PORT(pkt->data, model->dst.port);
+ SET_TCP_DST_PORT(pkt->data, model->src.port);
+
+ SET_TCP_SEQ_NUM(pkt->data, model->dst.seq_num);
+
+ // This is kind of weird
+ // We set the ack number to last ack that was sent on the actual channel
+ // We want to insert packets into the connection without messing things up
+ // So we don't want to ack data that hasn't necessarily been received
+ // Since we're blowing away the seq_num sequence anyway, this might not matter
+ //SET_TCP_ACK_NUM(pkt->data, model->dst.last_ack);
+ SET_TCP_ACK_NUM(pkt->data, model->src.seq_num);
+
+ SET_TCP_ACK_FLAG(pkt->data);
+
+ SET_TCP_WIN(pkt->data, model->dst.win);
+ }
+
+
+ SET_IP_TOTAL_LEN(pkt->data, GET_IP_HDR_LEN(pkt->data) + GET_TCP_HDR_LEN(pkt->data));
+ pkt->set_size(compute_pkt_size(pkt));
+
+ compute_ip_checksum(pkt);
+
+ compute_tcp_checksum(pkt);
+
+ JRLDBG("tcp_len = %d\n", GET_TCP_HDR_LEN(pkt->data));
+
+
+ // Set the ip hdr len
+
+ return 0;
+}
+
+
+int create_empty_udp_pkt(udp_model_t * model, RawEthernetPacket * pkt, int dir) {
+ create_empty_ip_pkt(&(model->ip), pkt, dir);
+
+ if (dir == OUTBOUND_PKT) {
+ SET_UDP_SRC_PORT(pkt->data, model->src.port);
+ SET_UDP_DST_PORT(pkt->data, model->dst.port);
+ } else if (dir == INBOUND_PKT) {
+ SET_UDP_SRC_PORT(pkt->data, model->dst.port);
+ SET_UDP_DST_PORT(pkt->data, model->src.port);
+ }
+ SET_UDP_LEN(pkt->data, 8);
+ SET_IP_TOTAL_LEN(pkt->data, GET_IP_HDR_LEN(pkt->data) + GET_UDP_LEN(pkt->data));
+
+ compute_ip_checksum(pkt);
+ compute_udp_checksum(pkt);
+
+ return 0;
+}
+
+int create_empty_pkt(vtl_model_t * model, RawEthernetPacket * pkt, int dir) {
+ if (model->type == TCP_MODEL) {
+ return create_empty_tcp_pkt(&(model->model.tcp_model), pkt, dir);
+ } else if (model->type == UDP_MODEL) {
+ return create_empty_udp_pkt(&(model->model.udp_model), pkt, dir);
+ } else if (model->type == IP_MODEL) {
+ return create_empty_ip_pkt(&(model->model.ip_model), pkt, dir);
+ }
+ return -1;
+}
+
+
+
+
+void dbg_dump_eth_model(ethernet_model_t * model) {
+ char src_mac[6];
+ char dst_mac[6];
+
+ printf("ETHERNET MODEL {\n");
+
+ printf("\tType: %s\n", get_eth_protocol(model->type));
+
+ mac_to_string(model->src.addr, src_mac);
+ printf("\tSrc Host {\n");
+ printf("\t\taddr: %s\n", src_mac);
+ printf("\t}\n");
+
+ mac_to_string(model->dst.addr, dst_mac);
+ printf("\tDST Host {\n");
+ printf("\t\taddr: %s\n", dst_mac);
+ printf("\t}\n");
+ printf("}\n");
+}
+
+
+
+void dbg_dump_ip_model(ip_model_t * model) {
+ dbg_dump_eth_model(&(model->ethernet));
+
+ printf("IP MODEL {\n");
+ printf("\tVersion: %d\n", model->version);
+ printf("\tProtocol: %s\n", get_ip_protocol(model->proto));
+
+ printf("\tSrc Host {\n");
+ printf("\t\taddr: %s\n", ip_to_string(model->src.addr));
+ printf("\t\tIP ID: %lu\n", model->src.ip_id);
+ printf("\t\tttl: %d\n", model->src.ttl);
+ printf("\t}\n");
+
+ printf("\tDst Host {\n");
+ printf("\t\taddr: %s\n", ip_to_string(model->dst.addr));
+ printf("\t\tIP ID: %lu\n", model->dst.ip_id);
+ printf("\t\tttl: %d\n", model->dst.ttl);
+ printf("\t}\n");
+
+ printf("}\n");
+}
+
+void dbg_dump_tcp_model(tcp_model_t * model) {
+ dbg_dump_ip_model(&(model->ip));
+
+ printf("TCP MODEL {\n");
+ printf("\tSrc Host {\n");
+ printf("\t\tport: %hu\n", model->src.port);
+ printf("\t\tseq: %lu\n", (unsigned long)(model->src.seq_num));
+ printf("\t\tlast ack: %lu\n", (unsigned long)(model->src.last_ack));
+ printf("\t\tWin Size: %hu\n", model->src.win);
+ printf("\t\tTimestamp: %lu\n", (unsigned long)(model->src.ts));
+ printf("\t\tMSS: %hu\n", model->src.mss);
+
+ printf("\t}\n");
+
+ printf("\tDst Host {\n");
+ printf("\t\tport: %hu\n", model->dst.port);
+ printf("\t\tseq: %lu\n", (unsigned long)(model->dst.seq_num));
+ printf("\t\tlast ack: %lu\n", (unsigned long)(model->dst.last_ack));
+ printf("\t\tWin Size: %hu\n", model->dst.win);
+ printf("\t\tTimestamp: %lu\n", (unsigned long)(model->dst.ts));
+ printf("\t\tMSS: %hu\n", model->dst.mss);
+ printf("\t}\n");
+
+
+ printf("}\n");
+
+}
+
+
+
+void dbg_dump_model(vtl_model_t * model) {
+ if (model->type == TCP_MODEL) {
+ dbg_dump_tcp_model(&(model->model.tcp_model));
+ } else if (model->type == IP_MODEL) {
+ dbg_dump_ip_model(&(model->model.ip_model));
+ }
+}
--- /dev/null
+#ifndef __VTL_MODEL_H
+#define __VTL_MODEL_H
+
+
+#include "vtl_util.h"
+
+#define INVALID_PKT 0
+#define OUTBOUND_PKT 1
+#define INBOUND_PKT 2
+
+typedef enum tcp_state { CLOSED,
+ LISTEN,
+ SYN_RCVD,
+ SYN_SENT,
+ ESTABLISHED,
+ CLOSE_WAIT,
+ LAST_ACK,
+ FIN_WAIT1,
+ FIN_WAIT2,
+ CLOSING,
+ TIME_WAIT } tcp_state_t;
+
+
+/* State Models */
+/*#define ETHERNET_MODEL 0
+#define IP_MODEL 1
+#define TCP_MODEL 2
+#define UDP_MODEL 3
+*/
+
+typedef enum model_type{ETHERNET_MODEL,
+ IP_MODEL,
+ TCP_MODEL,
+ UDP_MODEL } model_type_t;
+
+typedef struct ethernet_host_state {
+ char addr[6];
+
+} ethernet_host_state_t;
+
+typedef struct ethernet_model {
+ ethernet_host_state_t src;
+ ethernet_host_state_t dst;
+ unsigned short type;
+} ethernet_model_t;
+
+typedef struct ip_host_state {
+ unsigned short ip_id;
+ unsigned long addr;
+
+ unsigned char ttl;
+
+} ip_host_state_t;
+
+typedef struct ip_model {
+ ip_host_state_t src;
+ ip_host_state_t dst;
+
+ char version;
+ unsigned char proto;
+ ethernet_model_t ethernet;
+} ip_model_t;
+
+typedef struct tcp_host_state {
+ unsigned short port;
+ unsigned long seq_num;
+ unsigned long last_ack;
+ unsigned short win;
+
+ unsigned long ts;
+ unsigned short mss;
+
+ tcp_state_t state;
+
+} tcp_host_state_t;
+
+typedef struct tcp_model {
+ tcp_host_state_t src;
+ tcp_host_state_t dst;
+
+ ip_model_t ip;
+} tcp_model_t;
+
+typedef struct udp_host_state {
+ unsigned short port;
+} udp_host_state_t;
+
+typedef struct udp_model {
+ udp_host_state_t src;
+ udp_host_state_t dst;
+
+ ip_model_t ip;
+} udp_model_t;
+
+
+typedef struct vtl_model {
+ union model_u {
+ ethernet_model_t ethernet_model;
+ ip_model_t ip_model;
+ tcp_model_t tcp_model;
+ udp_model_t udp_model;
+ } model;
+ model_type_t type;
+} vtl_model_t;
+
+
+
+udp_model_t * new_udp_model();
+tcp_model_t * new_tcp_model();
+ip_model_t * new_ip_model();
+ethernet_model_t * new_ethernet_model();
+vtl_model_t * new_vtl_model(model_type_t type);
+
+int initialize_ip_model(ip_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int initialize_tcp_model(tcp_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int initialize_udp_model(udp_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int initialize_model(vtl_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+
+int sync_ip_model(ip_model_t * model, RawEthernetPacket * pkt);
+int sync_tcp_model(tcp_model_t * model, RawEthernetPacket * pkt);
+int sync_udp_model(udp_model_t * model, RawEthernetPacket * pkt);
+int sync_model(vtl_model_t * model, RawEthernetPacket * pkt);
+
+int is_udp_model_pkt(udp_model_t * model, RawEthernetPacket * pkt);
+int is_tcp_model_pkt(tcp_model_t * model, RawEthernetPacket * pkt);
+int is_ip_model_pkt(ip_model_t * model, RawEthernetPacket * pkt);
+int is_ethernet_model_pkt(ethernet_model_t * model, RawEthernetPacket * pkt);
+int is_model_pkt(vtl_model_t * model, RawEthernetPacket * pkt);
+
+
+
+int create_empty_ethernet_pkt(ethernet_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int create_empty_ip_pkt(ip_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int create_empty_tcp_pkt(tcp_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int create_empty_udp_pkt(udp_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+int create_empty_pkt(vtl_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+
+// User must track tcp state changes
+//tcp_state_t get_tcp_state(tcp_state_t current_state, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT);
+
+
+void dbg_dump_eth_model(ethernet_model_t * model);
+void dbg_dump_ip_model(ip_model_t * model);
+void dbg_dump_tcp_model(tcp_model_t * model);
+void dbg_dump_udp_model(udp_model_t * model);
+void dbg_dump_model(vtl_model_t * model);
+
+
+
+
+
+
+#endif // ! __VTL_MODEL_H
--- /dev/null
+#include "vtl_util.h"
+
+
+
+void dbg_print_pkt_info(RawEthernetPacket * pkt) {
+ unsigned short src_port;
+ unsigned short dest_port;
+ string dest_str;
+ string src_str;
+
+ unsigned long seq_num = GET_TCP_SEQ_NUM(pkt->data);
+ unsigned long ack_num = GET_TCP_ACK_NUM(pkt->data);
+
+ src_port = GET_TCP_SRC_PORT(pkt->data);
+ dest_port = GET_TCP_DST_PORT(pkt->data);
+
+ dest_str = ip_to_string(GET_IP_DST(pkt->data));
+ src_str = ip_to_string(GET_IP_SRC(pkt->data));
+
+ JRLDBG("Packet: %s:%d-%s:%d seq: %lu, ack: %lu\n", src_str.c_str(), ntohs(src_port), dest_str.c_str(), ntohs(dest_port),
+ seq_num, ack_num);
+
+ return;
+
+}
+
+void dbg_print_pkt(RawEthernetPacket * pkt) {
+ unsigned int x;
+ int i;
+ char pkt_line[128];
+ unsigned int pkt_size = pkt->get_size() - 1;
+
+ JRLDBG("Packet Dump: (pkt_size=%d) \n", pkt->get_size());
+
+ for (x = 0; x < pkt_size;) {
+ sprintf(pkt_line, "\t%.4x: ", x);
+
+ for (i = 0; i < 16; i += 2) {
+ if (pkt_size < x + i) {
+ break;
+ }
+
+ if (pkt_size == x + i) {
+ sprintf(pkt_line, "%s%.2x ", pkt_line, *(unsigned char *)(pkt->data + i + x));
+ } else {
+
+ sprintf(pkt_line, "%s%.4x ", pkt_line, ntohs(*(unsigned short *)(pkt->data + i + x)));
+ }
+ }
+
+ JRLDBG("%s\n", pkt_line);
+
+ x += 16;
+ }
+}
+
+void dbg_print_buf(unsigned char * buf, unsigned int len) {
+ unsigned int x;
+ int i;
+ char pkt_line[128];
+
+ JRLDBG("Buf Dump: (len=%d) \n", len);
+
+ for (x = 0; x < len-1;) {
+ sprintf(pkt_line, "\t%.4x: ", x);
+
+ for (i = 0; i < 16; i += 2) {
+ if ((len - 1) < x + i) {
+ break;
+ }
+
+ if (len == x + i + 1) {
+ sprintf(pkt_line, "%s%.2x ", pkt_line, *(unsigned char *)(buf + i + x));
+ } else {
+
+ sprintf(pkt_line, "%s%.4x ", pkt_line, ntohs(*(unsigned short *)(buf + i + x)));
+ }
+ }
+
+ JRLDBG("%s\n", pkt_line);
+
+ x += 16;
+ }
+
+}
+/*
+ void do_binary_to_ipaddress(unsigned char* ip,IPADDRESS& ipaddress)
+ {
+ ipaddress.a1=ip[0];
+ ipaddress.a2=ip[1];
+ ipaddress.a3=ip[2];
+ ipaddress.a4=ip[3];
+ }
+
+ void do_ipaddress_to_string(IPADDRESS ipaddress,char* buffer)
+ {
+ sprintf(buffer,"%d.%d.%d.%d",ipaddress.a1,ipaddress.a2,ipaddress.a3,ipaddress.a4);
+ }
+
+ void do_binary_to_string(unsigned char* ip,char* buffer)
+ {
+ IPADDRESS ipaddress;
+ do_binary_to_ipaddress(ip,ipaddress);
+ do_ipaddress_to_string(ipaddress,buffer);
+ }
+*/
+
+int get_mss(RawEthernetPacket * pkt) {
+ unsigned long ip_hdr_len = GET_IP_HDR_LEN(pkt->data);
+ unsigned short tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ int offset = 0;
+ int len = tcp_hdr_len - 20;
+ unsigned short mss;
+
+ char * opts = (pkt->data + ETH_HDR_LEN + ip_hdr_len + 20);
+
+ if (len <= 0) {
+ return -1;
+ }
+
+ while (offset < len) {
+ if (*(opts + offset) == 0x00) {
+ break;
+ } else if (*(opts + offset) == 0x01) {
+ offset++;
+ } else if (*(opts + offset) == 0x02) {
+ mss = (*(unsigned short *)(opts + offset + 2));
+ offset += *(opts + offset + 1);
+ return (int)ntohs(mss);
+ } else {
+ offset += *(opts + offset + 1);
+ }
+ }
+ return -1;
+}
+
+int parse_tcp_options(tcp_opts_t * options, RawEthernetPacket * pkt) {
+ ASSERT((options != NULL) && (pkt != NULL));
+
+ memset(options, 0, sizeof(options));
+
+ int offset = 0;
+ char * opts = TCP_OPTS(pkt->data);
+ int opt_len = GET_TCP_OPTS_LEN(pkt->data);
+ int field_len = 0;
+ if (opt_len == 0) {
+ // no options
+ return -1;
+ }
+
+
+ while (offset < opt_len) {
+ if (*(opts + offset) == 0x00) {
+ break;
+ } else if (*(opts + offset) == 0x01) {
+ offset++;
+ } else if (*(opts + offset) == 0x02) {
+ options->mss = ntohs(*(unsigned short *)(opts + offset + 2));
+ offset += *(opts + offset + 1);
+ } else if (*(opts + offset) == 0x03) {
+ options->window = *(unsigned char *)(opts + offset + 2);
+ offset += *(opts + offset + 1);
+ } else if (*(opts + offset) == 0x04) {
+ // SACK OK
+ options->sack_ok = 1;
+ offset += 2;
+ } else if (*(opts + offset) == 0x05) {
+ field_len = *(opts + offset + 1);
+ options->sack_entries = (unsigned long *)malloc(field_len - 2);
+ memcpy(options->sack_entries, opts + offset + 2, field_len - 2);
+ offset += field_len;
+ } else if (*(opts + offset) == 0x08) {
+ offset += 2;
+ options->local_ts = *(unsigned long *)(opts + offset);
+ offset += 4;
+ options->remote_ts = *(unsigned long *)(opts + offset);
+ offset += 4;
+ } else {
+ // default handler to skip what we don't look for
+ offset += *(opts + offset + 1);
+ }
+ }
+ return 0;
+}
+
+int set_tcp_options(tcp_opts_t * options, unsigned long opt_flags, RawEthernetPacket * pkt) {
+ char * pkt_opts = TCP_DATA(pkt->data);
+ int offset = 0;
+
+
+ if (opt_flags & TCP_OPTS_MSS) {
+ *(pkt_opts + offset) = 0x02;
+ *(pkt_opts + offset + 1) = 0x04;
+ *(unsigned short *)(pkt_opts + offset + 2) = ntohs(options->mss);
+ offset += 4;
+ }
+
+
+ *(pkt_opts + offset) = 0x00;
+ offset++;
+
+ SET_IP_TOTAL_LEN(pkt->data, GET_IP_TOTAL_LEN(pkt->data) + offset);
+ compute_ip_checksum(pkt);
+ SET_TCP_HDR_LEN(pkt->data, GET_TCP_HDR_LEN(pkt->data) + offset);
+ compute_tcp_checksum(pkt);
+ pkt->set_size(pkt->get_size() + offset);
+
+ return 0;
+}
+
+unsigned long get_tcp_timestamp(char *opts, int len) {
+ int offset = 0;
+ unsigned long timestamp = 0;
+ unsigned long * ts_ptr;
+
+ while (offset < len) {
+ if (*(opts + offset) == 0x00) {
+ break;
+ } else if (*(opts + offset) == 0x01) {
+ offset++;
+ } else if (*(opts + offset) == 0x08) {
+ offset += 2;
+ ts_ptr = (unsigned long *)(opts + offset);
+ timestamp = (*ts_ptr);
+ break;
+ } else if (*(opts + offset) == 0x02) {
+ offset += *(opts + offset + 1);
+ } else if (*(opts + offset) == 0x03) {
+ offset += *(opts + offset + 1);
+ } else if (*(opts + offset) == 0x04) {
+ // SACK OK
+ offset += 2;
+ } else if (*(opts + offset) == 0x05) {
+ offset += *(opts + offset + 1);
+ } else {
+ offset += *(opts + offset + 1);
+ //JRLDBG("Could not find timestamp\n");
+ //break;
+ }
+ }
+ return timestamp;
+}
+
+void set_tcp_timestamp(char * ts_opt, unsigned long local_ts, unsigned long remote_ts) {
+ int offset = 0;
+
+ // *(ts_opt + offset) = 0x01;
+ //offset++;
+ //*(ts_opt + offset) = 0x01;
+ //offset++;
+ *(ts_opt + offset) = 0x08;
+ offset++;
+ *(ts_opt + offset) = 0x0a;
+ offset++;
+
+ *(unsigned long *)(ts_opt + offset) = local_ts;
+ offset += sizeof(unsigned long);
+
+ *(unsigned long *)(ts_opt + offset) = remote_ts;
+
+ return;
+}
+
+
+
+int pkt_has_timestamp(RawEthernetPacket * pkt) {
+ unsigned short ip_hdr_len = GET_IP_HDR_LEN(pkt->data);
+ unsigned short tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
+ int offset = 0;
+ int len = tcp_hdr_len - 20;
+
+ char * opts = (pkt->data + ETH_HDR_LEN + ip_hdr_len + 20);
+
+ if (len <= 0) {
+ return -1;
+ }
+
+
+
+ while (offset < len) {
+ if (*(opts + offset) == 0x00) {
+ break;
+ } else if (*(opts + offset) == 0x01) {
+ offset++;
+ } else if (*(opts + offset) == 0x08) {
+ return offset;
+ } else {
+ offset += *(opts + offset + 1);
+ //JRLDBG("Could not find timestamp\n");
+ //break;
+ }
+ }
+ return -1;
+
+}
+
+int compute_pkt_size(RawEthernetPacket * pkt) {
+ if (is_ip_pkt(pkt)) {
+ return ETH_HDR_LEN + GET_IP_TOTAL_LEN(pkt->data);
+ }
+
+ return -1;
+}
+
+
+
+
+int is_arp_bcast_pkt(RawEthernetPacket * pkt) {
+ char broadcast[MAC_LEN] = MAC_BCAST;
+
+ if (memcmp(ETH_DST(pkt->data), broadcast, MAC_LEN) == 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+void swap_eth_addrs(RawEthernetPacket * pkt) {
+ char mac_addr[MAC_LEN];
+
+ memcpy(mac_addr, ETH_DST(pkt->data), MAC_LEN);
+
+ // copy the source mac to dest mac
+ memcpy(ETH_DST(pkt->data), ETH_SRC(pkt->data), MAC_LEN);
+
+ // set the dest mac to our taken address
+ memcpy(ETH_SRC(pkt->data), mac_addr, MAC_LEN);
+}
+
+void swap_ip_addrs(RawEthernetPacket * pkt) {
+ unsigned long src_ip;
+ unsigned long dst_ip;
+
+ src_ip = GET_IP_SRC(pkt->data);
+ dst_ip = GET_IP_DST(pkt->data);
+
+ SET_IP_SRC(pkt->data, dst_ip);
+ SET_IP_DST(pkt->data, src_ip);
+}
+
+void swap_ports(RawEthernetPacket * pkt) {
+ unsigned short src_port;
+ unsigned short dst_port;
+
+ src_port = GET_TCP_SRC_PORT(pkt->data);
+ dst_port = GET_TCP_DST_PORT(pkt->data);
+
+ SET_TCP_SRC_PORT(pkt->data, dst_port);
+ SET_TCP_DST_PORT(pkt->data, src_port);
+}
+
+
+int is_syn_pkt(RawEthernetPacket * pkt) {
+ char flags = GET_TCP_FLAGS(pkt->data);
+
+ if ((flags & TCP_SYN) == TCP_SYN) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int is_fin_pkt(RawEthernetPacket * pkt) {
+ char flags = GET_TCP_FLAGS(pkt->data);
+
+
+ if ((flags & TCP_FIN) == TCP_FIN)
+ return 1;
+ return 0;
+}
+
+
+int is_ack_pkt(RawEthernetPacket * pkt) {
+ char flags = GET_TCP_FLAGS(pkt->data);
+
+ if ((flags & TCP_ACK) == TCP_ACK)
+ return 1;
+ return 0;
+ }
+
+int is_dns_pkt(RawEthernetPacket * pkt) {
+ // Right now we just look at the destination port address
+ // there is probably a better way though....
+ if (GET_UDP_DST_PORT(pkt->data) == DNS_PORT) {
+ return 1;
+ }
+ return 0;
+}
+
+int is_tcp_pkt(RawEthernetPacket * pkt) {
+ //int eth_hdr_len = 14;
+ if (is_ip_pkt(pkt)) {
+ // IP packet
+ if (GET_IP_PROTO(pkt->data) == IP_TCP) {
+ // TCP packet
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int is_udp_pkt(RawEthernetPacket * pkt) {
+ if (is_ip_pkt(pkt)) {
+ if (GET_IP_PROTO(pkt->data) == IP_UDP) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int is_arp_pkt(RawEthernetPacket * pkt) {
+ if (GET_ETH_TYPE(pkt->data) == ETH_ARP) {
+ return 1;
+ }
+ return 0;
+}
+
+inline int is_ip_pkt(RawEthernetPacket * pkt) {
+ if (GET_ETH_TYPE(pkt->data) == ETH_IP) {
+ return 1;
+ }
+ return 0;
+}
+
+
+
+unsigned long compute_next_tcp_seq_num(RawEthernetPacket * pkt) {
+ if (is_syn_pkt(pkt)) {
+ return GET_TCP_SEQ_NUM(pkt->data) + 1;
+ } else {
+ return GET_TCP_SEQ_NUM(pkt->data) + GET_TCP_DATA_LEN(pkt->data);
+ }
+
+ return 0;
+}
+
+
+unsigned short compute_ip_checksum(RawEthernetPacket * pkt) {
+ unsigned short ip_cksum;
+ SET_IP_CKSUM(pkt->data, 0);
+ ip_cksum = get_ip_checksum(pkt);
+ SET_IP_CKSUM(pkt->data, ip_cksum);
+ return ip_cksum;
+}
+
+unsigned short compute_tcp_checksum(RawEthernetPacket * pkt) {
+ unsigned short tcp_cksum;
+ SET_TCP_CKSUM(pkt->data, 0);
+ tcp_cksum = get_tcp_checksum(pkt, GET_TCP_TOTAL_LEN(pkt->data));
+ SET_TCP_CKSUM(pkt->data, tcp_cksum);
+ return tcp_cksum;
+}
+
+unsigned short compute_udp_checksum(RawEthernetPacket * pkt) {
+ unsigned short udp_cksum;
+ SET_UDP_CKSUM(pkt->data, 0);
+ udp_cksum = get_udp_checksum(pkt, GET_UDP_LEN(pkt->data));
+
+ // Funky optional checksum... See the RFC
+ if (udp_cksum == 0) {
+ udp_cksum = 0xffff;
+ }
+ SET_UDP_CKSUM(pkt->data, udp_cksum);
+ return udp_cksum;
+}
+
+char * get_eth_protocol(unsigned short protocol) {
+ if (protocol == ETH_IP) {
+ return "IP";
+ } else if (protocol == ETH_ARP) {
+ return "ARP";
+ } else if (protocol == ETH_RARP) {
+ return "RARP";
+ } else {
+ return "Unknown";
+ }
+}
+
+char* get_ip_protocol(unsigned char protocol) {
+ if(protocol == IP_ICMP) {
+ return "ICMP";
+ } else if(protocol == IP_TCP) {
+ return "TCP";
+ } else if(protocol == IP_UDP) {
+ return "UDP";
+ } else if(protocol == 121) {
+ return "SMP";
+ } else {
+ return "Unknown";
+ }
+}
+
+
+unsigned short get_tcp_checksum(RawEthernetPacket * pkt, unsigned short tcp_len) {
+ unsigned short buf[1600];
+ unsigned long src_addr;
+ unsigned long dest_addr;
+ unsigned short len;
+ unsigned short proto;
+
+ len = tcp_len;
+ len += (len % 2) ? 1 : 0;
+
+ src_addr = htonl(GET_IP_SRC(pkt->data));
+ dest_addr = htonl(GET_IP_DST(pkt->data));
+ proto = GET_IP_PROTO(pkt->data);
+
+ *((unsigned long *)(buf)) = src_addr;
+ *((unsigned long *)(buf + 2)) = dest_addr;
+
+ buf[4]=htons(proto);
+ buf[5]=htons(tcp_len);
+ // return 0;
+
+ // memcpy(buf + 6, (pkt->data + ETH_HDR_LEN + GET_IP_HDR_LEN(pkt->data)), tcp_len);
+ memcpy(buf + 6, TCP_HDR(pkt->data), tcp_len);
+ if (tcp_len % 2) {
+ JRLDBG("Odd tcp_len: %hu\n", tcp_len);
+ *(((char*)buf) + 2 * 6 + tcp_len) = 0;
+ }
+
+ return htons(~(OnesComplementSum(buf, len/2+6)));
+}
+
+unsigned short get_udp_checksum(RawEthernetPacket * pkt, unsigned short udp_len) {
+ unsigned short buf[1600];
+ unsigned long src_addr;
+ unsigned long dest_addr;
+ unsigned short len;
+ unsigned short proto;
+
+ len = udp_len;
+ len += (len % 2) ? 1 : 0;
+
+
+ src_addr = GET_IP_SRC(pkt->data);
+ dest_addr = GET_IP_DST(pkt->data);
+ proto = GET_IP_PROTO(pkt->data);
+
+ *((unsigned long *)(buf)) = htonl(src_addr);
+ *((unsigned long *)(buf + 2)) = htonl(dest_addr);
+
+ buf[4]=htons(proto);
+ buf[5]=htons(udp_len);
+ // return 0;
+
+ // memcpy(buf + 6, (pkt->data + ETH_HDR_LEN + GET_IP_HDR_LEN(pkt->data)), udp_len);
+ memcpy(buf + 6, UDP_HDR(pkt->data), udp_len);
+ if (udp_len % 2) {
+ JRLDBG("Odd udp_len: %hu\n", udp_len);
+ *(((char*)buf) + 2 * 6 + udp_len) = 0;
+ }
+
+ return htons(~(OnesComplementSum(buf, len/2+6)));
+}
+
+unsigned short get_ip_checksum(RawEthernetPacket * pkt) {
+ unsigned short buf[10];
+ memset(buf, 0, 10);
+ memcpy((char*)buf, IP_HDR(pkt->data), 20);
+ return htons(~(OnesComplementSum(buf, 10)));
+}
+
+unsigned short OnesComplementSum(unsigned short *buf, int len) {
+ unsigned long sum, sum2, sum3;
+ unsigned short realsum;
+ int i;
+
+ sum=0;
+ for (i=0;i<len;i++) {
+ sum+=ntohs(buf[i]);
+ }
+ // assume there is no carry out, so now...
+
+ sum2 = (sum&0x0000ffff) + ((sum&0xffff0000)>>16);
+
+ sum3 = (sum2&0x0000ffff) +((sum2&0xffff0000)>>16);
+
+ realsum=sum3;
+
+ return realsum;
+}
+
+
+
--- /dev/null
+#ifndef __VTL_UTIL_H
+#define __VTL_UTIL_H 1
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef linux
+#include <sys/socket.h>
+#include <sys/types.h>
+#elif WIN32
+
+#endif
+
+#include "raw_ethernet_packet.h"
+#include "debug.h"
+#include "socks.h"
+
+
+
+typedef struct ip_hdr {
+ unsigned char hdr_len:4, version:4;
+ unsigned char tos;
+ unsigned short total_len;
+ unsigned short id;
+ unsigned char flags:3;
+ unsigned short offset:13;
+ unsigned char ttl;
+ unsigned char proto;
+ unsigned short cksum;
+ unsigned int src_addr;
+ unsigned int dst_addr;
+} ip_hdr_t;
+
+
+struct tcpheader {
+ unsigned short int th_sport;
+ unsigned short int th_dport;
+ unsigned int th_seq;
+ unsigned int th_ack;
+ unsigned char th_x2:4, th_off:4;
+ unsigned char th_flags;
+ unsigned short int th_win;
+ unsigned short int th_sum;
+ unsigned short int th_urp;
+};
+
+struct udpheader {
+ unsigned short int uh_sport;
+ unsigned short int uh_dport;
+ unsigned short int uh_len;
+ unsigned short int uh_check;
+};
+
+struct icmpheader {
+ unsigned char icmp_type;
+ unsigned char icmp_code;
+ unsigned short int icmp_cksum;
+ /* The following data structures are ICMP type specific */
+ unsigned short int icmp_id;
+ unsigned short int icmp_seq;
+};
+
+/* ETHERNET MACROS */
+#define ETH_HDR_LEN 14
+#define MAC_BCAST {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+#define ETH_IP 0x0008
+#define ETH_ARP 0x0608
+#define ETH_RARP 0x3508
+
+#define MAC_LEN 6
+
+#define ETH_DST_OFFSET 0
+#define ETH_SRC_OFFSET 6
+#define ETH_TYPE_OFFSET 12
+#define ETH_DATA_OFFSET 14
+
+#define ETH_DST(pkt) (pkt + ETH_DST_OFFSET)
+#define ETH_SRC(pkt) (pkt + ETH_SRC_OFFSET)
+#define ETH_TYPE(pkt) (pkt + ETH_TYPE_OFFSET)
+#define ETH_DATA(pkt) (pkt + ETH_DATA_OFFSET)
+
+#define SET_ETH_DST(pkt, dst) memcpy(ETH_DST(pkt), dst, 6)
+#define SET_ETH_SRC(pkt, src) memcpy(ETH_SRC(pkt), src, 6)
+#define SET_ETH_TYPE(pkt, type) (*(unsigned short *)(ETH_TYPE(pkt)) = type)
+#define GET_ETH_TYPE(pkt) (*(unsigned short *)ETH_TYPE(pkt))
+#define GET_ETH_DST(pkt, dst) memcpy(dst, ETH_DST(pkt), 6)
+#define GET_ETH_SRC(pkt, src) memcpy(src, ETH_SRC(pkt), 6)
+
+/* ARP MACROS */
+
+#define ARP_HW_TYPE_OFFSET 0
+#define ARP_PROTO_TYPE_OFFSET 2
+#define ARP_HW_LEN_OFFSET 4
+#define ARP_PROTO_LEN_OFFSET 5
+#define ARP_OP_OFFSET 6
+#define ARP_ADDR_OFFSET 8
+
+#define ARP_REQUEST 0x0001
+#define ARP_REPLY 0x0002
+#define RARP_REQUEST 0x0003
+#define RARP_REPLY 0x0004
+
+#define ARP_HDR(pkt) (pkt + ETH_HDR_LEN)
+
+#define ARP_HW_TYPE(pkt) (ARP_HDR(pkt) + ARP_HW_TYPE_OFFSET)
+#define ARP_PROTO_TYPE(pkt) (ARP_HDR(pkt) + ARP_PROTO_TYPE_OFFSET)
+#define ARP_HW_LEN(pkt) (ARP_HDR(pkt) + ARP_HW_LEN_OFFSET)
+#define ARP_PROTO_LEN(pkt) (ARP_HDR(pkt) + ARP_PROTO_LEN_OFFSET)
+#define ARP_OP(pkt) (ARP_HDR(pkt) + ARP_OP_OFFSET)
+#define ARP_SRC_HW(pkt) (ARP_HDR(pkt) + ARP_ADDR_OFFSET)
+#define ARP_SRC_PROTO(pkt) (ARP_HDR(pkt) + ARP_ADDR_OFFSET + GET_ARP_HW_LEN(pkt))
+#define ARP_DST_HW(pkt) (ARP_HDR(pkt) + ARP_ADDR_OFFSET + GET_ARP_HW_LEN(pkt) + GET_ARP_PROTO_LEN(pkt))
+#define ARP_DST_PROTO(pkt) (ARP_HDR(pkt) + ARP_ADDR_OFFSET + (GET_ARP_HW_LEN(pkt) * 2) + GET_ARP_PROTO_LEN(pkt))
+
+#define ARP_DST_MAC(pkt) ARP_DST_HW(pkt)
+#define ARP_DST_IP(pkt) ARP_DST_PROTO(pkt)
+#define ARP_SRC_MAC(pkt) ARP_SRC_HW(pkt)
+#define ARP_SRC_IP(pkt) ARP_SRC_PROTO(pkt)
+
+#define GET_ARP_HW_TYPE(pkt) ntohs(*(unsigned short *)ARP_HW_TYPE(pkt))
+#define GET_ARP_PROTO_TYPE(pkt) ntohs(*(unsigned short *)ARP_PROTO_TYPE(pkt))
+#define GET_ARP_HW_LEN(pkt) (*(char *)ARP_HW_LEN(pkt))
+#define GET_ARP_PROTO_LEN(pkt) (*(char *)ARP_PROTO_LEN(pkt))
+#define GET_ARP_OP(pkt) ntohs(*(unsigned short *)ARP_OP(pkt))
+#define GET_ARP_SRC_HW(pkt, src) memcpy(src, ARP_SRC_HW(pkt), GET_ARP_HW_LEN(pkt))
+#define GET_ARP_SRC_PROTO(pkt, src) memcpy(src, ARP_SRC_PROTO(pkt), GET_ARP_PROTO_LEN(pkt))
+#define GET_ARP_DST_HW(pkt, dst) memcpy(dst, ARP_DST_HW(pkt), GET_ARP_HW_LEN(pkt))
+#define GET_ARP_DST_PROTO(pkt, dst) memcpy(dst, ARP_DST_PROTO(pkt), GET_ARP_PROTO_LEN(pkt))
+
+#define GET_ARP_SRC_MAC(pkt, src) GET_ARP_SRC_HW(pkt, src)
+#define GET_ARP_DST_MAC(pkt, dst) GET_ARP_DST_HW(pkt, dst)
+#define GET_ARP_SRC_IP(pkt) ntohl(*(unsigned long *)ARP_SRC_IP(pkt))
+#define GET_ARP_DST_IP(pkt) ntohl(*(unsigned long *)ARP_DST_IP(pkt))
+
+#define SET_ARP_HW_TYPE(pkt, type) (*(unsigned short *)ARP_HW_TYPE(pkt) = htons(type))
+#define SET_ARP_PROTO_TYPE(pkt, type) (*(unsigned short *)ARP_PROTO_TYPE(pkt) = htons(type))
+#define SET_ARP_HW_LEN(pkt, len) (*(char *)ARP_HW_LEN(pkt) = len)
+#define SET_ARP_PROTO_LEN(pkt, len) (*(char *)ARP_PROTO_LEN(pkt) = len)
+#define SET_ARP_OP(pkt, op) (*(unsigned short *)ARP_OP(pkt) = htons(op))
+#define SET_ARP_SRC_HW(pkt, src) memcpy(ARP_SRC_HW(pkt), src, GET_ARP_HW_LEN(pkt))
+#define SET_ARP_SRC_PROTO(pkt, src) memcpy(ARP_SRC_PROTO(pkt), src, GET_ARP_PROTO_LEN(pkt))
+#define SET_ARP_DST_HW(pkt, dst) memcpy(ARP_DST_HW(pkt), dst, GET_ARP_HW_LEN(pkt))
+#define SET_ARP_DST_PROTO(pkt, dst) memcpy(ARP_DST_PROTO(pkt), dst, GET_ARP_PROTO_LEN(pkt))
+
+#define SET_ARP_SRC_MAC(pkt, src) SET_ARP_SRC_HW(pkt, src)
+#define SET_ARP_DST_MAC(pkt, dst) SET_ARP_DST_HW(pkt, dst)
+#define SET_ARP_SRC_IP(pkt, src) (*(unsigned long *)ARP_SRC_IP(pkt) = htonl(src))
+#define SET_ARP_DST_IP(pkt, dst) (*(unsigned long *)ARP_DST_IP(pkt) = htonl(dst))
+
+
+/* IP MACROS */
+#define IP_SVC_TYPE_OFFSET 1
+#define IP_TOTAL_LEN_OFFSET 2
+#define IP_ID_OFFSET 4
+#define IP_FLAGS_OFFSET 6
+#define IP_FRAG_OFFSET 6
+#define IP_TTL_OFFSET 8
+#define IP_PROTO_OFFSET 9
+#define IP_CKSUM_OFFSET 10
+#define IP_SRC_OFFSET 12
+#define IP_DST_OFFSET 16
+
+
+// These can be fleshed out:
+// http://www.iana.org/assignments/protocol-numbers
+#define IP_ICMP 0x01
+#define IP_TCP 0x06
+#define IP_UDP 0x11
+
+
+#define IP_HDR(pkt) (pkt + ETH_HDR_LEN)
+
+#define IP_HDR_LEN(pkt) (IP_HDR(pkt));
+#define IP_SVC_TYPE(pkt) (IP_HDR(pkt) + IP_SVC_TYPE_OFFSET)
+#define IP_DSCP(pkt) IP_TOS(pkt)
+#define IP_TOTAL_LEN(pkt) (IP_HDR(pkt) + IP_TOTAL_LEN_OFFSET)
+#define IP_ID(pkt) (IP_HDR(pkt) + IP_ID_OFFSET)
+#define IP_FLAGS(pkt) (IP_HDR(pkt) + IP_FLAGS_OFFSET)
+#define IP_FRAG(pkt) (IP_HDR(pkt) + IP_FRAG_OFFSET)
+#define IP_TTOL(pkt) (IP_HDR(pkt) + IP_TTL_OFFSET)
+#define IP_PROTO(pkt) (IP_HDR(pkt) + IP_PROTO_OFFSET)
+#define IP_CKSUM(pkt) (IP_HDR(pkt) + IP_CKSUM_OFFSET)
+#define IP_SRC(pkt) (IP_HDR(pkt) + IP_SRC_OFFSET)
+#define IP_DST(pkt) (IP_HDR(pkt) + IP_DST_OFFSET)
+#define IP_DATA(pkt) (IP_HDR(pkt) + GET_IP_HDR_LEN(pkt))
+
+
+#define GET_IP_VERSION(pkt) (((*(char *)IP_HDR(pkt)) & 0xf0) >> 4)
+#define GET_IP_HDR_LEN(pkt) ((*((char *)IP_HDR(pkt)) & 0x0f) << 2)
+#define GET_IP_SVC_TYPE(pkt) (*(char *)IP_SVC_TYPE(pkt))
+#define GET_IP_DSCP(pkt) (*(char *)IP_DSCP(pkt))
+#define GET_IP_TOTAL_LEN(pkt) ntohs(*(unsigned short *)IP_TOTAL_LEN(pkt))
+#define GET_IP_ID(pkt) ntohs(*(unsigned short *)IP_ID(pkt))
+#define GET_IP_FLAGS(pkt) (*(char *)IP_FLAGS(pkt) & 0xe0)
+#define GET_IP_FRAG(pkt) ntohs(*(unsigned short *)IP_FRAG(pkt) & htons(0x1fff))
+#define GET_IP_TTL(pkt) (*(char *)IP_TTOL(pkt))
+#define GET_IP_PROTO(pkt) (*(char *)IP_PROTO(pkt))
+#define GET_IP_CKSUM(pkt) (*(unsigned short *)IP_CKSUM(pkt))
+#define GET_IP_SRC(pkt) ntohl(*(unsigned long *)IP_SRC(pkt))
+#define GET_IP_DST(pkt) ntohl(*(unsigned long *)IP_DST(pkt))
+
+
+
+void inline SET_IP_VERSION(char * pkt, char version) {
+ *(char *)IP_HDR(pkt) &= 0x0f;
+ *(char *)IP_HDR(pkt) |= ((version & 0x0f) << 4);
+}
+
+void inline SET_IP_HDR_LEN(char * pkt, char len) {
+ *(char *)IP_HDR(pkt) &= 0xf0;
+ *(char *)IP_HDR(pkt) |= ((len >> 2) & 0x0f);
+}
+
+#define SET_IP_SVC_TYPE(pkt, tos) (*(char *)IP_SVC_TYPE(pkt) = tos)
+#define SET_IP_DSCP(pkt, dscp) (*(char *)IP_DSCP(pkt) = dscp)
+#define SET_IP_TOTAL_LEN(pkt, len) (*(unsigned short *)IP_TOTAL_LEN(pkt) = htons(len))
+#define SET_IP_ID(pkt, id) (*(unsigned short *)IP_ID(pkt) = htons(id))
+
+void inline SET_IP_FLAGS(char * pkt, char flags) {
+ *(char *)IP_FLAGS(pkt) &= 0x1f;
+ *(char *)IP_FLAGS(pkt) |= (flags & 0xe0);
+}
+
+void inline SET_IP_FRAG(char * pkt, unsigned short frag) {
+ *(unsigned short *)IP_FRAG(pkt) &= htons(0xe000);
+ *(unsigned short *)IP_FRAG(pkt) |= htons(frag & 0x1fff);
+}
+
+#define SET_IP_TTL(pkt, ttl) (*(char *)IP_TTOL(pkt) = ttl)
+#define SET_IP_PROTO(pkt, proto) (*(char *)IP_PROTO(pkt) = proto)
+#define SET_IP_CKSUM(pkt, cksum) (*(unsigned short *)IP_CKSUM(pkt) = cksum)
+#define SET_IP_SRC(pkt, src) (*(unsigned long *)IP_SRC(pkt) = htonl(src))
+#define SET_IP_DST(pkt, dst) (*(unsigned long *)IP_DST(pkt) = htonl(dst))
+
+unsigned short compute_ip_checksum(RawEthernetPacket * pkt);
+
+/* TCP MACROS */
+#define TCP_SRC_PORT_OFFSET 0
+#define TCP_DST_PORT_OFFSET 2
+#define TCP_SEQ_NUM_OFFSET 4
+#define TCP_ACK_NUM_OFFSET 8
+#define TCP_HDR_LEN_OFFSET 12
+#define TCP_RSVD_OFFSET 12
+#define TCP_FLAGS_OFFSET 13
+#define TCP_WIN_OFFSET 14
+#define TCP_CKSUM_OFFSET 16
+#define TCP_URG_PTR_OFFSET 18
+#define TCP_OPTS_OFFSET 20
+
+
+#define TCP_HDR(pkt) (pkt + ETH_HDR_LEN + GET_IP_HDR_LEN(pkt))
+#define TCP_SRC_PORT(pkt) (TCP_HDR(pkt) + TCP_SRC_PORT_OFFSET)
+#define TCP_DST_PORT(pkt) (TCP_HDR(pkt) + TCP_DST_PORT_OFFSET)
+#define TCP_SEQ_NUM(pkt) (TCP_HDR(pkt) + TCP_SEQ_NUM_OFFSET)
+#define TCP_ACK_NUM(pkt) (TCP_HDR(pkt) + TCP_ACK_NUM_OFFSET)
+#define TCP_HDR_LEN(pkt) (TCP_HDR(pkt) + TCP_HDR_LEN_OFFSET)
+#define TCP_RSVD(pkt) (TCP_HDR(pkt) + TCP_RSVD_OFFSET)
+#define TCP_FLAGS(pkt) (TCP_HDR(pkt) + TCP_FLAGS_OFFSET)
+#define TCP_WIN(pkt) (TCP_HDR(pkt) + TCP_WIN_OFFSET)
+#define TCP_CKSUM(pkt) (TCP_HDR(pkt) + TCP_CKSUM_OFFSET)
+#define TCP_URG_PTR(pkt) (TCP_HDR(pkt) + TCP_URG_PTR_OFFSET)
+#define TCP_OPTS(pkt) (TCP_HDR(pkt) + TCP_OPTS_OFFSET)
+#define TCP_DATA(pkt) (TCP_HDR(pkt) + GET_TCP_HDR_LEN(pkt))
+
+#define GET_TCP_SRC_PORT(pkt) ntohs(*(unsigned short *)TCP_SRC_PORT(pkt))
+#define GET_TCP_DST_PORT(pkt) ntohs(*(unsigned short *)TCP_DST_PORT(pkt))
+#define GET_TCP_SEQ_NUM(pkt) ntohl(*(unsigned long *)TCP_SEQ_NUM(pkt))
+#define GET_TCP_ACK_NUM(pkt) ntohl(*(unsigned long *)TCP_ACK_NUM(pkt))
+#define GET_TCP_HDR_LEN(pkt) (((*(char *)TCP_HDR_LEN(pkt)) & 0xf0) >> 2)
+#define GET_TCP_RSVD(pkt) (((*(unsigned short *)TCP_RSVD(pkt)) & htons(0x0fc0)) >> 6)
+#define GET_TCP_FLAGS(pkt) ((*(char *)TCP_FLAGS(pkt)) & 0x3f)
+#define GET_TCP_EFLAGS(pkt) (*(char *)TCP_FLAGS(pkt))
+#define GET_TCP_WIN(pkt) ntohs(*(unsigned short *)TCP_WIN(pkt))
+#define GET_TCP_CKSUM(pkt) (*(unsigned short *)TCP_CKSUM(pkt))
+#define GET_TCP_URG_PTR(pkt) ntohs(*(unsigned short *)TCP_URG_PTR(pkt))
+
+#define GET_TCP_DATA_LEN(pkt) (GET_IP_TOTAL_LEN(pkt) - (GET_IP_HDR_LEN(pkt) + GET_TCP_HDR_LEN(pkt)))
+#define GET_TCP_TOTAL_LEN(pkt) (GET_IP_TOTAL_LEN(pkt) - GET_IP_HDR_LEN(pkt))
+#define GET_TCP_OPTS_LEN(pkt) (GET_TCP_HDR_LEN(pkt) - 20)
+
+#define SET_TCP_SRC_PORT(pkt, port) ((*(unsigned short *)TCP_SRC_PORT(pkt)) = htons(port))
+#define SET_TCP_DST_PORT(pkt, port) ((*(unsigned short *)TCP_DST_PORT(pkt)) = htons(port))
+#define SET_TCP_SEQ_NUM(pkt, num) ((*(unsigned long *)TCP_SEQ_NUM(pkt)) = htonl(num))
+#define SET_TCP_ACK_NUM(pkt, num) ((*(unsigned long *)TCP_ACK_NUM(pkt)) = htonl(num))
+
+void inline SET_TCP_HDR_LEN(char * pkt, char len) {
+ *(char *)TCP_HDR_LEN(pkt) &= 0x0f;
+ *(char *)TCP_HDR_LEN(pkt) |= ((len << 2) & 0xf0);
+}
+
+void inline SET_TCP_RSVD(char * pkt, char rsvd) {
+ *(unsigned short *)TCP_RSVD(pkt) &= htons(0xf03f);
+ *(char *)TCP_RSVD(pkt) |= ((rsvd >> 2) & 0x0f);
+ *(char *)(TCP_RSVD(pkt) + 1) |= ((rsvd << 6) & 0xc0);
+}
+
+void inline SET_TCP_FLAGS(char * pkt, char flags) {
+ *(char *)TCP_FLAGS(pkt) &= 0xc0;
+ *(char *)TCP_FLAGS(pkt) |= (flags & 0x3f);
+}
+#define SET_TCP_EFLAGS(pkt, eflags) (*(char *)TCP_FLAGS(pkt) = eflags)
+#define SET_TCP_WIN(pkt, win) (*(unsigned short *)TCP_WIN(pkt) = htons(win))
+#define SET_TCP_CKSUM(pkt, cksum) (*(unsigned short *)TCP_CKSUM(pkt) = cksum)
+#define SET_TCP_URG_PTR(pkt, urg) (*(unsigned short *)TCP_URG_PTR(pkt) = htons(urg))
+
+
+#define TCP_OPTS_MSS 0x0001
+#define TCP_OPTS_TS 0x0002
+#define TCP_OPTS_SACK_OK 0x0004
+
+typedef struct tcp_opts {
+ unsigned short mss ;
+ char window;
+ char sack_ok;
+ unsigned long * sack_entries;
+ unsigned long local_ts;
+ unsigned long remote_ts;
+} tcp_opts_t;
+
+#define TCP_FIN 0x01
+#define TCP_SYN 0x02
+#define TCP_RST 0x04
+#define TCP_PSH 0x08
+#define TCP_ACK 0x10
+#define TCP_URG 0x20
+#define TCP_ECN 0x40
+#define TCP_CWR 0x80
+
+#define SET_TCP_FIN_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_FIN)
+#define SET_TCP_SYN_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_SYN)
+#define SET_TCP_RST_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_RST)
+#define SET_TCP_PSH_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_PSH)
+#define SET_TCP_ACK_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_ACK)
+#define SET_TCP_URG_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_URG)
+#define SET_TCP_ECN_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_ECN)
+#define SET_TCP_CWR_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) |= TCP_CWR)
+
+
+
+#define UNSET_TCP_FIN_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_FIN)
+#define UNSET_TCP_SYN_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_SYN)
+#define UNSET_TCP_RST_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_RST)
+#define UNSET_TCP_PSH_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_PSH)
+#define UNSET_TCP_ACK_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_ACK)
+#define UNSET_TCP_URG_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_URG)
+#define UNSET_TCP_ECN_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_ECN)
+#define UNSET_TCP_CWR_FLAG(pkt) (*(char *)TCP_FLAGS(pkt) &= ~TCP_CWR)
+
+int is_syn_pkt(RawEthernetPacket * pkt);
+int is_ack_pkt(RawEthernetPacket * pkt);
+int is_fin_pkt(RawEthernetPacket * pkt);
+
+
+unsigned long compute_next_tcp_seq_num(RawEthernetPacket * pkt);
+unsigned short compute_tcp_checksum(RawEthernetPacket * pkt);
+
+/* UDP MACROS */
+#define UDP_SRC_PORT_OFFSET 0
+#define UDP_DST_PORT_OFFSET 2
+#define UDP_LEN_OFFSET 4
+#define UDP_CKSUM_OFFSET 6
+#define UDP_DATA_OFFSET 8
+
+#define UDP_HDR(pkt) (pkt + ETH_HDR_LEN + GET_IP_HDR_LEN(pkt))
+#define UDP_SRC_PORT(pkt) (UDP_HDR(pkt) + UDP_SRC_PORT_OFFSET)
+#define UDP_DST_PORT(pkt) (UDP_HDR(pkt) + UDP_DST_PORT_OFFSET)
+#define UDP_LEN(pkt) (UDP_HDR(pkt) + UDP_LEN_OFFSET)
+#define UDP_CKSUM(pkt) (UDP_HDR(pkt) + UDP_CKSUM_OFFSET)
+#define UDP_DATA(pkt) (UDP_HDR(pkt) + UDP_DATA_OFFSET)
+
+#define GET_UDP_SRC_PORT(pkt) ntohs(*(unsigned short *)UDP_SRC_PORT(pkt))
+#define GET_UDP_DST_PORT(pkt) ntohs(*(unsigned short *)UDP_DST_PORT(pkt))
+#define GET_UDP_LEN(pkt) ntohs(*(unsigned short *)UDP_LEN(pkt))
+#define GET_UDP_CKSUM(pkt) ntohs(*(unsigned short *)UDP_CKSUM(pkt))
+
+
+#define SET_UDP_SRC_PORT(pkt, src) (*(unsigned short *)UDP_SRC_PORT(pkt) = htons(src))
+#define SET_UDP_DST_PORT(pkt, dst) (*(unsigned short *)UDP_DST_PORT(pkt) = htons(dst))
+#define SET_UDP_LEN(pkt, len) (*(unsigned short *)UDP_LEN(pkt) = htons(len))
+#define SET_UDP_CKSUM(pkt, cksum) (*(unsigned short *)UDP_CKSUM(pkt) = cksum)
+
+unsigned short compute_udp_checksum(RawEthernetPacket * pkt);
+
+/* DNS MACROS */
+
+#define DNS_PORT 53
+
+
+void dbg_print_pkt_info(RawEthernetPacket * pkt);
+void dbg_print_pkt(RawEthernetPacket * pkt);
+void dbg_print_buf(unsigned char * buf, unsigned int len);
+
+
+
+/* Packet Field Utility Functions */
+int is_tcp_pkt(RawEthernetPacket * pkt);
+int is_arp_pkt(RawEthernetPacket * pkt);
+int is_udp_pkt(RawEthernetPacket * pkt);
+int is_ip_pkt(RawEthernetPacket * pkt);
+
+/* UDP Packet queries */
+int is_dns_pkt(RawEthernetPacket * pkt);
+
+/* TCP Packet queries */
+
+int parse_tcp_options(tcp_opts_t * options, RawEthernetPacket * pkt);
+int set_tcp_options(tcp_opts_t * options, unsigned long opt_flags, RawEthernetPacket * pkt);
+
+int compute_pkt_size(RawEthernetPacket * pkt);
+
+/* ARP Packet queries */
+int is_arp_bcast_pkt(RawEthernetPacket * pkt);
+
+/* ARP functions */
+
+
+
+
+
+void swap_eth_addrs(RawEthernetPacket * pkt);
+void swap_ip_addrs(RawEthernetPacket * pkt);
+void swap_ports(RawEthernetPacket * pkt);
+
+int pkt_has_timestamp(RawEthernetPacket * pkt);
+
+char * get_eth_protocol(unsigned short protocol);
+char * get_ip_protocol(unsigned char protocol);
+
+unsigned long get_tcp_timestamp(char *opts, int len);
+unsigned short OnesComplementSum(unsigned short *buf, int len);
+unsigned short get_tcp_checksum(RawEthernetPacket * pkt, unsigned short tcp_len);
+unsigned short get_ip_checksum(RawEthernetPacket * pkt);
+unsigned short get_udp_checksum(RawEthernetPacket * pkt, unsigned short udp_len);
+
+int get_mss(RawEthernetPacket * pkt);
+
+
+void set_tcp_timestamp(char * ts_opt, unsigned long local_ts, unsigned long remote_ts);
+
+
+
+
+#endif
--- /dev/null
+========================================================================\r
+ STATIC LIBRARY : vtl Project Overview\r
+========================================================================\r
+\r
+AppWizard has created this vtl library project for you. \r
+No source files were created as part of your project.\r
+\r
+\r
+vtl.vcproj\r
+ This is the main project file for VC++ projects generated using an Application Wizard. \r
+ It contains information about the version of Visual C++ that generated the file, and \r
+ information about the platforms, configurations, and project features selected with the\r
+ Application Wizard.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+Other notes:\r
+\r
+AppWizard uses "TODO:" comments to indicate parts of the source code you\r
+should add to or customize.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="7.10"\r
+ Name="vtl"\r
+ ProjectGUID="{B9EAD33A-B1FB-4F2C-985C-12CD6116B05D}"\r
+ RootNamespace="vtl"\r
+ Keyword="Win32Proj">\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"/>\r
+ </Platforms>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="Debug"\r
+ IntermediateDirectory="Debug"\r
+ ConfigurationType="4"\r
+ CharacterSet="2">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"\r
+ MinimalRebuild="TRUE"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="5"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="TRUE"\r
+ DebugInformationFormat="4"/>\r
+ <Tool\r
+ Name="VCCustomBuildTool"/>\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ AdditionalDependencies="ws2_32.lib wpcap.lib IPHlpApi.lib packet.lib"\r
+ OutputFile="$(OutDir)/vtl.lib"\r
+ AdditionalLibraryDirectories=""$(SolutionDir)\local\WpdPack\Lib""/>\r
+ <Tool\r
+ Name="VCMIDLTool"/>\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="mkdir $(SolutionDir)\local\lib\r
+mkdir $(SolutionDir)\local\include\r
+copy $(TargetPath) $(SolutionDir)\local\lib\$(TargetFileName)\r
+copy $(SolutionDir)\vtl\vtl.h $(SolutionDir)\local\include\vtl.h\r
+copy $(SolutionDir)\vtl\config.h $(SolutionDir)\local\include\config.h\r
+copy $(SolutionDir)\vtl\debug.h $(SolutionDir)\local\include\debug.h\r
+copy $(SolutionDir)\vtl\if.h $(SolutionDir)\local\include\if.h\r
+copy $(SolutionDir)\vtl\net_util.h $(SolutionDir)\local\include\net_util.h\r
+copy $(SolutionDir)\vtl\raw_ethernet_packet.h $(SolutionDir)\local\include\raw_ethernet_packet.h\r
+copy $(SolutionDir)\vtl\socks.h $(SolutionDir)\local\include\socks.h\r
+copy $(SolutionDir)\vtl\util.h $(SolutionDir)\local\include\util.h\r
+copy $(SolutionDir)\vtl\vtl_harness.h $(SolutionDir)\local\include\vtl_harness.h\r
+copy $(SolutionDir)\vtl\vtl_model.h $(SolutionDir)\local\include\vtl_model.h\r
+copy $(SolutionDir)\vtl\vtl_util.h $(SolutionDir)\local\include\vtl_util.h\r
+"/>\r
+ <Tool\r
+ Name="VCPreBuildEventTool"/>\r
+ <Tool\r
+ Name="VCPreLinkEventTool"/>\r
+ <Tool\r
+ Name="VCResourceCompilerTool"/>\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"/>\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"/>\r
+ <Tool\r
+ Name="VCManagedWrapperGeneratorTool"/>\r
+ <Tool\r
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="Release"\r
+ IntermediateDirectory="Release"\r
+ ConfigurationType="4"\r
+ CharacterSet="2">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"\r
+ RuntimeLibrary="4"\r
+ UsePrecompiledHeader="0"\r
+ WarningLevel="3"\r
+ Detect64BitPortabilityProblems="TRUE"\r
+ DebugInformationFormat="3"/>\r
+ <Tool\r
+ Name="VCCustomBuildTool"/>\r
+ <Tool\r
+ Name="VCLibrarianTool"\r
+ AdditionalDependencies="ws2_32.lib wpcap.lib IPHlpApi.lib packet.lib"\r
+ OutputFile="$(OutDir)/vtl.lib"\r
+ AdditionalLibraryDirectories=""$(SolutionDir)\local\WpdPack\Lib""/>\r
+ <Tool\r
+ Name="VCMIDLTool"/>\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="mkdir $(SolutionDir)\local\lib\r
+mkdir $(SolutionDir)\local\include\r
+copy $(TargetPath) $(SolutionDir)\local\lib\$(TargetFileName)\r
+copy $(SolutionDir)\vtl\vtl.h $(SolutionDir)\local\include\vtl.h\r
+copy $(SolutionDir)\vtl\config.h $(SolutionDir)\local\include\config.h\r
+copy $(SolutionDir)\vtl\debug.h $(SolutionDir)\local\include\debug.h\r
+copy $(SolutionDir)\vtl\if.h $(SolutionDir)\local\include\if.h\r
+copy $(SolutionDir)\vtl\net_util.h $(SolutionDir)\local\include\net_util.h\r
+copy $(SolutionDir)\vtl\raw_ethernet_packet.h $(SolutionDir)\local\include\raw_ethernet_packet.h\r
+copy $(SolutionDir)\vtl\socks.h $(SolutionDir)\local\include\socks.h\r
+copy $(SolutionDir)\vtl\util.h $(SolutionDir)\local\include\util.h\r
+copy $(SolutionDir)\vtl\vtl_harness.h $(SolutionDir)\local\include\vtl_harness.h\r
+copy $(SolutionDir)\vtl\vtl_model.h $(SolutionDir)\local\include\vtl_model.h\r
+copy $(SolutionDir)\vtl\vtl_util.h $(SolutionDir)\local\include\vtl_util.h\r
+"/>\r
+ <Tool\r
+ Name="VCPreBuildEventTool"/>\r
+ <Tool\r
+ Name="VCPreLinkEventTool"/>\r
+ <Tool\r
+ Name="VCResourceCompilerTool"/>\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"/>\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"/>\r
+ <Tool\r
+ Name="VCManagedWrapperGeneratorTool"/>\r
+ <Tool\r
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Source Files"\r
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+ <File\r
+ RelativePath="..\config.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\if.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\net_util.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\raw_ethernet_packet.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\socks.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\util.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\vtl_model.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath="..\vtl_util.cc">\r
+ <FileConfiguration\r
+ Name="Debug|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32">\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ AdditionalIncludeDirectories=""$(SolutionDir)\local\WpdPack\Include""/>\r
+ </FileConfiguration>\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Header Files"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">\r
+ <File\r
+ RelativePath="..\config.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\debug.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\if.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\net_util.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\raw_ethernet_packet.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\socks.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\util.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\vtl.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\vtl_harness.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\vtl_model.h">\r
+ </File>\r
+ <File\r
+ RelativePath="..\vtl_util.h">\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resource Files"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">\r
+ </Filter>\r
+ <File\r
+ RelativePath=".\ReadMe.txt">\r
+ </File>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r