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
[palacios.git] / misc / network_servers / vtl / if.cc
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;
+}