linux或者Android使用内核抓包c语言程序

linux或者Android使用内核抓包c语言程序

本文连接:https://i.cnblogs.com/posts/edit;postId=14928858

参考程序:http://www.nsfocus.net/index.php?act=magazine&do=view&mid=1797

设置包过滤参考:https://www.kernel.org/doc/Documentation/networking/filter.txt 

完整程序 ioctl.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <linux/filter.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    int sock, n;
    char buffer[2048];
    unsigned char *iphead, *ethhead;
    struct ifreq ethreq;

    //$tcpdump -i eth0 tcp src port 502 -dd  # 设置过滤 可以通过此命令获取c程序片段,复制到下面
    struct sock_filter BPF_code[] = {
        {0x28, 0, 0, 0x0000000c},
        {0x15, 0, 6, 0x000086dd},
        {0x30, 0, 0, 0x00000014},
        {0x15, 0, 15, 0x00000006},
        {0x28, 0, 0, 0x00000036},
        {0x15, 12, 0, 0x000001f6},
        {0x28, 0, 0, 0x00000038},
        {0x15, 10, 11, 0x000001f6},
        {0x15, 0, 10, 0x00000800},
        {0x30, 0, 0, 0x00000017},
        {0x15, 0, 8, 0x00000006},
        {0x28, 0, 0, 0x00000014},
        {0x45, 6, 0, 0x00001fff},
        {0xb1, 0, 0, 0x0000000e},
        {0x48, 0, 0, 0x0000000e},
        {0x15, 2, 0, 0x000001f6},
        {0x48, 0, 0, 0x00000010},
        {0x15, 0, 1, 0x000001f6},
        {0x6, 0, 0, 0x00040000},
        {0x6, 0, 0, 0x00000000}};
    struct sock_fprog Filter;

    Filter.len = sizeof(BPF_code) / sizeof(BPF_code[0]);
    Filter.filter = BPF_code;

    if ((sock = socket(PF_PACKET, SOCK_RAW,
                       htons(ETH_P_IP))) < 0)
    {
        perror("socket");
        exit(1);
    }

    /* Set the network card in promiscuos mode */
    strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);
    if (ioctl(sock, SIOCGIFFLAGS, &ethreq) == -1)
    {
        perror("ioctl");
        close(sock);
        exit(1);
    }
    ethreq.ifr_flags |= IFF_PROMISC;
    if (ioctl(sock, SIOCSIFFLAGS, &ethreq) == -1)
    {
        perror("ioctl");
        close(sock);
        exit(1);
    }

    /* Attach the filter to the socket */
    if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER,
                   &Filter, sizeof(Filter)) < 0)
    {
        perror("setsockopt");
        close(sock);
        exit(1);
    }

    while (1)
    {
        printf("----------\n");
        n = recvfrom(sock, buffer, 2048, 0, NULL, NULL);
        printf("%d bytes read\n", n);

        /* Check to see if the packet contains at least
     * complete Ethernet (14), IP (20) and TCP/UDP
     * (8) headers.
     */
        if (n < 42)
        {
            perror("recvfrom():");
            printf("Incomplete packet (errno is %d)\n",
                   errno);
            close(sock);
            exit(0);
        }

        ethhead = buffer;
        printf("Ethernet MAC: [%02X:%02X:%02X:%02X:%02X:%02X]", ethhead[0], ethhead[1], ethhead[2], ethhead[3], ethhead[4], ethhead[5]);
        printf("->[%02X:%02X:%02X:%02X:%02X:%02X]", ethhead[6], ethhead[7], ethhead[8], ethhead[9], ethhead[10], ethhead[11]);
        printf(" type[%04x]\n", (ntohs(ethhead[12] | ethhead[13] << 8)));

        iphead = buffer + 14; /* Skip Ethernet  header */
        if (*iphead == 0x45)
        { /* Double check for IPv4 * and no options present */
            printf("Layer-4 protocol %d\n", iphead[9]);
            printf("Version: %d HeaderLen: %d[%d] ", (*iphead >> 4), (*iphead & 0x0f), (*iphead & 0x0f) * 4);
            printf("TotalLen %d\n", (iphead[2] << 8 | iphead[3]));
            printf("IP [%d.%d.%d.%d:%d]", iphead[12], iphead[13], iphead[14], iphead[15], (iphead[20] << 8 | iphead[21]));
            printf("->[%d.%d.%d.%d:%d]\n", iphead[16], iphead[17], iphead[18], iphead[19], (iphead[22] << 8 | iphead[23]));
            for (int i = 0; i < n; ++i)
            {
                printf(" %02x", buffer[i] & 0xff);
                if ((i + 1) % 16 == 0)
                    printf("\n");
            }
            printf("\n");
        }
    }
}

 测试

如果在Android编译,需要安卓gcc,这个apk下载后使用压缩软件winrar打开,将gcc.zip复制出来解压到/data(似乎这里读写权限没有问题)目录下(我的目录是/data/ruphy)并设置环境变量:

export PATH=$PATH:/data/ruphy/gcc/bin:/data/ruphy/gcc/arm-linux-androideabi/bin:/data/ruphy/gcc/libexec

雷电模拟器开启终端,使用gcc编译ioctl.c为ioctl.o可执行文件并执行启动抓包

linux或者Android使用内核抓包c语言程序

 在Linux使用nc开启一个tcp服务,也可以不需要,因为模拟器可以上网,随便产生tcp连接即可

然后在模拟器使用telnet连接服务并通信

linux或者Android使用内核抓包c语言程序

 

linux或者Android使用内核抓包c语言程序

上一篇:java 笔记(4) —— java I/O 流、字节流、字符流


下一篇:街头摄影也要有演技 街拍陌生人不害羞祕笈图文详情介绍