From: Jack Lange Date: Sun, 24 May 2009 17:05:56 +0000 (-0500) Subject: added network server files X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=ac93f0773f4c6cef2f2f542240695a8706037d41 added network server files --- diff --git a/misc/network_servers/v3_nbd/Makefile b/misc/network_servers/v3_nbd/Makefile new file mode 100644 index 0000000..5598cfd --- /dev/null +++ b/misc/network_servers/v3_nbd/Makefile @@ -0,0 +1,43 @@ +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 + + + diff --git a/misc/network_servers/v3_nbd/v3_nbd.cc b/misc/network_servers/v3_nbd/v3_nbd.cc new file mode 100644 index 0000000..1b1099d --- /dev/null +++ b/misc/network_servers/v3_nbd/v3_nbd.cc @@ -0,0 +1,288 @@ +/* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include + + + +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; +} diff --git a/misc/network_servers/v3_nbd/v3_nbd.h b/misc/network_servers/v3_nbd/v3_nbd.h new file mode 100644 index 0000000..b7e4e6a --- /dev/null +++ b/misc/network_servers/v3_nbd/v3_nbd.h @@ -0,0 +1,64 @@ +/* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * 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 +#include +#include +#include +#include + +#ifdef linux +#include +#include +#include +#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 diff --git a/misc/network_servers/vtl/Makefile b/misc/network_servers/vtl/Makefile new file mode 100644 index 0000000..885adf9 --- /dev/null +++ b/misc/network_servers/vtl/Makefile @@ -0,0 +1,76 @@ +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 + + + diff --git a/misc/network_servers/vtl/config.cc b/misc/network_servers/vtl/config.cc new file mode 100644 index 0000000..f54d765 --- /dev/null +++ b/misc/network_servers/vtl/config.cc @@ -0,0 +1,43 @@ +#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; +} diff --git a/misc/network_servers/vtl/config.h b/misc/network_servers/vtl/config.h new file mode 100644 index 0000000..70b902a --- /dev/null +++ b/misc/network_servers/vtl/config.h @@ -0,0 +1,27 @@ +#ifndef _config +#define _config +#include +#include +#include +#include +#include + +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 config_t; + + +int read_config(string conf_file_name, config_t * config); + + + +#endif diff --git a/misc/network_servers/vtl/debug.h b/misc/network_servers/vtl/debug.h new file mode 100644 index 0000000..20cb547 --- /dev/null +++ b/misc/network_servers/vtl/debug.h @@ -0,0 +1,61 @@ +#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 diff --git a/misc/network_servers/vtl/if.cc b/misc/network_servers/vtl/if.cc new file mode 100644 index 0000000..b96bbae --- /dev/null +++ b/misc/network_servers/vtl/if.cc @@ -0,0 +1,170 @@ +#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; +} diff --git a/misc/network_servers/vtl/if.h b/misc/network_servers/vtl/if.h new file mode 100644 index 0000000..03be171 --- /dev/null +++ b/misc/network_servers/vtl/if.h @@ -0,0 +1,67 @@ +#ifndef __IF_H +#define __IF_H 1 + +#include "util.h" +#include "debug.h" +#include "raw_ethernet_packet.h" + + + +#ifdef linux +#include +#define LIBNET_ERRORBUF_SIZE 256 +#elif defined(WIN32) +#define WPCAP +#endif + +#include + +#ifdef WIN32 +#include +#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 diff --git a/misc/network_servers/vtl/net_util.cc b/misc/network_servers/vtl/net_util.cc new file mode 100644 index 0000000..7b352ee --- /dev/null +++ b/misc/network_servers/vtl/net_util.cc @@ -0,0 +1,53 @@ +#include +#include + +#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; +} +*/ diff --git a/misc/network_servers/vtl/net_util.h b/misc/network_servers/vtl/net_util.h new file mode 100644 index 0000000..6883c0d --- /dev/null +++ b/misc/network_servers/vtl/net_util.h @@ -0,0 +1,51 @@ +#ifndef __NET_UTIL_H +#define __NET_UTIL_H 1 + +#ifdef linux +#include +#include +#include +#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 diff --git a/misc/network_servers/vtl/raw_ethernet_packet.cc b/misc/network_servers/vtl/raw_ethernet_packet.cc new file mode 100644 index 0000000..90cc098 --- /dev/null +++ b/misc/network_servers/vtl/raw_ethernet_packet.cc @@ -0,0 +1,298 @@ +#include +#include + +#ifdef linux +#include +#include +#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;iget_size();i++) { + bytetohexbyte(data[i],&(buf[n+2*i])); + } + buf[n+2*i]=0; + os<<(char*)buf; + os<<", text=\""; + for (i=0;iget_size();i++) { + char c= data[i]; + if (c>=32 && c<=126) { + os< +#include + +#include "socks.h" + +#ifdef linux +#include +#include +#elif defined(WIN32) + + +#endif + + + +#ifdef USE_SSL +extern "C" { +#define OPENSSL_NO_KRB5 +#include +} +#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 diff --git a/misc/network_servers/vtl/socks.cc b/misc/network_servers/vtl/socks.cc new file mode 100644 index 0000000..2caa571 --- /dev/null +++ b/misc/network_servers/vtl/socks.cc @@ -0,0 +1,1039 @@ +#include "socks.h" +#include +#include +#include +#include + + + +#if defined(__sparc__) +#include +#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 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: " <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: " <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 + + diff --git a/misc/network_servers/vtl/socks.h b/misc/network_servers/vtl/socks.h new file mode 100644 index 0000000..2b2e1a3 --- /dev/null +++ b/misc/network_servers/vtl/socks.h @@ -0,0 +1,173 @@ +#ifndef _socks +#define _socks + +#include "util.h" + +#if defined(WIN32) && !defined(__CYGWIN__) +#include +#include +#include +#include +#else +extern "C" { +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(USE_SSL) +#define OPENSSL_NO_KRB5 +#include +#endif // USE_SSL + +#include +#include +#include +} +#endif + +#include + +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 +#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 diff --git a/misc/network_servers/vtl/test/vtl_ack.cc b/misc/network_servers/vtl/test/vtl_ack.cc new file mode 100644 index 0000000..3e0d615 --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_ack.cc @@ -0,0 +1,79 @@ +#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; + + +} diff --git a/misc/network_servers/vtl/test/vtl_ack.h b/misc/network_servers/vtl/test/vtl_ack.h new file mode 100644 index 0000000..78ba014 --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_ack.h @@ -0,0 +1,11 @@ +#ifndef VTL_ACK_H +#define VTL_ACK_H + +#include "vtl.h" + + +int make_ack_pkt(RawEthernetPacket * data_pkt, RawEthernetPacket * ack_pkt); + + + +#endif diff --git a/misc/network_servers/vtl/test/vtl_ack_test.cc b/misc/network_servers/vtl/test/vtl_ack_test.cc new file mode 100644 index 0000000..93c3e00 --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_ack_test.cc @@ -0,0 +1,479 @@ +#include +#include +#include +#include +#include +#include + +#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; +} + +*/ diff --git a/misc/network_servers/vtl/test/vtl_client.cc b/misc/network_servers/vtl/test/vtl_client.cc new file mode 100644 index 0000000..b072a3c --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_client.cc @@ -0,0 +1,34 @@ +#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"); + } + + + + + } + +} diff --git a/misc/network_servers/vtl/test/vtl_harness.cc b/misc/network_servers/vtl/test/vtl_harness.cc new file mode 100755 index 0000000..6125b45 --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_harness.cc @@ -0,0 +1,633 @@ +#include +#include +#ifdef linux +#include +#include +#include +#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; +} + diff --git a/misc/network_servers/vtl/test/vtl_server.cc b/misc/network_servers/vtl/test/vtl_server.cc new file mode 100644 index 0000000..bc92dfc --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_server.cc @@ -0,0 +1,32 @@ +#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"); + } + + } + +} diff --git a/misc/network_servers/vtl/test/vtl_test.cc b/misc/network_servers/vtl/test/vtl_test.cc new file mode 100644 index 0000000..c500f4c --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_test.cc @@ -0,0 +1,30 @@ +#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"); + } + + } + +} diff --git a/misc/network_servers/vtl/util.cc b/misc/network_servers/vtl/util.cc new file mode 100644 index 0000000..8abf950 --- /dev/null +++ b/misc/network_servers/vtl/util.cc @@ -0,0 +1,363 @@ + +#include "util.h" +#include + +#include + + +#if defined(USE_SSL) +//SSL specific include libraries +#include +#include +#include +#include +#include +#include +#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(); + } +} + diff --git a/misc/network_servers/vtl/util.h b/misc/network_servers/vtl/util.h new file mode 100644 index 0000000..9cf520d --- /dev/null +++ b/misc/network_servers/vtl/util.h @@ -0,0 +1,121 @@ +#ifndef _util +#define _util + + +#include +#include +#include + + +#ifdef linux +#include +#include +#include +#include +#include +#include +#elif defined(WIN32) + +#include +#include +#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 +} +#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 diff --git a/misc/network_servers/vtl/vtl.h b/misc/network_servers/vtl/vtl.h new file mode 100644 index 0000000..332f3de --- /dev/null +++ b/misc/network_servers/vtl/vtl.h @@ -0,0 +1,13 @@ +#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 diff --git a/misc/network_servers/vtl/vtl_harness.h b/misc/network_servers/vtl/vtl_harness.h new file mode 100644 index 0000000..55a25b0 --- /dev/null +++ b/misc/network_servers/vtl/vtl_harness.h @@ -0,0 +1,49 @@ +#ifndef VTL_HARNESS_H +#define VTL_HARNESS_H + +#include "vtl.h" + +#ifdef linux +#include +#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 diff --git a/misc/network_servers/vtl/vtl_model.cc b/misc/network_servers/vtl/vtl_model.cc new file mode 100644 index 0000000..2b95abd --- /dev/null +++ b/misc/network_servers/vtl/vtl_model.cc @@ -0,0 +1,562 @@ +#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)); + } +} diff --git a/misc/network_servers/vtl/vtl_model.h b/misc/network_servers/vtl/vtl_model.h new file mode 100644 index 0000000..f776eae --- /dev/null +++ b/misc/network_servers/vtl/vtl_model.h @@ -0,0 +1,153 @@ +#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 diff --git a/misc/network_servers/vtl/vtl_util.cc b/misc/network_servers/vtl/vtl_util.cc new file mode 100644 index 0000000..87e7803 --- /dev/null +++ b/misc/network_servers/vtl/vtl_util.cc @@ -0,0 +1,587 @@ +#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>16); + + sum3 = (sum2&0x0000ffff) +((sum2&0xffff0000)>>16); + + realsum=sum3; + + return realsum; +} + + + diff --git a/misc/network_servers/vtl/vtl_util.h b/misc/network_servers/vtl/vtl_util.h new file mode 100644 index 0000000..6c4ac77 --- /dev/null +++ b/misc/network_servers/vtl/vtl_util.h @@ -0,0 +1,444 @@ +#ifndef __VTL_UTIL_H +#define __VTL_UTIL_H 1 + + +#include +#include + +#ifdef linux +#include +#include +#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 diff --git a/misc/network_servers/vtl/win32/ReadMe.txt b/misc/network_servers/vtl/win32/ReadMe.txt new file mode 100755 index 0000000..034527f --- /dev/null +++ b/misc/network_servers/vtl/win32/ReadMe.txt @@ -0,0 +1,21 @@ +======================================================================== + STATIC LIBRARY : vtl Project Overview +======================================================================== + +AppWizard has created this vtl library project for you. +No source files were created as part of your project. + + +vtl.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/misc/network_servers/vtl/win32/vtl.vcproj b/misc/network_servers/vtl/win32/vtl.vcproj new file mode 100755 index 0000000..e3a2a17 --- /dev/null +++ b/misc/network_servers/vtl/win32/vtl.vcproj @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/misc/custom.el b/misc/xemacs.scripts/custom.el similarity index 100% rename from misc/custom.el rename to misc/xemacs.scripts/custom.el diff --git a/misc/init.el b/misc/xemacs.scripts/init.el similarity index 100% rename from misc/init.el rename to misc/xemacs.scripts/init.el