zoukankan      html  css  js  c++  java
  • paper 78:sniff抓包程序片段

    #define INTERFACE "eth0"
    #define MAX_SIZE 65535

    int init_raw_socket();
    int open_promisc(char *interface, int sockfd);

    int main()
    {
        int sockfd;
        int bytes_recv;
        int addr_len;

        char recv_buff[MAX_SIZE];
        struct sockaddr_in from_addr;
        struct ip *ip;
        struct tcp *tcp;

        sockfd = init_raw_socket();
        open_promisc(INTERFACE, sockfd);

        addr_len = sizeof(from_addr);

        while (1)
        {
            bytes_recv = recvfrom(sockfd, recv_buff, MAX_SIZE - 1, 0,
                (struct sockaddr_in*)&from_addr, &addr_len));
            if (bytes_recv < 0)
            {
                perror("recvfrom error");
                exit(EXIT_FAILURE);
            }

            printf("receive %d bytes from %s ", bytes_recv, 
                inet_ntoa(from_addr.sin_addr));

            ip = (struct ip*)recv_buff;
            if (ip->ip_protocol == 6)
            {
                printf("IP header length ::: %d ",ip->ip_length);  
                printf("Protocol ::: %d ",ip->ip_protocol);  
                tcp = (struct tcp *)(buffer + (4*ip->ip_length));  
                printf("Source port ::: %d ",ntohs(tcp->tcp_source_port));  
                printf("Dest port ::: %d ",ntohs(tcp->tcp_dest_port));  
            }
        }
        return 0;
    }

    int init_raw_socket()
    {
        int sockfd;
        sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
        if (sockfd < 0)
        {
            perror("create socker error");
            exit(EXIT_FAILURE);
        }
        
        return sockfd;
    }

    int open_promisc(char *interface, int sockfd)
    {
        struct ifreq ifr;
        strncpy(ifr.ifr_name, interface, strlen(interface) + 1);
        if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) == -1)
        {
            perror("couldn't rettrive flags for the interface");
            exit(EXIT_FAILURE);
        }

        ifr.ifr_flags |= IFF_PROMISC;
        if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) == -1)
        {
            perror("couldn't set the promisc flags");
            exit(EXIT_FAILURE);
        }

        printf("set interface: %s to promisc ", interface);
        return 0;



    关于open_promisc打开网口混合模式
    #include <sys/ioctl.h> 
    #include <net/if.h>

    Linux 支持 一些 配置 网络设备 的 标准 ioctl. 他们 用于 任意的 套接字 描述符, 而 无须 了解 其 类型 或 系列. 他们 传递 一个 ifreq 结构:

    struct ifreq
    {
    char ifr_name[IFNAMSIZ]; /* Interface name */
    union {
    struct sockaddr ifr_addr;
    struct sockaddr ifr_dstaddr;
    struct sockaddr ifr_broadaddr;
    struct sockaddr ifr_netmask;
    struct sockaddr ifr_hwaddr;
    short ifr_flags;
    int ifr_ifindex;
    int ifr_metric;
    int ifr_mtu;
    struct ifmap ifr_map;
    char ifr_slave[IFNAMSIZ];
    char ifr_newname[IFNAMSIZ];
    char * ifr_data;
    };
    }

    struct ifconf
    {
    int ifc_len; /* size of buffer */
    union {
    char * ifc_buf; /* buffer address */
    struct ifreq *ifc_req; /* array of structures */
    };
    };

    一般说来, ioctl 通过 把 ifr_name 设置为 接口 的 名字 来 指定 将要 操作 的 设备. 结构的 其他成员 可以 分享 内存.

    如果 某个 ioctl 标记为 特权操作, 那么 操作时 需要 有效uid 为 0, 或者 拥有 CAP_NET_ADMIN 能力. 否则 将 返回 EPERM .

    SIOCGIFNAME
    给定 ifr_ifindex, 返回 ifr_name 中 的 接口名字. 这是 唯一 返回 ifr_name 内容 的 ioctl.
    SIOCGIFINDEX
    把 接口 的 索引 存入 ifr_ifindex.
    SIOCGIFFLAGSSIOCSIFFLAGS
    读取 或 设置 设备的 活动标志字. ifr_flags 包含 下列值 的 屏蔽位:
    设备标志
    IFF_UP 接口正在运行.
    IFF_BROADCAST 有效的广播地址集.
    IFF_DEBUG 内部调试标志.
    IFF_LOOPBACK 这是自环接口.
    IFF_POINTOPOINT 这是点到点的链路接口.
    IFF_RUNNING 资源已分配.
    IFF_NOARP 无arp协议, 没有设置第二层目的地址.
    IFF_PROMISC 接口为杂凑(promiscuous)模式.
    IFF_NOTRAILERS 避免使用trailer .
    IFF_ALLMULTI 接收所有组播(multicast)报文.
    IFF_MASTER 主负载平衡群(bundle).
    IFF_SLAVE 从负载平衡群(bundle).
    IFF_MULTICAST 支持组播(multicast).
    IFF_PORTSEL 可以通过ifmap选择介质(media)类型.
    IFF_AUTOMEDIA 自动选择介质.
    IFF_DYNAMIC 接口关闭时丢弃地址.

    设置 活动标志字 是 特权操作, 但是 任何进程 都可以 读取 标志字.

    SIOCGIFMETRICSIOCSIFMETRIC
    使用 ifr_metric 读取 或 设置 设备的 metric 值. 该功能 目前 还没有 实现. 读取操作 使 ifr_metric 置 0, 而 设置操作 则 返回 EOPNOTSUPP.
    SIOCGIFMTUSIOCSIFMTU
    使用 ifr_mtu 读取 或 设置 设备的 MTU(最大传输单元). 设置 MTU 是 特权操作. 过小的 MTU 可能 导致 内核 崩溃.
    SIOCGIFHWADDRSIOCSIFHWADDR
    使用 ifr_hwaddr 读取 或 设置 设备的 硬件地址. 设置 硬件地址 是 特权操作.
    SIOCSIFHWBROADCAST
    使用 ifr_hwaddr 读取 或 设置 设备的 硬件广播地址. 这是个 特权操作.
    SIOCGIFMAPSIOCSIFMAP
    使用 ifr_map 读取 或 设置 接口的 硬件参数. 设置 这个参数 是 特权操作.
    struct ifmap 
    {
    unsigned long mem_start;
    unsigned long mem_end;
    unsigned short base_addr;
    unsigned char irq;
    unsigned char dma;
    unsigned char port;
    };

    对 ifmap 结构 的 解释 取决于 设备驱动程序 和 体系结构.

    SIOCADDMULTISIOCDELMULTI
    使用 ifr_hwaddr 在 设备的 链路层 组播过滤器 (multicase filter) 中 添加 或 删除 地址. 这些是 特权操作. 
    SIOCGIFTXQLENSIOCSIFTXQLEN
    使用 ifr_qlen 读取 或 设置 设备的 传输队列长度. 设置 传输队列长度 是 特权操作.
    SIOCSIFNAME
    把 ifr_ifindex 中 指定的 接口名字 改成 ifr_newname. 这是个 特权操作.
    SIOCGIFCONF
    返回 接口地址(传输层) 列表. 出于 兼容性, 目前 只代表 AF_INET 地址. 用户 传送 一个 ifconf 结构 作为 ioctl 的 参数. 其中 ifc_req 包含 一个 指针 指向 ifreq 结构数组, 他的 长度 以字节 为单位 存放在 ifc_len 中. 内核 用 所有 当前的 L3(第三层?) 接口地址 填充 ifreqs, 这些 接口 正在 运行: ifr_name 存放 接口名字 (eth0:1等), ifr_addr 存放 地址. 内核 在 ifc_len 中 返回 实际长度; 如果 他 等于 初始长度, 表示 溢出了, 用户 应该 换一个 大些的 缓冲区 重试 一下. 没有 发生 错误时 ioctl 返回 0, 否则 返回 -1, 溢出 不算 错误.


    相关结构体:
    /*structure of an ip header*/    
    struct ip {      
    unsigned int ip_length:4; /*little-endian*/    
    unsigned int ip_version:4;   
    unsigned char ip_tos;    
    unsigned short ip_total_length;     
    unsigned short ip_id;     
    unsigned short ip_flags;   
    unsigned char ip_ttl;   
    unsigned char ip_protocol;   
    unsigned short ip_cksum;   
    unsigned int ip_source; unsigned int ip_dest;     
    };   
         
    /* Structure of a TCP header */   
    struct tcp {   
    unsigned short tcp_source_port;   
    unsigned short tcp_dest_port;   
    unsigned int tcp_seqno;     
    unsigned int tcp_ackno;   
    unsigned int tcp_res1:4, /*little-endian*/   
    tcp_hlen:4,   
    tcp_fin:1,   
    tcp_syn:1,   
    tcp_rst:1,   
    tcp_psh:1,   
    tcp_ack:1,   
    tcp_urg:1,   
    tcp_res2:2;   
    unsigned short tcp_winsize;   
    unsigned short tcp_cksum;   
    unsigned short tcp_urgent;   
    };   
    /*********************EOF***********************************/  

  • 相关阅读:
    推送
    XPath
    XML
    在xcode 6.4 环境下写的demo 在xode7 环境下 网络请求有问题
    SVN 搭建
    翻译
    iOS面试题积累
    安卓扁平化之路专题(三)Android 5.0新特性
    Android @SuppressLint @TargetApi 总结
    Android_support_v4,Android_support_v7,Android_support_v13区别
  • 原文地址:https://www.cnblogs.com/molakejin/p/5617854.html
Copyright © 2011-2022 走看看