#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netpacket/packet.h>
#include <linux/if_ether.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
int raw_fd;
int sumcnt;
int ipcnt;
int tcpcnt;
int init_rawsocket(char *ethname)
{
struct sockaddr_ll sll;
struct ifreq ifstruct;
int netfd, i;
memset(&sll, 0, sizeof(struct sockaddr_ll));
memset(&ifstruct, 0, sizeof(struct sockaddr_ll));
netfd = socket(PF_PACKET, SOCK_RAW, ETH_P_ALL);
if (netfd == -1)
{
perror("open socket error");
exit(EXIT_FAILURE);
}
snprintf(ifstruct.ifr_name, IF_NAMESIZE, "%s", ethname);
i = ioctl(netfd, SIOCGIFINDEX, &ifstruct);
if (i == -1)
{
perror("get ifindex error");
exit(EXIT_FAILURE);
}
sll.sll_family = PF_PACKET;
sll.sll_ifindex = ifstruct.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);
sll.sll_hatype = ARPHRD_ETHER;
sll.sll_pkttype = PACKET_OTHERHOST;
sll.sll_halen = ETH_ALEN;
sll.sll_addr[6] = 0;
sll.sll_addr[7] = 0;
i = ioctl(netfd, SIOCGIFHWADDR, &ifstruct);
if (i == -1)
{
perror("get ifhwaddr error");
exit(EXIT_FAILURE);
}
printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x
",
(uint8_t)ifstruct.ifr_hwaddr.sa_data[0],
(uint8_t)ifstruct.ifr_hwaddr.sa_data[1],
(uint8_t)ifstruct.ifr_hwaddr.sa_data[2],
(uint8_t)ifstruct.ifr_hwaddr.sa_data[3],
(uint8_t)ifstruct.ifr_hwaddr.sa_data[4],
(uint8_t)ifstruct.ifr_hwaddr.sa_data[5]);
i = ioctl(netfd, SIOCGIFFLAGS, &ifstruct);
if (i == -1)
{
perror("get ifflags error");
exit(EXIT_FAILURE);
}
ifstruct.ifr_flags |= IFF_PROMISC;
i = ioctl(netfd, SIOCSIFFLAGS, &ifstruct);
if (i == -1)
{
perror("set ifflags error");
exit(EXIT_FAILURE);
}
i = bind(netfd, (struct sockaddr *)&sll, sizeof(struct sockaddr_ll));
if (i == -1)
{
perror("bind socket error");
exit(EXIT_FAILURE);
}
return netfd;
}
void procpacket(struct ether_header *eth, int rlen)
{
struct iphdr *ip;
struct tcphdr *tcp;
sumcnt++;
if (ntohs(eth->ether_type) == ETHERTYPE_IP)
{
ipcnt++;
ip = (struct iphdr *)((char *)eth + ETH_HLEN);
if (ip->protocol == IPPROTO_TCP)
{
tcpcnt++;
}
}
//printf("recv a packet %d.
", rlen);
}
void* showcnt(void *para)
{
while (1)
{
fprintf(stderr, "Sum: %10d IP: %10d TCP: %10d
", sumcnt, ipcnt, tcpcnt);
sleep(1);
}
}
int main(int argc, char **argv)
{
int rlen;
char rbuf[1500];
pthread_t tid;
pthread_create(&tid, NULL, showcnt, NULL);
raw_fd = init_rawsocket(argv[1]);
printf("Opened net socket fd: %d
", raw_fd);
while (1)
{
rlen = recvfrom(raw_fd, rbuf, 1500, 0, NULL, NULL);
if (rlen > 0)
{
procpacket((struct ether_header *)rbuf, rlen);
}
}
close(raw_fd);
return EXIT_SUCCESS;
}