當前位置:編程學習大全網 - 編程語言 - 在cygwin下想用c語言調用libpcap實現網絡抓包。是不是cygwin下不支持libpcap?

在cygwin下想用c語言調用libpcap實現網絡抓包。是不是cygwin下不支持libpcap?

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <netdb.h>

#include <sys/ioctl.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/ip.h>

#include <netinet/in.h>

#include <netinet/if_ether.h>

#include <netpacket/packet.h>

#include <net/ethernet.h>

#include <net/if.h>

#include <arpa/inet.h>

#include <errno.h>

/* 接收緩沖區大小 */

#define RCV_BUF_SIZE 1024 * 5

/* 接收緩沖區 */

static int g_iRecvBufSize = RCV_BUF_SIZE;

static char g_acRecvBuf[RCV_BUF_SIZE] = {0};

/* 物理網卡接口,需要根據具體情況修改 */

static const char *g_szIfName = "eth1";

/* 以太網幀封裝的協議類型 */

static const int g_iEthProId[] = { ETHERTYPE_PUP,

ETHERTYPE_SPRITE,

ETHERTYPE_IP,

ETHERTYPE_ARP,

ETHERTYPE_REVARP,

ETHERTYPE_AT,

ETHERTYPE_AARP,

ETHERTYPE_VLAN,

ETHERTYPE_IPX,

ETHERTYPE_IPV6,

ETHERTYPE_LOOPBACK

};

static const char g_szProName[][24] = {

"none", "xerox pup", "sprite", "ip", "arp",

"rarp", "apple-protocol", "apple-arp",

"802.1q", "ipx", "ipv6", "loopback"

};

/* 輸出MAC地址 */

static void ethdump_showMac(const int iType, const char acHWAddr[])

{ int i = 0;

if (0 == iType)

{

printf("SMAC=[");

}

else

{

printf("DMAC=[");

}

for(i = 0; i < ETHER_ADDR_LEN - 1; i++)

{

printf("%02x:", *((unsigned char *)&(acHWAddr[i])));

}

printf("%02x] ", *((unsigned char *)&(acHWAddr[i])));

}

/* 物理網卡混雜模式屬性操作 */

static int ethdump_setPromisc(const char *pcIfName, int fd, int iFlags)

{ int iRet = -1;

struct ifreq stIfr;

/* 獲取接口屬性標誌位 */

strcpy(stIfr.ifr_name, pcIfName);

iRet = ioctl(fd, SIOCGIFFLAGS, &stIfr);

if (0 > iRet)

{ perror("[Error]Get Interface Flags");

return -1;

}

if (0 == iFlags)

{ /* 取消混雜模式 */

stIfr.ifr_flags &= ~IFF_PROMISC;

}

else

{ /* 設置為混雜模式 */

stIfr.ifr_flags |= IFF_PROMISC;

}

iRet = ioctl(fd, SIOCSIFFLAGS, &stIfr);

if (0 > iRet)

{ perror("[Error]Set Interface Flags");

return -1;

}

return 0;

}

/* 獲取L2幀封裝的協議類型 */

static char *ethdump_getProName(const int iProNum)

{ int iIndex = 0;

for(iIndex = 0; iIndex < sizeof(g_iEthProId) / sizeof(g_iEthProId[0]); iIndex++)

{ if (iProNum == g_iEthProId[iIndex])

{

break;

}

}

return (char *)(g_szProName[iIndex + 1]);

}

/* Init L2 Socket */

static int ethdump_initSocket()

{ int iRet = -1;

int fd = -1;

struct ifreq stIf;

struct sockaddr_ll stLocal = {0};

/* 創建SOCKET */

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

if (0 > fd)

{ perror("[Error]Initinate L2 raw socket");

return -1;

}

/* 網卡混雜模式設置 */

ethdump_setPromisc(g_szIfName, fd, 1);

/* 設置SOCKET選項 */

iRet = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &g_iRecvBufSize,sizeof(int));

if (0 > iRet)

{ perror("[Error]Set socket option");

close(fd);

return -1;

}

/* 獲取物理網卡接口索引 */

strcpy(stIf.ifr_name, g_szIfName);

iRet = ioctl(fd, SIOCGIFINDEX, &stIf);

if (0 > iRet)

{ perror("[Error]Ioctl operation");

close(fd);

return -1;

}

/* 綁定物理網卡 */

stLocal.sll_family = PF_PACKET;

stLocal.sll_ifindex = stIf.ifr_ifindex;

stLocal.sll_protocol = htons(ETH_P_ALL);

iRet = bind(fd, (struct sockaddr *)&stLocal, sizeof(stLocal));

if (0 > iRet)

{ perror("[Error]Bind the interface");

close(fd);

return -1;

}

return fd;

}

/* 解析Ethernet幀首部 */

static int ethdump_parseEthHead(const struct ether_header *pstEthHead)

{ unsigned short usEthPktType;

if (NULL == pstEthHead)

{ return -1;}

/* 協議類型、源MAC、目的MAC */

usEthPktType = ntohs(pstEthHead->ether_type);

printf(">>>\nEth-Pkt-Type:0x%04x(%s) ", usEthPktType, ethdump_getProName(usEthPktType));

ethdump_showMac(0, pstEthHead->ether_shost);

ethdump_showMac(1, pstEthHead->ether_dhost);

return 0;

}

/* 解析IP數據包頭 */

static int ethdump_parseIpHead(const struct ip *pstIpHead)

{ struct protoent *pstIpProto = NULL;

if (NULL == pstIpHead)

{ return -1;}

/* 協議類型、源IP地址、目的IP地址 */

pstIpProto = getprotobynumber(pstIpHead->ip_p);

if(NULL != pstIpProto)

{ printf("\nIP-Pkt-Type:%d(%s) ", pstIpHead->ip_p, pstIpProto->p_name); }

else

{ printf("\nIP-Pkt-Type:%d(%s) ", pstIpHead->ip_p, "None");}

printf("SAddr=[%s] ", inet_ntoa(pstIpHead->ip_src));

printf("DAddr=[%s]\n", inet_ntoa(pstIpHead->ip_dst));

return 0;

}

/* 數據幀解析函數 */

static int ethdump_parseFrame(const char *pcFrameData)

{ int iRet = -1;

struct ether_header *pstEthHead = NULL;

struct ip *pstIpHead = NULL;

/* Ethnet幀頭解析 */

pstEthHead = (struct ether_header*)g_acRecvBuf;

iRet = ethdump_parseEthHead(pstEthHead);

if (0 > iRet)

{ return iRet;}

/* IP數據包類型 */

pstIpHead = (struct ip *)(pstEthHead + 1);

iRet = ethdump_parseIpHead(pstIpHead);

return iRet;

}

/* 捕獲網卡數據幀 */

static void ethdump_startCapture(const int fd)

{ int iRet = -1;

socklen_t stFromLen = 0;

/* 循環監聽 */

while(1)

{ /* 清空接收緩沖區 */

memset(g_acRecvBuf, 0, RCV_BUF_SIZE);

/* 接收數據幀 */

iRet = recvfrom(fd, g_acRecvBuf, g_iRecvBufSize, 0, NULL, &stFromLen);

if (0 > iRet)

{ continue;}

/* 解析數據幀 */

ethdump_parseFrame(g_acRecvBuf);

}

}

/* Main */

int main(int argc, char *argv[])

{ int iRet = -1;

int fd = -1;

/* 初始化SOCKET */

fd = ethdump_initSocket();

if(0 > fd) {

return -1;

}

/* 捕獲數據包 */

ethdump_startCapture(fd);

/* 關閉SOCKET */

close(fd);

return 0;

}

編譯命令

gcc -o a a.c

./a

實現效果圖

...

>>>Eth-Pkt-Type:0x0800(ip) SMAC=[00:1a:92:ef:b6:dd] DMAC=[00:24:7e:dc:99:18] IP-Pkt-Type:6(tcp) SAddr=[192.168.0.111] DAddr=[192.168.0.100]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:24:7e:dc:99:18] DMAC=[00:1a:92:ef:b6:dd] IP-Pkt-Type:6(tcp) SAddr=[192.168.0.100] DAddr=[192.168.0.111]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:24:7e:dc:99:18] DMAC=[00:1a:92:ef:b6:dd] IP-Pkt-Type:1(icmp) SAddr=[192.168.0.100] DAddr=[192.168.0.111]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:1a:92:ef:b6:dd] DMAC=[00:24:7e:dc:99:18] IP-Pkt-Type:1(icmp) SAddr=[192.168.0.111] DAddr=[192.168.0.100]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:1a:92:ef:b6:dd] DMAC=[00:24:7e:dc:99:18] IP-Pkt-Type:6(tcp) SAddr=[192.168.0.111] DAddr=[192.168.0.100]

...

  • 上一篇:如何在 Mac OS X 下編譯,安裝 gcc
  • 下一篇:電腦學什麽好就
  • copyright 2024編程學習大全網