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.


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