blob: 22e50635f150d102247b97c1727779a57c3c8646 [file] [log] [blame]
oliverschmidtb025e432007-09-05 16:11:04 +00001/*
2 * Copyright (c) 2007, Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. Neither the name of the Institute nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * This file is part of the uIP TCP/IP stack.
33 *
34 * Author: Oliver Schmidt <ol.sc@web.de>
35 *
36 * $Id: wpcap.c,v 1.1 2007/09/05 16:11:08 oliverschmidt Exp $
37 */
38
39#define WIN32_LEAN_AND_MEAN
40#define _WIN32_WINNT 0x0501
41#include <windows.h>
42#include <winsock2.h>
43#include <iphlpapi.h>
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <malloc.h>
48
49#define htonl contiki_htonl /* htonl is defined in winsock2 */
50#define htons contiki_htons /* htons is defined in winsock2 */
51
52#include "uip.h"
53#include "uip_arp.h"
54#include "ctk.h"
55#include "wpcap.h"
56
57struct pcap;
58
59struct pcap_if {
60 struct pcap_if *next;
61 char *name;
62 char *description;
63 struct pcap_addr {
64 struct pcap_addr *next;
65 struct sockaddr *addr;
66 struct sockaddr *netmask;
67 struct sockaddr *broadaddr;
68 struct sockaddr *dstaddr;
69 } *addresses;
70 DWORD flags;
71};
72
73struct pcap_pkthdr {
74 struct timeval ts;
75 DWORD caplen;
76 DWORD len;
77};
78
79HMODULE wpcap;
80
81static struct pcap *pcap;
82
83static int (* pcap_findalldevs)(struct pcap_if **, char *);
84static struct pcap *(* pcap_open_live)(char *, int, int, int, char *);
85static int (* pcap_next_ex)(struct pcap *, struct pcap_pkthdr **, unsigned char **);
86static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int);
87
88#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
89
90extern void debug_printf(char *format, ...);
91
92/*---------------------------------------------------------------------------*/
93static void
94error_exit(char *message)
95{
96 console_exit();
97 cprintf(message);
98 exit(EXIT_FAILURE);
99}
100/*---------------------------------------------------------------------------*/
101static void
102init_pcap(struct in_addr addr)
103{
104 struct pcap_if *interfaces;
105 char error[256];
106
107 if(pcap_findalldevs(&interfaces, error) == -1) {
108 error_exit(error);
109 }
110
111 while(interfaces != NULL) {
112 debug_printf("init_pcap: found interface: %s\n", interfaces->description);
113
114 if(interfaces->addresses != NULL &&
115 interfaces->addresses->addr != NULL &&
116 interfaces->addresses->addr->sa_family == AF_INET) {
117
118 struct in_addr interface_addr;
119 interface_addr = ((struct sockaddr_in *)interfaces->addresses->addr)->sin_addr;
120 debug_printf("init_pcap: with address: %s\n", inet_ntoa(interface_addr));
121
122 if(interface_addr.s_addr == addr.s_addr) {
123 break;
124 }
125 }
126 interfaces = interfaces->next;
127 }
128
129 if(interfaces == NULL) {
130 error_exit("no interface found with ip addr specified on cmdline\n");
131 }
132
133 pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error);
134 if(pcap == NULL) {
135 error_exit(error);
136 }
137}
138/*---------------------------------------------------------------------------*/
139static void
140set_ethaddr(struct in_addr addr)
141{
142 PIP_ADAPTER_ADDRESSES adapters;
143 ULONG size = 0;
144
145 if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST |
146 GAA_FLAG_SKIP_MULTICAST |
147 GAA_FLAG_SKIP_DNS_SERVER,
148 NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) {
149 error_exit("error on access to adapter list size\n");
150 }
151 adapters = alloca(size);
152 if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST |
153 GAA_FLAG_SKIP_MULTICAST |
154 GAA_FLAG_SKIP_DNS_SERVER,
155 NULL, adapters, &size) != ERROR_SUCCESS) {
156 error_exit("error on access to adapter list\n");
157 }
158
159 while(adapters != NULL) {
160
161 char buffer[256];
162 WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1,
163 buffer, sizeof(buffer), NULL, NULL);
164 debug_printf("set_ethaddr: found adapter: %s\n", buffer);
165
166 if(adapters->FirstUnicastAddress != NULL &&
167 adapters->FirstUnicastAddress->Address.lpSockaddr != NULL &&
168 adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET) {
169
170 struct in_addr adapter_addr;
171 adapter_addr = ((struct sockaddr_in *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin_addr;
172 debug_printf("set_ethaddr: with address: %s\n", inet_ntoa(adapter_addr));
173
174 if(adapter_addr.s_addr == addr.s_addr) {
175 if(adapters->PhysicalAddressLength != 6) {
176 error_exit("ip addr specified on cmdline does not belong to an ethernet card\n");
177 }
178 debug_printf("set_ethaddr: ethernetaddr: %02X-%02X-%02X-%02X-%02X-%02X\n",
179 adapters->PhysicalAddress[0], adapters->PhysicalAddress[1],
180 adapters->PhysicalAddress[2], adapters->PhysicalAddress[3],
181 adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]);
182
183 uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress));
184 break;
185 }
186 }
187 adapters = adapters->Next;
188 }
189
190 if(adapters == NULL) {
191 error_exit("no adapter found with ip addr specified on cmdline\n");
192 }
193}
194/*---------------------------------------------------------------------------*/
195void
196wpcap_init(void)
197{
198 struct in_addr addr;
199
200 addr.s_addr = inet_addr(__argv[1]);
201 if(addr.s_addr == INADDR_NONE) {
202 error_exit("usage: <program> <ip addr of ethernet card to share>\n");
203 }
204 debug_printf("wpcap_init: cmdline address: %s\n", inet_ntoa(addr));
205
206 wpcap = LoadLibrary("wpcap.dll");
207 (FARPROC)pcap_findalldevs = GetProcAddress(wpcap, "pcap_findalldevs");
208 (FARPROC)pcap_open_live = GetProcAddress(wpcap, "pcap_open_live");
209 (FARPROC)pcap_next_ex = GetProcAddress(wpcap, "pcap_next_ex");
210 (FARPROC)pcap_sendpacket = GetProcAddress(wpcap, "pcap_sendpacket");
211
212 if(pcap_findalldevs == NULL || pcap_open_live == NULL ||
213 pcap_next_ex == NULL || pcap_sendpacket == NULL) {
214 error_exit("error on access to winpcap library\n");
215 }
216
217 init_pcap(addr);
218 set_ethaddr(addr);
219}
220/*---------------------------------------------------------------------------*/
221u16_t
222wpcap_poll(void)
223{
224 struct pcap_pkthdr *packet_header;
225 unsigned char *packet;
226
227 if(pcap == NULL) {
228 return 0;
229 }
230
231 switch(pcap_next_ex(pcap, &packet_header, &packet)) {
232 case -1:
233 error_exit("error on read\n");
234 case 0:
235 return 0;
236 }
237
238 if(packet_header->caplen > UIP_BUFSIZE) {
239 return 0;
240 }
241
242 CopyMemory(uip_buf, packet, packet_header->caplen);
243 return (u16_t)packet_header->caplen;
244}
245/*---------------------------------------------------------------------------*/
246void
247wpcap_send(void)
248{
249 if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) {
250 error_exit("error on send\n");
251 }
252}
253/*---------------------------------------------------------------------------*/
254void
255wpcap_exit(void)
256{
257 FreeLibrary(wpcap);
258 pcap = NULL;
259}
260/*---------------------------------------------------------------------------*/