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>