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.


1b1099da057712dacc70f32b1c807893216fe2ff
[palacios.git] / misc / network_servers / v3_nbd / v3_nbd.cc
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <sstream>
21
22
23
24 nbd_config_t g_nbd_conf;
25
26 using namespace std;
27 //using namespace __gnu_cxx;
28
29
30
31 config_t g_config;
32
33 int __main (int argc, char ** argv);
34
35 #ifdef linux
36
37 int main(int argc, char ** argv) {
38   return __main(argc, argv);
39 }
40
41 #elif WIN32
42
43 void main() {
44   __main(0, NULL);
45 }
46
47 #endif 
48
49 int __main (int argc, char ** argv) {
50   string config_file;
51   SOCK vnet_sock = 0;
52   struct vnet_config vnet_info;
53   iface_t * iface;
54   if (argc > 2) {
55     usage();
56     exit(0);
57   }
58
59   if (argc == 2) {
60     config_file = string(argv[1]);
61   } else {
62     config_file = VIDS_CONF_FILE;
63   }
64
65
66   int * foo;
67   int num_ports = GetOpenUdpPorts(&foo);
68   int i;
69   for (i = 0; i < num_ports; i++) {
70     printf("port %d open\n", foo[i]);
71   }
72   
73
74   //  g_conf.log_file = "./vids.log";
75
76   if (config_vids(config_file) == -1) {
77     cerr << "Configuration Error" << endl;
78     exit(-1);
79   }
80
81   // JRL DEBUG
82   debug_init(g_config[LOGFILE_TAG].c_str());
83   JRLDBG("testing...\n");
84
85
86
87   // Configure pcap filter...
88
89   vids_loop(iface, vnet_sock, &vnet_info);
90
91   return 0;
92 }
93
94
95 #ifdef linux
96 int vids_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
97   fd_set all_set, read_set;
98   int max_fd = -1;
99   RawEthernetPacket pkt;
100
101   FD_ZERO(&all_set);
102   FD_SET(vnet_sock, &all_set);
103   max_fd = vnet_sock;
104
105
106   while (1) {
107     int nready = 0;
108     read_set = all_set;
109     nready = select(max_fd + 1, &read_set, NULL, NULL, NULL);
110     
111     
112     if (nready == -1) {
113       if (errno == EINTR) {
114         continue;
115       } else {
116         perror("Select returned error: ");
117         break;
118       }
119     }
120     
121
122     if (FD_ISSET(vnet_sock, &read_set)) {
123       //vnet_recv();
124       
125
126     }
127   }
128
129   return 0;
130 }
131
132 #elif WIN32
133 int vids_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
134   int ret;
135   RawEthernetPacket pkt;
136   WSANETWORKEVENTS net_events;
137   WSAEVENT events[2];
138   DWORD event_i;
139   
140   events[VNET_EVENT] = WSACreateEvent();
141   
142   WSAEventSelect(vnet_sock, events[VNET_EVENT], FD_READ | FD_CLOSE);
143   events[IF_EVENT] = if_get_event(iface);
144   
145   while (1) {
146     event_i = WSAWaitForMultipleEvents(2, events, false, WSA_INFINITE, false);
147     cout << "Wait returned" << endl;
148     
149     if (event_i == WAIT_FAILED) {
150       cout << "ERROR: " <<   GetLastError() << endl;
151       exit(-1);
152     }
153     event_i -= WAIT_OBJECT_0;
154     
155     if (event_i == VNET_EVENT) {
156       
157       if (WSAEnumNetworkEvents(vnet_sock, events[event_i], &net_events) == SOCKET_ERROR) {
158         cout << "EnumEventsError: " << WSAGetLastError() << endl;
159         exit(-1);
160       }
161       if (net_events.lNetworkEvents & FD_READ) {
162         
163         JRLDBG("Receied VNET Packet\n");
164         // we received data
165         
166         if (vnet_info->link_type == TCP_LINK) {
167           pkt.Unserialize(vnet_sock);
168         } else if (vnet_info->link_type == UDP_LINK) {
169           pkt.UdpUnserialize(vnet_sock);
170         }
171         
172         process_outbound_pkt(&pkt);
173         
174         if_write_pkt(iface, &pkt);
175         
176       } else if (net_events.lNetworkEvents & FD_CLOSE) {
177         CLOSE(vnet_sock);
178         return 0;
179       }
180       
181     }
182   }
183   
184   return 0;
185 }
186 #endif
187
188
189
190 int config_vids(string conf_file_name) {
191   if (read_config(conf_file_name, &g_config) != 0) {
192     return -1;
193   }
194
195   if (g_config.count(VIDS_SERVER_TAG) > 0) {
196     g_vids_conf.server_addr = ToIPAddress(g_config[VIDS_SERVER_TAG].c_str());
197   } else {
198     printf("Must specify VIDS server address\n");
199     return -1;
200   }
201
202   if (g_config.count(VIDS_SERVER_PORT_TAG) > 0) {
203     g_vids_conf.server_port = atoi(g_config[VIDS_SERVER_PORT_TAG].c_str());
204   } else {
205     printf("Must specify VIDS server port\n");
206     return -1;
207   }
208
209   if (g_config.count(TCP_PORTS_TAG) > 0) {
210     istringstream port_stream(g_config[TCP_PORTS_TAG], istringstream::in);
211     int port;
212     int i = 0;
213     
214     while (port_stream >> port) {
215       if (i >= MAX_PORTS) {
216         cerr << "You specified too many ports to forward, truncating..." << endl;
217         break;
218       }
219       
220       g_vids_conf.tcp_ports[i] = port;      
221       i++;
222     }
223
224     g_vids_conf.num_tcp_ports = i;
225   }
226
227
228
229   if (g_config.count(VIRTUAL_MAC_TAG) > 0) {
230    string_to_mac(g_config[VIRTUAL_MAC_TAG].c_str(), g_vids_conf.virtual_mac);
231   }
232
233   if (g_config.count(LOGFILE_TAG) == 0) {
234     g_config[LOGFILE_TAG] = DEFAULT_LOG_FILE;
235   }
236
237   if (GetLocalMacAddress(g_config[INTERFACE_TAG], g_vids_conf.local_mac) == -1) {
238     cerr << "Could not get local mac address" << endl;
239     return -1;
240   }
241
242
243   return 0;
244 }
245
246
247 int read_config(string conf_file_name) {
248   fstream conf_file(conf_file_name.c_str(), ios::in);
249   char line[MAX_STRING_SIZE];
250
251   while ((conf_file.getline(line, MAX_STRING_SIZE))) {
252     string conf_line = line;
253     string tag;
254     string value;
255     int offset, ltrim_index, rtrim_index;
256
257     if (conf_line[0] == '#') {
258       continue;
259     }
260
261     offset = conf_line.find(":", 0);
262     tag = conf_line.substr(0,offset);
263
264     // kill white space
265     istringstream tag_stream(tag, istringstream::in);
266     tag_stream >> tag;
267
268     if (tag.empty()) {
269       continue;
270     }
271
272     // basic whitespace trimming, we assume that the config handlers will deal with 
273     // tokenizing and further formatting
274     value = conf_line.substr(offset + 1, conf_line.length() - offset);
275     ltrim_index = value.find_first_not_of(" \t");
276     rtrim_index = value.find_last_not_of(" \t");
277     value = value.substr(ltrim_index, (rtrim_index + 1) - ltrim_index);
278
279     g_config[tag] = value;
280   }
281   return 0;
282 }
283
284
285 void usage() {
286   cout << "Usage: vids [config_file]" << endl;
287   return;
288 }