Annotation of embedaddon/libnet/src/libnet_link_win32.c, revision 1.1.1.1
1.1 misho 1: /*
2: * $Id: libnet_link_win32.c,v 1.16 2004/02/18 18:19:00 mike Exp $
3: *
4: * libnet
5: * libnet_link_win32.c - low-level win32 libwpcap routines
6: *
7: * Copyright (c) 2001 - 2002 Don Bowman <don@sandvine.com>
8: * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
9: * Copyright (c) 2002 Roberto Larcher <roberto.larcher@libero.it>
10: * All rights reserved.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: */
34:
35: #if (HAVE_CONFIG_H)
36: #include "../include/config.h"
37: #endif
38: #include <winsock2.h>
39: #include <iphlpapi.h> // From the Microsoft Platform SDK
40: #include "../include/win32/libnet.h"
41: #include <assert.h>
42: #include <Packet32.h>
43: #include <Ntddndis.h>
44: #include "iprtrmib.h"
45:
46: int
47: libnet_open_link(libnet_t *l)
48: {
49: DWORD dwErrorCode;
50: NetType IFType;
51:
52: if (l == NULL)
53: {
54: return (-1);
55: }
56:
57: if (l->device == NULL)
58: {
59: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
60: "%s(): NULL device\n", __func__);
61: return (-1);
62: }
63:
64: l->lpAdapter = 0;
65:
66: /* open adapter */
67: l->lpAdapter = PacketOpenAdapter(l->device);
68: if (!l->lpAdapter || (l->lpAdapter->hFile == INVALID_HANDLE_VALUE))
69: {
70: dwErrorCode=GetLastError();
71: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
72: "%s(): unable to open the driver, error Code : %lx\n",
73: __func__, dwErrorCode);
74: return (-1);
75: }
76:
77: /* increase the send buffer */
78: PacketSetBuff(l->lpAdapter, 512000);
79:
80: /*
81: * Assign link type and offset.
82: */
83: if (PacketGetNetType(l->lpAdapter, &IFType))
84: {
85: switch(IFType.LinkType)
86: {
87: case NdisMedium802_3:
88: l->link_type = DLT_EN10MB;
89: l->link_offset = LIBNET_ETH_H;
90: break;
91: case NdisMedium802_5:
92: l->link_type = DLT_IEEE802;
93: l->link_offset = LIBNET_TOKEN_RING_H;
94: break;
95: case NdisMediumFddi:
96: l->link_type = DLT_FDDI;
97: l->link_offset = 0x15;
98: break;
99: case NdisMediumWan:
100: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
101: "%s():, WinPcap has disabled support for Network type (%d)\n",
102: __func__, IFType.LinkType);
103: return (-1);
104: break;
105: case NdisMediumAtm:
106: l->link_type = DLT_ATM_RFC1483;
107: break;
108: case NdisMediumArcnet878_2:
109: l->link_type = DLT_ARCNET;
110: break;
111: default:
112: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
113: "%s(): network type (%d) is not supported\n",
114: __func__, IFType.LinkType);
115: return (-1);
116: break;
117: }
118: }
119: else
120: {
121: dwErrorCode=GetLastError();
122: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
123: "%s(): unable to determine the network type, error Code : %lx\n",
124: __func__, dwErrorCode);
125: return (-1);
126: }
127: return (1);
128: }
129:
130: int
131: libnet_close_link_interface(libnet_t *l)
132: {
133: if (l->lpAdapter)
134: {
135: PacketSetHwFilter(l->lpAdapter, NDIS_PACKET_TYPE_ALL_LOCAL);
136: PacketCloseAdapter(l->lpAdapter);
137: }
138: return (1);
139: }
140:
141: int
142: libnet_write_link(libnet_t *l, u_int8_t *packet, u_int32_t size)
143: {
144: LPPACKET lpPacket;
145: DWORD BytesTransfered;
146:
147: BytesTransfered = -1;
148:
149: if ((lpPacket = PacketAllocatePacket()) == NULL)
150: {
151: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
152: "%s(): failed to allocate the LPPACKET structure\n", __func__);
153: return (-1);
154: }
155: PacketInitPacket(lpPacket, packet, size);
156:
157: /* PacketSendPacket returns a BOOLEAN */
158: if(PacketSendPacket(l->lpAdapter, lpPacket, TRUE))
159: {
160: BytesTransfered = size;
161: }
162:
163: PacketFreePacket(lpPacket);
164: return (BytesTransfered);
165: }
166:
167: struct libnet_ether_addr *
168: libnet_get_hwaddr(libnet_t *l)
169: {
170: /* This implementation is not-reentrant. */
171: static struct libnet_ether_addr *mac;
172:
173: ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1);
174: PPACKET_OID_DATA OidData;
175:
176: int i = 0;
177:
178: if (l == NULL)
179: {
180: return (NULL);
181: }
182:
183: if (l->device == NULL)
184: {
185: if (libnet_select_device(l) == -1)
186: {
187: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
188: "%s(): can't figure out a device to use\n", __func__);
189: return (NULL);
190: }
191: }
192:
193: mac = (struct libnet_ether_addr *)calloc(1,sizeof(struct libnet_ether_addr));
194: if (mac == NULL)
195: {
196: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
197: "%s(): calloc error\n", __func__);
198: return (NULL);
199: }
200:
201: OidData = (struct _PACKET_OID_DATA *) malloc(IoCtlBufferLength);
202:
203: if (OidData == NULL)
204: {
205: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
206: "%s(): OidData is NULL\n", __func__);
207: return(NULL);
208: }
209:
210: if (l->link_type == DLT_IEEE802)
211: {
212: OidData->Oid = OID_802_5_CURRENT_ADDRESS;
213: }
214: else
215: {
216: OidData->Oid = OID_802_3_CURRENT_ADDRESS;
217: }
218:
219: OidData->Length = 6;
220: if((PacketRequest(l->lpAdapter, FALSE, OidData)) == FALSE)
221: {
222: memset(mac, 0, 6);
223: }
224: else
225: {
226: for (i = 0; i < 6; i++)
227: {
228: mac->ether_addr_octet[i] = OidData->Data[i];
229: }
230: }
231: free(OidData);
232: return(mac);
233: }
234:
235: struct hostent *gethostbyname2(const int8_t *name, int af)
236: {
237: // XXX not implemented
238: return(NULL);
239: }
240:
241: BYTE *
242: libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
243: {
244: HRESULT hr;
245: ULONG pulMac[6];
246: ULONG ulLen = 6;
247: static PBYTE pbHexMac;
248: PIP_ADAPTER_INFO pinfo = NULL;
249: DWORD dwSize = 0;
250: struct sockaddr_in sin;
251: static BYTE bcastmac[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
252:
253: BYTE *MAC = libnet_win32_read_arp_table(DestIP);
254:
255: if (MAC==NULL)
256: {
257: memset(pulMac, 0xff, sizeof (pulMac));
258: memset(&sin, 0, sizeof(sin));
259:
260: if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR)
261: {
262: *(int32_t *)&sin.sin_addr = DestIP;
263: GetAdaptersInfo(NULL, &dwSize);
264: pinfo = (PIP_ADAPTER_INFO)GlobalAlloc(GPTR, dwSize);
265: GetAdaptersInfo(pinfo, &dwSize);
266: if(pinfo != NULL)
267: {
268: DestIP = inet_addr(pinfo->GatewayList.IpAddress.String);
269: memset (pulMac, 0xff, sizeof (pulMac));
270: ulLen = 6;
271: if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR)
272: {
273: GlobalFree(pinfo);
274: return(bcastmac);
275: }
276: }
277: else
278: {
279: GlobalFree(pinfo);
280: return(bcastmac); /* ff:ff:ff:ff:ff:ff */
281: }
282: }
283:
284: pbHexMac = (PBYTE) pulMac;
285:
286: return (pbHexMac);
287: }
288: else
289: {
290: return (MAC);
291: }
292: }
293:
294: BYTE * libnet_win32_read_arp_table(DWORD DestIP)
295: {
296: static BYTE buffMAC[6];
297: BOOL fOrder=TRUE;
298: BYTE *MAC=NULL;
299: DWORD status, i, ci;
300:
301: PMIB_IPNETTABLE pIpNetTable = NULL;
302: DWORD Size = 0;
303:
304: memset(buffMAC, 0, sizeof(buffMAC));
305:
306: if((status = GetIpNetTable(pIpNetTable, &Size, fOrder)) == ERROR_INSUFFICIENT_BUFFER)
307: {
308: pIpNetTable = (PMIB_IPNETTABLE) malloc(Size);
309: assert(pIpNetTable);
310: status = GetIpNetTable(pIpNetTable, &Size, fOrder);
311: }
312:
313: if(status == NO_ERROR)
314: {
315: // set current interface
316: ci = pIpNetTable->table[0].dwIndex;
317:
318: for (i = 0; i < pIpNetTable->dwNumEntries; ++i)
319: {
320: if (pIpNetTable->table[i].dwIndex != ci)
321: ci = pIpNetTable->table[i].dwIndex;
322:
323: if(pIpNetTable->table[i].dwAddr == DestIP) // found IP in arp cache
324: {
325: memcpy(buffMAC, pIpNetTable->table[i].bPhysAddr, sizeof(buffMAC));
326: free(pIpNetTable);
327: return buffMAC;
328: }
329: }
330:
331: if (pIpNetTable)
332: free (pIpNetTable);
333: return(NULL);
334: }
335: else
336: {
337: if (pIpNetTable)
338: {
339: free (pIpNetTable);
340: }
341: MAC=NULL;
342: }
343: return(NULL);
344: }
345:
346: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>