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.


IDE/ATA enhancements and bug-fixing: DMA operation
[palacios.git] / misc / network_servers / vtl / if.cc
1 #include "if.h"
2 #include <assert.h>
3
4 iface_t *  if_connect(string if_name, char mode) {
5   char pcap_errbuf[PCAP_ERRBUF_SIZE];
6
7   iface_t * iface = (iface_t *)malloc(sizeof(iface_t));
8   iface->name = new string();
9
10   cout << "device name : " << if_name << endl;
11
12   *(iface->name) = if_name;
13   iface->mode = mode;
14
15
16
17   // mode is relevant only under linux
18 #ifdef linux 
19   if (mode & IF_RD) {
20     if ((iface->pcap_interface = pcap_open_live((char*)if_name.c_str(), 65536, 1, 1, pcap_errbuf)) == NULL) {
21       vtl_debug("Could not initialize pcap\n");
22       return NULL;
23     }
24
25     iface->pcap_fd = pcap_fileno(iface->pcap_interface);
26   }
27
28   if (mode & IF_WR) {
29     char libnet_errbuf[LIBNET_ERRORBUF_SIZE];
30     
31     if ((iface->net_interface = libnet_init(LIBNET_LINK_ADV, (char *)if_name.c_str(), libnet_errbuf)) == NULL) {
32       vtl_debug("Could not initialize libnet\n");
33       return NULL;
34     }
35   }
36
37 #elif defined(WIN32) 
38   if ((iface->pcap_interface = pcap_open_live((char*)if_name.c_str(), 65536, 1, 1, pcap_errbuf)) == NULL) {
39     vtl_debug("Could not initialize pcap\n");
40     return NULL;
41   }
42   
43   pcap_setmintocopy(iface->pcap_interface, 40); 
44   iface->pcap_event = pcap_getevent(iface->pcap_interface);
45 #endif
46
47   return iface;
48 }
49
50 void if_disconnect(iface_t * iface) {
51   free(iface->name);
52   pcap_close(iface->pcap_interface);
53
54 }
55
56 #ifdef WIN32
57 HANDLE if_get_event(iface_t * iface) {
58   return iface->pcap_event;
59   //  return pcap_getevent(iface->pcap_interface);
60 }
61 #endif
62
63 #ifdef linux
64 int if_get_fd(iface_t * iface) {
65   return iface->pcap_fd;
66 }
67 #endif
68
69
70 int if_loop(iface_t * iface, RawEthernetPacket * pkt) {
71   int ret;
72
73   ret = pcap_loop(iface->pcap_interface, 1, pkt_handler, (u_char*)pkt);
74
75   if (ret == 0) {
76     return IF_PACKET;
77   } else if (ret == -2) {
78     return IF_BREAK;
79   } else if (ret == -1) {
80     return IF_CONT;
81   } else {
82     return -1;
83   }
84 }
85
86 void if_break_loop(iface_t * iface) {
87   pcap_breakloop(iface->pcap_interface);
88 }
89
90 void pkt_handler(u_char * pkt, const struct pcap_pkthdr * pkt_header, const u_char * pkt_data) {
91   RawEthernetPacket pkt2((const char *)pkt_data, (unsigned)(pkt_header->len));
92   *(RawEthernetPacket *)pkt = pkt2;
93   ((RawEthernetPacket*)pkt)->set_type("et");
94 }
95
96
97 int if_read_pkt(iface_t * iface, RawEthernetPacket * pkt) {
98   struct pcap_pkthdr header;
99   const u_char * pcap_pkt;
100
101   pcap_pkt = pcap_next(iface->pcap_interface, &header);
102
103   if (pcap_pkt == NULL) {
104     return -1;
105   }
106
107   RawEthernetPacket pkt2((const char *)pcap_pkt, (unsigned)(header.len));
108   *pkt = pkt2;
109
110   pkt->set_type("et");
111
112   return 0;
113 }
114
115
116
117 int if_write_pkt(iface_t * iface, RawEthernetPacket * pkt) {
118   assert((iface != NULL) && (pkt != NULL) && (iface->net_interface != NULL));
119
120 #ifdef linux
121   vtl_debug("Writing pkt size(%lu)\n", pkt->get_size());
122   if (libnet_adv_write_link(iface->net_interface, 
123                             (u_char *)(pkt->get_data()), 
124                             pkt->get_size()) < 0) {
125     vtl_debug("Libnet could not inject packet size (%lu)\n", pkt->get_size());
126     return -1;
127   }
128
129 #elif defined(WIN32)
130   if (pcap_sendpacket(iface->pcap_interface, 
131                       (u_char *)(pkt->get_data()),
132                       pkt->get_size()) < 0) {
133     vtl_debug("PCAP could not inject packet\n");
134     return -1;
135   }
136
137 #endif
138
139   return 0;
140 }
141
142 int if_setup_filter(iface_t * iface, string bpf_str) {
143   struct bpf_program fcode;
144   bpf_u_int32 netmask; 
145   bpf_u_int32 network;
146   char errbuf[PCAP_ERRBUF_SIZE];
147   char * filter_buf;
148         
149
150   filter_buf = (char *)malloc(bpf_str.length());
151   strcpy(filter_buf, bpf_str.c_str());
152   cout << "Setting Getting interface info for " << iface->name << endl;
153   if (pcap_lookupnet(iface->name->c_str(), &network, &netmask, errbuf) == -1) {
154     vtl_debug("Error looking up the network info\n");
155     return -1;
156   }
157
158   netmask=0xffffffff;
159   cout << bpf_str << endl;
160   if (pcap_compile(iface->pcap_interface, &fcode, filter_buf, 1, netmask) < 0) { 
161     vtl_debug("Could not compile bpf filter\n");
162     return -1; 
163   } 
164   
165   if (pcap_setfilter(iface->pcap_interface, &fcode) < 0) { 
166     vtl_debug("Could not insert bpf filter\n");
167     return -1; 
168   } 
169
170   return 0;
171 }