Annotation of embedaddon/libnet/src/libnet_link_win32.c, revision 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>