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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
24 nbd_config_t g_nbd_conf;
27 //using namespace __gnu_cxx;
33 int __main (int argc, char ** argv);
37 int main(int argc, char ** argv) {
38 return __main(argc, argv);
49 int __main (int argc, char ** argv) {
52 struct vnet_config vnet_info;
60 config_file = string(argv[1]);
62 config_file = VIDS_CONF_FILE;
67 int num_ports = GetOpenUdpPorts(&foo);
69 for (i = 0; i < num_ports; i++) {
70 printf("port %d open\n", foo[i]);
74 // g_conf.log_file = "./vids.log";
76 if (config_vids(config_file) == -1) {
77 cerr << "Configuration Error" << endl;
82 debug_init(g_config[LOGFILE_TAG].c_str());
83 JRLDBG("testing...\n");
87 // Configure pcap filter...
89 vids_loop(iface, vnet_sock, &vnet_info);
96 int vids_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
97 fd_set all_set, read_set;
99 RawEthernetPacket pkt;
102 FD_SET(vnet_sock, &all_set);
109 nready = select(max_fd + 1, &read_set, NULL, NULL, NULL);
113 if (errno == EINTR) {
116 perror("Select returned error: ");
122 if (FD_ISSET(vnet_sock, &read_set)) {
133 int vids_loop(iface_t * iface, SOCK vnet_sock, struct vnet_config * vnet_info) {
135 RawEthernetPacket pkt;
136 WSANETWORKEVENTS net_events;
140 events[VNET_EVENT] = WSACreateEvent();
142 WSAEventSelect(vnet_sock, events[VNET_EVENT], FD_READ | FD_CLOSE);
143 events[IF_EVENT] = if_get_event(iface);
146 event_i = WSAWaitForMultipleEvents(2, events, false, WSA_INFINITE, false);
147 cout << "Wait returned" << endl;
149 if (event_i == WAIT_FAILED) {
150 cout << "ERROR: " << GetLastError() << endl;
153 event_i -= WAIT_OBJECT_0;
155 if (event_i == VNET_EVENT) {
157 if (WSAEnumNetworkEvents(vnet_sock, events[event_i], &net_events) == SOCKET_ERROR) {
158 cout << "EnumEventsError: " << WSAGetLastError() << endl;
161 if (net_events.lNetworkEvents & FD_READ) {
163 JRLDBG("Receied VNET Packet\n");
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);
172 process_outbound_pkt(&pkt);
174 if_write_pkt(iface, &pkt);
176 } else if (net_events.lNetworkEvents & FD_CLOSE) {
190 int config_vids(string conf_file_name) {
191 if (read_config(conf_file_name, &g_config) != 0) {
195 if (g_config.count(VIDS_SERVER_TAG) > 0) {
196 g_vids_conf.server_addr = ToIPAddress(g_config[VIDS_SERVER_TAG].c_str());
198 printf("Must specify VIDS server address\n");
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());
205 printf("Must specify VIDS server port\n");
209 if (g_config.count(TCP_PORTS_TAG) > 0) {
210 istringstream port_stream(g_config[TCP_PORTS_TAG], istringstream::in);
214 while (port_stream >> port) {
215 if (i >= MAX_PORTS) {
216 cerr << "You specified too many ports to forward, truncating..." << endl;
220 g_vids_conf.tcp_ports[i] = port;
224 g_vids_conf.num_tcp_ports = i;
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);
233 if (g_config.count(LOGFILE_TAG) == 0) {
234 g_config[LOGFILE_TAG] = DEFAULT_LOG_FILE;
237 if (GetLocalMacAddress(g_config[INTERFACE_TAG], g_vids_conf.local_mac) == -1) {
238 cerr << "Could not get local mac address" << endl;
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];
251 while ((conf_file.getline(line, MAX_STRING_SIZE))) {
252 string conf_line = line;
255 int offset, ltrim_index, rtrim_index;
257 if (conf_line[0] == '#') {
261 offset = conf_line.find(":", 0);
262 tag = conf_line.substr(0,offset);
265 istringstream tag_stream(tag, istringstream::in);
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);
279 g_config[tag] = value;
286 cout << "Usage: vids [config_file]" << endl;