日期:2014-05-16  浏览次数:20746 次

Linux下使用socket进行网卡抓包

有时候需要自己编写代码进行抓包,以找出特殊意义的包。

下面是简单的一个示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <ioctl.h>

int main (int argc, char *argv[])
{
    int sockfd;
    int ret = 0;
    char buffer[1518] = {0};
    char *eth_head = NULL;

   /* PF_PACKET:链路层,  SOCK_RAW: 包含 mac头, ETH_P_ALL: 所有协议  */

   if ((sockfd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
   {
       printf ("create socket failed\n");
       return -1;
   }

   while (1)
   {
        memset (buffer, 0x0, sizeof (buffer));
        ret = recvfrom (sockfd, buffer, sizeof (buffer), 0, NULL, NULL);
        printf ("recview package length : %d\n", ret);

        eth_head = buffer;
        printf ("PACKAGE START\n");
        /* get source and dectination mac address */
        printf ("dectination mac:%02x-%02x-%02x-%02x-%02x-%02x,"
                "source mac:%02x-%02x-%02x-%02x-%02x-%02x;\n", eth_head[0],
                eth_head[1], eth_head[2], eth_head[3], eth_head[4],
                eth_head[5], eth_head[6], eth_head[7], eth_head[8],
                eth_head[9], eth_head[10], eth_head[11]);
        printf ("eth_type:%02x%02x\n", eth_head[12], eth_head[13]);

        /* ARP proptocol flag */
        if (0x08 == eth_head[12] && 0x06 == eth_head[13])
        {
            printf ("ARP source ip:%d.%d.%d.%d,destination ip:%d.%d.%d.%d;\n",
                    eth_head[28], eth_head[29], eth_head[30], eth_head[31],
                    eth_head[38], eth_head[39], eth_head[40], eth_head[41]);
        }
        /* IPv4 proptocol flag */
        else if (0x08 == eth_head[12] && 0x00 == eth_head[13])
        {
            if (0x45 == eth_head[14])
            {
                printf ("IPv4 source ip:%d.%d.%d.%d,destination ip:%d.%d.%d."
                        "%d;\n", eth_head[26], eth_head[27], eth_head[28],
                        eth_head[29