📄 main.c
字号:
/* * This source code is a part of coLinux source package. * * Dan Aloni <da-x@colinux.org>, 2003-2004 (c) * Alejandro R. Sedeno <asedeno@mit.edu>, 2004 (c) * * The code is licensed under the GPL. See the COPYING file at * the root directory. * */#include <windows.h>#include <winsock2.h>#include <pcap.h>#include <stdio.h>#include <colinux/common/common.h>#include <colinux/user/debug.h>#include <colinux/user/reactor.h>#include <colinux/user/monitor.h>#include <colinux/user/macaddress.h>#include <colinux/os/user/misc.h>#include <colinux/os/current/user/reactor.h>#include "pcap-registry.h"COLINUX_DEFINE_MODULE("colinux-bridged-net-daemon");/******************************************************************************* * Defines */#define PCAP_NAME_HDR "\\Device\\NPF_"/******************************************************************************* * Type Declarations */typedef struct co_win32_pcap { pcap_t *adhandle; struct pcap_pkthdr *pkt_header; u_char *buffer;} co_win32_pcap_t;/* Runtime parameters */typedef struct start_parameters { bool_t show_help; bool_t mac_specified; char mac_address[18]; bool_t name_specified; char interface_name[0x100]; co_id_t instance; int index; int promisc;} start_parameters_t;/******************************************************************************* * Globals */co_win32_pcap_t pcap_packet;co_reactor_t g_reactor = NULL;co_user_monitor_t *g_monitor_handle = NULL;start_parameters_t *daemon_parameters;co_rc_t monitor_receive(co_reactor_user_t user, unsigned char *buffer, unsigned long size){ co_message_t *message; unsigned long message_size; long size_left = size; long position = 0; int pcap_rc; while (size_left > 0) { message = (typeof(message))(&buffer[position]); message_size = message->size + sizeof(*message); size_left -= message_size; if (size_left >= 0) { pcap_rc = pcap_sendpacket(pcap_packet.adhandle, message->data, message->size); /* TODO */ } position += message_size; } return CO_RC(OK);}/******************************************************************************* * Take packet received from pcap and retransmit to coLinux. */co_rc_tco_win32_pcap_read_received(co_win32_pcap_t * pcap_pkt){ struct { co_message_t message; co_linux_message_t linux; char data[pcap_pkt->pkt_header->len]; } message; message.message.from = CO_MODULE_CONET0 + daemon_parameters->index; message.message.to = CO_MODULE_LINUX; message.message.priority = CO_PRIORITY_DISCARDABLE; message.message.type = CO_MESSAGE_TYPE_OTHER; message.message.size = sizeof (message) - sizeof (message.message); message.linux.device = CO_DEVICE_NETWORK; message.linux.unit = daemon_parameters->index; message.linux.size = pcap_pkt->pkt_header->len; memcpy(message.data, pcap_pkt->buffer, pcap_pkt->pkt_header->len); g_monitor_handle->reactor_user->send(g_monitor_handle->reactor_user, (unsigned char *)&message, sizeof(message)); return CO_RC(OK);}/******************************************************************************* * The pcap2Daemon function is spawned as a thread. * It takes packets from winPCap and relays them to the coLinux Daemon. */DWORD WINAPIpcap2Daemon(LPVOID lpParam){ int pcap_status; co_rc_t rc; while (1) { /* Attempt to receive packet from WPcap. */ pcap_status = pcap_next_ex(pcap_packet.adhandle, &pcap_packet.pkt_header, (const u_char **)&pcap_packet.buffer); switch (pcap_status) { case 1: /* Packet read */ rc = co_win32_pcap_read_received(&pcap_packet); if (!CO_OK(rc)) return 0; break; case 0: /* Timeout */ break; default: /* Error or EOF(offline capture only) */ co_debug_lvl(network, 5, "unexpected error %d reading from winPCap.", pcap_status); ExitProcess(0); return 0; } } /* We should never get to here. */ return 0;}/******************************************************************************* * Get the Connection name for an PCAP Interface (using NetCfgInstanceId). */co_rc_t get_device_name(char *name, int name_size, char *actual_name, int actual_name_size){ char connection_string[256]; HKEY connection_key; char name_data[256]; DWORD name_type; const char name_string[] = "Name"; LONG status; DWORD len; snprintf(connection_string, sizeof(connection_string), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, name); status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key); if (status == ERROR_SUCCESS) { len = sizeof(name_data); status = RegQueryValueEx( connection_key, name_string, NULL, &name_type, (PBYTE)name_data, &len); if (status != ERROR_SUCCESS || name_type != REG_SZ) { co_terminal_print("conet-bridged-daemon: error opening registry key: %s\\%s\\%s", NETWORK_CONNECTIONS_KEY, connection_string, name_string); return CO_RC(ERROR); } else { snprintf(actual_name, actual_name_size, "%s", name_data); } RegCloseKey(connection_key); } return CO_RC(OK);}/******************************************************************************* * Initialize winPCap interface. */intpcap_init(){ pcap_if_t *alldevs = NULL; pcap_if_t *device; pcap_if_t *found_device = NULL; int exit_code = 0; pcap_t *adhandle = NULL; char errbuf[PCAP_ERRBUF_SIZE]; u_int netmask; char packet_filter[0x100]; struct bpf_program fcode; co_snprintf(packet_filter, sizeof(packet_filter), "(ether dst %s) or (ether broadcast or multicast) or (ip broadcast or multicast)", daemon_parameters->mac_address); /* Retrieve the device list */ if (pcap_findalldevs(&alldevs, errbuf) == -1) { co_terminal_print("conet-bridged-daemon: error in pcap_findalldevs: %s\n", errbuf); exit_code = -1; goto pcap_out; } if (daemon_parameters->name_specified == PTRUE) co_terminal_print("conet-bridged-daemon: Looking for interface \"%s\"\n", daemon_parameters->interface_name); else co_terminal_print("conet-bridged-daemon: Auto selecting name for bridged interface\n"); device = alldevs; char name_data[256]; char connection_name_data[256]; while (device) { memset(connection_name_data, 0, sizeof(connection_name_data)); snprintf(name_data, sizeof(name_data), "%s", device->name+(sizeof(PCAP_NAME_HDR) - 1)); get_device_name(name_data, sizeof(name_data), connection_name_data, sizeof(connection_name_data)); if (*connection_name_data != 0) { co_terminal_print("conet-bridged-daemon: checking connection: %s\n", connection_name_data); if (daemon_parameters->name_specified == PTRUE) { /* If an exact match exists, over-ride any found device, setting exact match device to it. */ if (strcmp(connection_name_data, daemon_parameters->interface_name) == 0) { found_device = device; break; } /* Do an partial search, if partial search is found, set this device as he found device, but continue looping through devices. */ if (found_device == NULL && strstr(connection_name_data, daemon_parameters->interface_name) != NULL) { found_device = device; } } else { /* If no name specified and network has an address, autoselect first device. */ if (device->addresses) { found_device = device; break; } } } else { co_terminal_print("conet-bridged-daemon: adapter %s doesn't have a connection\n", device->description); } device = device->next; } if (found_device == NULL) { co_terminal_print("conet-bridged-daemon: no matching adapter\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -