在cygwin下想用c语言调用libpcap实现网络抓包。是否cygwin下不支持libpcap?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在cygwin下想用c语言调用libpcap实现网络抓包。是否cygwin下不支持libpcap?相关的知识,希望对你有一定的参考价值。
我要用c语言在cygwin下实现一个简单的网络抓包程序应该怎么做?请大大帮帮忙啊,不胜感激。
希望能给出能调通的源码~~~~求高手相助!!!!
#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]
... 参考技术A 用 libpcap在windows下对应的winpcap吧追问
我们老师是要在linux环境下的。应该也大同小异,有可用代码给我参考吗?
追答这个暂时没有
参考技术B 这个有点复杂,没做过!netbeans 中的 C pthread_barriers (cygwin)
【中文标题】netbeans 中的 C pthread_barriers (cygwin)【英文标题】:C pthread_barriers in netbeans (cygwin) 【发布时间】:2015-02-23 08:35:04 【问题描述】:我想用 netbeans 编写一些学校的 C 任务。他们给了我们必须使用 pthread_barrier 的任务。所以我用 gcc、g++、gdb 和 make 下载了 netbeans 和 cygwin。在pthreads.h
中没有任何pthread_barrier_t
等。在this question 中,我发现“障碍是在POSIX 1003.1 2004 版的可选部分中定义的”。问题是如何在 cygwin 中使用 netbeans 中的障碍?
一些代码:
//#define _POSIX_BARRIERS 1
//I don't get it what they mean
//"only if the _POSIX_BARRIERS macro is defined as positive number,
//you can use pthread_barrier_t"
#define _XOPEN_SOURCE 600
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
// declaration of the barrier
pthread_barrier_t a_barrier; // err: Unable to resolve identifier pthread_barrier_t.
【问题讨论】:
【参考方案1】:Cygwin 目前不支持pthread_barrier_*
,因此您将无法在 Cygwin 上编译或运行需要这些的代码。
【讨论】:
以上是关于在cygwin下想用c语言调用libpcap实现网络抓包。是否cygwin下不支持libpcap?的主要内容,如果未能解决你的问题,请参考以下文章