X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=misc%2Fnetwork_servers%2Fvtl%2Fif.cc;fp=misc%2Fnetwork_servers%2Fvtl%2Fif.cc;h=b96bbae3f35a2973b3d8ba0655334e6cd40231c3;hp=0000000000000000000000000000000000000000;hb=ac93f0773f4c6cef2f2f542240695a8706037d41;hpb=c016bb46bd68474161e275a5ace086c3fb810d9f diff --git a/misc/network_servers/vtl/if.cc b/misc/network_servers/vtl/if.cc new file mode 100644 index 0000000..b96bbae --- /dev/null +++ b/misc/network_servers/vtl/if.cc @@ -0,0 +1,170 @@ +#include "if.h" + +iface_t * if_connect(string if_name, char mode) { + char pcap_errbuf[PCAP_ERRBUF_SIZE]; + + iface_t * iface = (iface_t *)malloc(sizeof(iface_t)); + iface->name = new string(); + + cout << "device name : " << if_name << endl; + + *(iface->name) = if_name; + iface->mode = mode; + + + + // mode is relevant only under linux +#ifdef linux + if (mode & IF_RD) { + if ((iface->pcap_interface = pcap_open_live((char*)if_name.c_str(), 65536, 1, 1, pcap_errbuf)) == NULL) { + JRLDBG("Could not initialize pcap\n"); + return NULL; + } + + iface->pcap_fd = pcap_fileno(iface->pcap_interface); + } + + if (mode & IF_WR) { + char libnet_errbuf[LIBNET_ERRORBUF_SIZE]; + + if ((iface->net_interface = libnet_init(LIBNET_LINK_ADV, (char *)if_name.c_str(), libnet_errbuf)) == NULL) { + JRLDBG("Could not initialize libnet\n"); + return NULL; + } + } + +#elif defined(WIN32) + if ((iface->pcap_interface = pcap_open_live((char*)if_name.c_str(), 65536, 1, 1, pcap_errbuf)) == NULL) { + JRLDBG("Could not initialize pcap\n"); + return NULL; + } + + pcap_setmintocopy(iface->pcap_interface, 40); + iface->pcap_event = pcap_getevent(iface->pcap_interface); +#endif + + return iface; +} + +void if_disconnect(iface_t * iface) { + free(iface->name); + pcap_close(iface->pcap_interface); + +} + +#ifdef WIN32 +HANDLE if_get_event(iface_t * iface) { + return iface->pcap_event; + // return pcap_getevent(iface->pcap_interface); +} +#endif + +#ifdef linux +int if_get_fd(iface_t * iface) { + return iface->pcap_fd; +} +#endif + + +int if_loop(iface_t * iface, RawEthernetPacket * pkt) { + int ret; + + ret = pcap_loop(iface->pcap_interface, 1, pkt_handler, (u_char*)pkt); + + if (ret == 0) { + return IF_PACKET; + } else if (ret == -2) { + return IF_BREAK; + } else if (ret == -1) { + return IF_CONT; + } else { + return -1; + } +} + +void if_break_loop(iface_t * iface) { + pcap_breakloop(iface->pcap_interface); +} + +void pkt_handler(u_char * pkt, const struct pcap_pkthdr * pkt_header, const u_char * pkt_data) { + RawEthernetPacket pkt2((const char *)pkt_data, (unsigned)(pkt_header->len)); + *(RawEthernetPacket *)pkt = pkt2; + ((RawEthernetPacket*)pkt)->set_type("et"); +} + + +int if_read_pkt(iface_t * iface, RawEthernetPacket * pkt) { + struct pcap_pkthdr header; + const u_char * pcap_pkt; + + pcap_pkt = pcap_next(iface->pcap_interface, &header); + + if (pcap_pkt == NULL) { + return -1; + } + + RawEthernetPacket pkt2((const char *)pcap_pkt, (unsigned)(header.len)); + *pkt = pkt2; + + pkt->set_type("et"); + + return 0; +} + + + +int if_write_pkt(iface_t * iface, RawEthernetPacket * pkt) { + ASSERT((iface != NULL) && (pkt != NULL) && (iface->net_interface != NULL)); + +#ifdef linux + JRLDBG("Writing pkt size(%d)\n", pkt->get_size()); + if (libnet_adv_write_link(iface->net_interface, + (u_char *)(pkt->get_data()), + pkt->get_size()) < 0) { + JRLDBG("Libnet could not inject packet size (%d)\n", pkt->get_size()); + return -1; + } + +#elif defined(WIN32) + if (pcap_sendpacket(iface->pcap_interface, + (u_char *)(pkt->get_data()), + pkt->get_size()) < 0) { + JRLDBG("PCAP could not inject packet\n"); + return -1; + } + +#endif + + return 0; +} + +int if_setup_filter(iface_t * iface, string bpf_str) { + struct bpf_program fcode; + bpf_u_int32 netmask; + bpf_u_int32 network; + char errbuf[PCAP_ERRBUF_SIZE]; + char * filter_buf; + + + filter_buf = (char *)malloc(bpf_str.length()); + strcpy(filter_buf, bpf_str.c_str()); + cout << "Setting Getting interface info for " << iface->name << endl; + if (pcap_lookupnet(iface->name->c_str(), &network, &netmask, errbuf) == -1) { + JRLDBG("Error looking up the network info\n"); + return -1; + } + + netmask=0xffffffff; + cout << bpf_str << endl; + if (pcap_compile(iface->pcap_interface, &fcode, filter_buf, 1, netmask) < 0) { + JRLDBG("Could not compile bpf filter\n"); + return -1; + } + + if (pcap_setfilter(iface->pcap_interface, &fcode) < 0) { + JRLDBG("Could not insert bpf filter\n"); + return -1; + } + + return 0; +}