Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3929259
  • 博文数量: 93
  • 博客积分: 3189
  • 博客等级: 中校
  • 技术积分: 4229
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-02 13:29
个人简介

出没于杭州和青岛的程序猿一枚,对内核略懂一二

文章分类

全部博文(93)

文章存档

2016年(2)

2015年(3)

2014年(11)

2013年(29)

2012年(16)

2011年(5)

2010年(5)

2009年(22)

分类: C/C++

2009-02-05 08:59:16

先说一下我的思想,由于大部分主机都是禁止ping的,而netbios不能探测linux,所以这里探测活动主机使用arp协议。
首选使用libnet在指定的网段发送arp请求包,于此同时(多进程),使用libpcap捕捉arp应答包。从而分析出这个网段的活动主机ip和mac.

#include <libnet.h>
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/ioctl.h>
#define CAP_LEN 2048
FILE *fp;
static int ipnumber=0;
pcap_t *pd;
void catch(void)
{
    pcap_close(pd);
    printf("Total ip number is %d\n",ipnumber);
    if(fp!=stdout&&fp!=stderr&&fp) fclose(fp);
    exit(0);
}

void deal(u_char *user,const struct pcap_pkthdr *h,const u_char *sp)
{
    struct in_addr *ip;
    if(*(sp+21)!=2) return;
    ip=(struct in_addr *)(sp+28);
    fprintf(fp,"%-15s ",inet_ntoa(*ip));
    fprintf(fp,"%02x:%02x:%02x:%02x:%02x:%02x\n",*(sp+22),*(sp+23),*(sp+24),*(sp+25),*(sp+26),*(sp+27));
    ++ipnumber;
}
pcap_handler printer=deal;

void deal_arp()
{
    bpf_u_int32 localnet,netmask;
    struct bpf_program fcode;
    pcap_dumper_t *p;
    char ebuf[PCAP_ERRBUF_SIZE];
    char *device;
    u_char *pcap_userdata;
    int dev_flag=1;
    int cap_len=CAP_LEN;
    char *str="arp";
    int i;
    device=pcap_lookupdev(ebuf);
    if(device==NULL) exit(printf("device is null%s\n",ebuf));
    #ifdef _DEBUG_
        printf("device is %s\n",device);
    #endif
    pd=pcap_open_live(device,cap_len,dev_flag,1000,ebuf);
    if(pd==NULL) exit(printf("%s\n",ebuf));
    i=pcap_snapshot(pd);
    if(cap_len<i)
    {
        cap_len=i;
        printf("snaplen raised from %d to %d\n",cap_len,i);
    }
    if(pcap_lookupnet(device,&localnet,&netmask,ebuf)<0)
    {
        localnet=0;
        netmask=0;
        printf("%s\n",ebuf);
    }
    #ifdef _DEBUG_
        printf("localnet %u\n",(u_int)localnet);
        printf("netmask %u\n",(u_int)netmask);
    #endif
    if(pcap_compile(pd,&fcode,str,1,netmask)<0) exit(printf("Error %s\n","pcap_compile"));
    if(pcap_setfilter(pd,&fcode)<0) exit(printf("Error %s\n","pcap_setfilter"));
    if(pcap_loop(pd,-1,printer,pcap_userdata)<0) exit(printf("Error %s\n","pcap_loop"));
}
void open_file(char *filename)
{
    if(!strcmp(filename,"stdout")) fp=stdout;
    else if(!strcmp(filename,"stderr")) fp=stderr;
    else
    {
        file_exist(filename);
        fp=fopen(filename,"w");
    }
}

void help()
{
    printf("Usage:\n\thostscan -r [-i] [-f]\n\t-r 192.168.0.0/24 scan which network \n\t-i eth0 using which interface,default eth0 or ppp0.\n\t-f filename save the result to file\nExample:\nhostscan -r 192.168.0.0/24\n");
    printf("**ltw.tony\n");
    exit(0);
}

int main(int argc,char **argv)
{
    const char *options="r:hi:f:";
    const struct option long_options[]={
        {"network",1,NULL,'r'},
        {"interface",1,NULL,'i'},
        {"file",1,NULL,'f'},
        {"help",0,NULL,'h'},
        {NULL,0,NULL,0}
    };
    u_long dst_ip=0,src_ip=0;
    libnet_t *l;
    libnet_ptag_t t;
    struct in_addr ip;
    char *ip_mask,*mask;
    uint32_t min;
    uint32_t max;
    uint32_t m;
    int excursion;
    unsigned int j=1;
    const char *delim="/";
    u_char enet_src[6]={0x00,0x0c,0x29,0xa0,0x1a,0x9b};
    u_char enet_dst[6]={0xff,0xff,0xff,0xff,0xff,0xff};
    //u_char ip_dst[4]={0xc0,0xa8,0x00,0x01};

    u_long i;
    char *device=NULL;
    struct libnet_ether_addr *e;
    char *network=NULL;
    char errbuf[LIBNET_ERRBUF_SIZE];
    memset(errbuf,0,LIBNET_ERRBUF_SIZE);
    char op;
    char *filename=NULL;
    int k=0;
    fp=stdout;
    while((op=getopt_long(argc,argv,options,long_options,NULL))!=-1)
    {
        switch(op)
        {
            case 'r':
                network=strdup(optarg);
                break;
            case 'i':
                device=strdup(optarg);
                break;
            case 'h':
                help();
                break;
            case 'f':
                filename=strdup(optarg);
                open_file(filename);
                break;
            default:
                help();
                break;
        }
    }
    if(network==NULL) help();
    ip_mask=strtok(network,delim);
    mask=strtok(NULL,delim);
    excursion=32-atoi(mask);
    max=min=inet_network(ip_mask);
    min>>=excursion;
    min<<=excursion;
    while(excursion--)
    {
        max|=j;
        j<<=1;
    }
    //printf("%08x\n",min);

    //printf("%08x\n",max);

    //inet_aton(ip_mask,&ip);

    if(fork()==0)
    {
        signal(SIGALRM,(void *)catch);
        alarm(3);
        deal_arp();
    }
    else
    {
        sleep(1);
        l=libnet_init(LIBNET_LINK_ADV,device,errbuf);
        if(l==NULL)
        {
            fprintf(stderr,"libnet_init() failed %s\n",errbuf);
            exit(0);
        }
        i=libnet_get_ipaddr4(l);
        e=libnet_get_hwaddr(l);
        while(min<max)
        {
            //t=libnet_build_arp(ARPHRD_ETHER,ETHERTYPE_IP,6,4,ARPOP_REQUEST,enet_src,    (u_int32_t*)&i,enet_dst,ip_dst,NULL,0,l,0);

            m=htonl(min);
            ip=*(struct in_addr*)&m;
            t=libnet_build_arp(ARPHRD_ETHER,ETHERTYPE_IP,6,4,ARPOP_REQUEST,e->ether_addr_octet,(u_int8_t*)&i,enet_dst,(u_int8_t*)&ip,NULL,0,l,0);
            t=libnet_autobuild_ethernet(enet_dst,ETHERTYPE_ARP,l);
            libnet_write(l);
            ++min;
            libnet_clear_packet(l);
        }
        libnet_destroy(l);
        if(network) free(network);
        if(device) free(device);
        if(filename) free(filename);
        wait();
    }
}

 

转载时请注明出处(pengliang.cublog.cn),谢谢。

阅读(5221) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~