文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>闲着没事写了个嗅探器

闲着没事写了个嗅探器

时间:2009-08-16  来源:famdestiny

这两天闲着没事,练练手,没什么技术含量,大部分时间花在折腾输出逻辑上了,汗!涉及到的一些细节包括:
  • 数据链路层的访问
  • 将网卡设置为混杂模式
  • 以太网桢头,IP头,TCP/UDP头的部分内容
  • getopt_long的使用方法

程序只输出了部分必要的信息,具体的信息可以根据自己的需要进行修改。

使用方法:

NAME

rawsocket - A simple sniffer

SYNOPSIS

rawsocket [-i] [-r] [-a] [-g] [-c] [-v] [-t [port]] [-u [port]] [-p ifname]

DESCRIPTION

I am not good in english. rawsocket is sniffer than can sniff most pakage on local network. it also has the capacity of setting the NIC(network interface card) to promiscuous mode. etc.

OPTIONS

-i, --ip

monitor IP pakage.

-r, --rarp

monitor RARP pakage.

-a, --arp

monotor ARP pakage.

-g, --igmp

monotor IGMP pakage.

-c, --icmp

monitor ICMP pakage.

-v, --version

print version

-t[port], --tcp=[port]

monitor tcp port port.

-u[port], --udp=[port]

monitor udp port port.

-pifname, --promisc=ifname

set the NIC ifname to promiscuous mode.

AUTHORS

famdestiny

author

NOTES

None

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>            //for htons
#include <linux/if_ether.h>        //for ETH_P_ARP ETH_P_IP ...
#include <sys/ioctl.h>
#include <linux/if.h>            //for IFF_PROMISC
#include <getopt.h>                //for getopt_long
#define _GUN_SOURCE                //for getopt_long


#define OUTPUT_ETH_NONE        0x0000
#define OUTPUT_ETH_IP        0x0001
#define OUTPUT_ETH_ARP        0x0002
#define OUTPUT_ETH_RARP        0x0004
#define OUTPUT_IP_ICMP        0x0008
#define OUTPUT_IP_IGMP        0x0010
#define OUTPUT_IP_TCP        0x0020
#define OUTPUT_IP_UDP         0x0040
#define OUTPUT_ETH_ALL        0xFFFF

#define IP_P_NONE    0x00
#define IP_P_ICMP    0x01
#define IP_P_IGMP    0x02
#define IP_P_TCP    0x06
#define IP_P_UDP    0x11

#define BUF_LEN 1516

//#define NEW_PF_PACKET

#define OLD_SOCK_PACKET

void output_pkg(ssize_t n, unsigned char *buf, unsigned short int eth_type, unsigned char ip_type)
{
    unsigned short int src_port;
    unsigned short int dst_port;
    char src_ip_addr[16] = {0};
    char dst_ip_addr[16] = {0};
    printf("%d\t%02x:%02x:%02x:%02x:%02x:%02x > %02x:%02x:%02x:%02x:%02x:%02x\t0x%04x\t", n,
            buf[6]&0xFF, buf[7]&0xFF, buf[8]&0xFF, buf[9]&0xFF, buf[10]&0xFF, buf[11]&0xFF,
            buf[0]&0xFF, buf[1]&0xFF, buf[2]&0xFF, buf[3]&0xFF, buf[4]&0xFF, buf[5]&0xFF,
            eth_type);
    if(eth_type == ETH_P_ARP)
    {
        printf("\n");
    }
    else if(eth_type == ETH_P_RARP)
    {
        printf("\n");
    }
    else if(eth_type == ETH_P_IP)
    {
        if(ip_type == IP_P_ICMP)
        {
            strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26])))));
            strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30])))));
            printf("0x%02x\t%s > %s\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr);
        }
        else if(ip_type == IP_P_IGMP)
        {
            strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26])))));
            strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30])))));
            printf("0x%02x\t%s > %s\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr);
        }
        else if(ip_type == IP_P_TCP)
        {
            strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26])))));
            strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30])))));
            src_port = ntohs(*((unsigned short int *)(buf+34)));
            dst_port = ntohs(*((unsigned short int *)(buf+36)));
            printf("0x%02x\t%s > %s\t%d>%d\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr, src_port, dst_port);
        }
        else if(ip_type == IP_P_UDP)
        {
            strcpy(src_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[26])))));
            strcpy(dst_ip_addr, inet_ntoa(*((struct in_addr *)(&(buf[30])))));
            src_port = ntohs(*((unsigned short int *)(buf+34)));
            dst_port = ntohs(*((unsigned short int *)(buf+36)));
            printf("0x%02x\t%s > %s\t%d>%d\t", ip_type & 0xFF, src_ip_addr, dst_ip_addr, src_port, dst_port);
        }
        else
        {
            printf("0x%02x\t", ip_type & 0xFF);
        }
        printf("\n");
    }
    else
    {
        printf("\n");
    }
}

