Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added network server files
Jack Lange [Sun, 24 May 2009 17:05:56 +0000 (12:05 -0500)]
34 files changed:
misc/network_servers/v3_nbd/Makefile [new file with mode: 0644]
misc/network_servers/v3_nbd/v3_nbd.cc [new file with mode: 0644]
misc/network_servers/v3_nbd/v3_nbd.h [new file with mode: 0644]
misc/network_servers/vtl/Makefile [new file with mode: 0644]
misc/network_servers/vtl/config.cc [new file with mode: 0644]
misc/network_servers/vtl/config.h [new file with mode: 0644]
misc/network_servers/vtl/debug.h [new file with mode: 0644]
misc/network_servers/vtl/if.cc [new file with mode: 0644]
misc/network_servers/vtl/if.h [new file with mode: 0644]
misc/network_servers/vtl/net_util.cc [new file with mode: 0644]
misc/network_servers/vtl/net_util.h [new file with mode: 0644]
misc/network_servers/vtl/raw_ethernet_packet.cc [new file with mode: 0644]
misc/network_servers/vtl/raw_ethernet_packet.h [new file with mode: 0644]
misc/network_servers/vtl/socks.cc [new file with mode: 0644]
misc/network_servers/vtl/socks.h [new file with mode: 0644]
misc/network_servers/vtl/test/vtl_ack.cc [new file with mode: 0644]
misc/network_servers/vtl/test/vtl_ack.h [new file with mode: 0644]
misc/network_servers/vtl/test/vtl_ack_test.cc [new file with mode: 0644]
misc/network_servers/vtl/test/vtl_client.cc [new file with mode: 0644]
misc/network_servers/vtl/test/vtl_harness.cc [new file with mode: 0755]
misc/network_servers/vtl/test/vtl_server.cc [new file with mode: 0644]
misc/network_servers/vtl/test/vtl_test.cc [new file with mode: 0644]
misc/network_servers/vtl/util.cc [new file with mode: 0644]
misc/network_servers/vtl/util.h [new file with mode: 0644]
misc/network_servers/vtl/vtl.h [new file with mode: 0644]
misc/network_servers/vtl/vtl_harness.h [new file with mode: 0644]
misc/network_servers/vtl/vtl_model.cc [new file with mode: 0644]
misc/network_servers/vtl/vtl_model.h [new file with mode: 0644]
misc/network_servers/vtl/vtl_util.cc [new file with mode: 0644]
misc/network_servers/vtl/vtl_util.h [new file with mode: 0644]
misc/network_servers/vtl/win32/ReadMe.txt [new file with mode: 0755]
misc/network_servers/vtl/win32/vtl.vcproj [new file with mode: 0755]
misc/xemacs.scripts/custom.el [moved from misc/custom.el with 100% similarity]
misc/xemacs.scripts/init.el [moved from misc/init.el with 100% similarity]

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