#ifdef NEW_PF_PACKET
int set_promisc_mode(int fd, char *ifname)
{
    struct ifreq req;
    struct packet_mreq mreq;

    bzero(&req, sizeof(req));
    bzero(&mreq, sizeof(mreq));

    strcpy(req.ifr_name, ifname);
    if(ioctl(fd, SIOCGIFINDEX, &req) == -1)
    {
        return -1;
    }

    mreq.mr_ifindex = req.ifr_ifindex;
    mreq.mr_type = PACKET_MR_PROMISC;
    if(setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1)
    {
        return -1;
    }

    return 0;
}
#endif

#ifdef OLD_SOCK_PACKET
int set_promisc_mode(int fd, char *ifname)
{
    struct ifreq req;

    strcpy(req.ifr_name, ifname);
    if(ioctl(fd, SIOCGIFFLAGS, &req) == -1)
    {
        return -1;
    }
    req.ifr_flags |= IFF_PROMISC;
    if(ioctl(fd, SIOCSIFFLAGS, &req) == -1)
    {
        return -1;
    }
    return 0;
}
#endif

/*****************************************************
 *options:
 *    i:ip, a:arp, r:rarp, g: igmp, c:icmp, t:tcp, u:udp
 *
 *
 * **************************************************/

int main(int argc, char **argv)
{
    int fd, opt, opt_promisc = 0;
    char *if_name = "eth0";
    ssize_t n;
    unsigned short int pkg_to_output = OUTPUT_ETH_NONE;
    unsigned short int eth_pkg_type = 0x0000;
    unsigned short int src_port = 0;
    unsigned short int dst_port = 0;
    unsigned short int monitor_port = 0;
    unsigned char ip_pkg_type = 0x00;
    unsigned char buf[BUF_LEN] = {0};

    int optidx;
    static struct option long_options[] = {
        {"ip", 0, 0, 'i'},
        {"arp", 0, 0, 'a'},
        {"rarp", 0, 0, 'r'},
        {"icmp", 0, 0, 'c'},
        {"igmp", 0, 0, 'g'},
        {"tcp", 2, 0, 't'},
        {"udp", 2, 0, 'u'},
        {"version", 0, 0, 'v'},
        {"promisc", 1, 0, 'p'},
        {0, 0, 0, 0},
    };
    while((opt = getopt_long(argc, argv, "iargct::u::p:v", long_options, &optidx)) != -1)
    {
        switch(opt)
        {
            case 'i':
            {
                pkg_to_output |= OUTPUT_ETH_IP;
                break;
            }
            case 'a':
            {
                pkg_to_output |= OUTPUT_ETH_ARP;
                break;
            }
            case 'r':
            {
                pkg_to_output |= OUTPUT_ETH_RARP;
                break;
            }
            case 'g':
            {
                pkg_to_output |= OUTPUT_ETH_IP;
                pkg_to_output |= OUTPUT_IP_IGMP;
                break;
            }
            case 'c':
            {
                pkg_to_output |= OUTPUT_ETH_IP;
                pkg_to_output |= OUTPUT_IP_ICMP;
                break;
            }
            case 't':
            {
                pkg_to_output |= OUTPUT_ETH_IP;
                pkg_to_output |= OUTPUT_IP_TCP;
                if(optarg != NULL)
                {
                    monitor_port = (unsigned short int)atoi(optarg);
                }
                break;
            }
            case 'u':
            {
                pkg_to_output |= OUTPUT_ETH_IP;
                pkg_to_output |= OUTPUT_IP_UDP;
                if(optarg != NULL)
                {
                    monitor_port = (unsigned short int)atoi(optarg);
                }break;
            }
            case 'v':
            {
                printf("version 1.0\n");
                exit(0);
            }
            case 'p':
            {
                opt_promisc = 1;
                if_name = optarg;
                break;
            }
            default:
            {
                printf("useage: rawsocket [-i] [-r] [-a] [-g] [-c] [-v] [-t [port]] [-u [port]] [-p ifname]\n");
                return 0;
            }
        }
    }

    if (pkg_to_output == OUTPUT_ETH_NONE)
    {
        pkg_to_output = OUTPUT_ETH_ALL;
    }
    /***************************************
     *Argument 2:
     *    SOCK_RAW: The packet includes the link layer header.
     *    SOCK_DGRAM: The packet don`t includes the link layer header.
     *Argument 3:
     *    ETH_P_IP(0x0800):    ip
     *    ETH_P_RARP(0x0806):    arp
     *    ETH_P_ARP(0x8035):    rarp
     * *************************************/
    if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
    {
        printf("create socket failed: %s\n", strerror(errno));
        return 0;
    }

    if(opt_promisc == 1)
    {
        if(set_promisc_mode(fd, if_name) == -1)
        {
            printf("set promisc mode failed!\n");
            exit(0);
        }
    }

    while(1)
    {
        if((n = read(fd, buf, BUF_LEN)) == -1)
        {
            if(errno == EINTR)
            {
                continue;
            }
            else
            {
                printf("read error: %s\n", strerror(errno));
                exit(0);
            }
        }

        eth_pkg_type = ntohs((*(unsigned short int *)(buf+12)))&0xFFFF;
        if((eth_pkg_type == ETH_P_ARP) && (pkg_to_output & OUTPUT_ETH_ARP))    //ARP:0x0806

        {
            output_pkg(n, buf, eth_pkg_type, IP_P_NONE);
        }
        else if((eth_pkg_type == ETH_P_RARP) && (pkg_to_output & OUTPUT_ETH_RARP))    //RARP:0x8035

        {
            output_pkg(n, buf, eth_pkg_type, IP_P_NONE);
        }
        else if((eth_pkg_type == ETH_P_IP) && (pkg_to_output & OUTPUT_ETH_IP))    //IP:0x0800

        {
            ip_pkg_type = buf[23];
            if(((pkg_to_output & OUTPUT_IP_ICMP) && ip_pkg_type == IP_P_ICMP) ||    //ICMP:0x01

                ((pkg_to_output & OUTPUT_IP_IGMP) && ip_pkg_type == IP_P_IGMP))    //IGMP:0x02

            {
                output_pkg(n, buf, eth_pkg_type, ip_pkg_type);
            }
            else if((pkg_to_output & OUTPUT_IP_TCP) && ip_pkg_type == IP_P_TCP)        //TCP:0x06

            {
                src_port = ntohs(*((unsigned short int *)(buf+34)));
                dst_port = ntohs(*((unsigned short int *)(buf+36)));
                
                if(monitor_port == dst_port || monitor_port == 0)
                {
                    output_pkg(n, buf, eth_pkg_type, ip_pkg_type);
                }
            }
            else if((pkg_to_output & OUTPUT_IP_UDP) && ip_pkg_type == IP_P_UDP)        //UDP:0x11    

            {
                src_port = ntohs(*((unsigned short int *)(buf+34)));
                dst_port = ntohs(*((unsigned short int *)(buf+36)));
                
                if(monitor_port == dst_port || monitor_port == 0)
                {
                    output_pkg(n, buf, eth_pkg_type, ip_pkg_type);
                }
            }
            else    //unknown ip pakage

            {
                if((pkg_to_output == OUTPUT_ETH_ALL) || (pkg_to_output == OUTPUT_ETH_IP))
                {
                    output_pkg(n, buf, eth_pkg_type, ip_pkg_type);
                }
            }
        }
        else    //unknown eth pakage

        {
            if(pkg_to_output == OUTPUT_ETH_ALL)
            {
                output_pkg(n, buf, eth_pkg_type, IP_P_NONE);
            }
        }
    }
}

相关阅读 更多 +
排行榜 更多 +
勇敢的哈克中文版

勇敢的哈克中文版

飞行射击 下载
狙击突袭特种行动手机版

狙击突袭特种行动手机版

飞行射击 下载
射箭小子

射箭小子

飞行射击 下载