Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31558
  • 博文数量: 14
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 155
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-07 10:01
文章分类
文章存档

2009年(14)

我的朋友

分类: LINUX

2009-10-07 11:10:52

网卡混杂模式探测小程序
sniffscan [-s]
-s 为探测网段中的存活主机
不加参数为探测网络中混杂模式的网卡
 
 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <net/ethernet.h>

#define MAXINTERFACES 16

int getpacket(int fd);

int sendpacket(int fd, char *mac, unsigned int network, unsigned ipaddr, unsigned int range);

struct arpheader
  {
    unsigned short int ar_hrd; /* Format of hardware address. */
    unsigned short int ar_pro; /* Format of protocol address. */
    unsigned char ar_hln; /* Length of hardware address. */
    unsigned char ar_pln; /* Length of protocol address. */
    unsigned short int ar_op; /* ARP opcode (command). */

    unsigned char __ar_sha[6]; /* Sender hardware address. */
    unsigned char __ar_sip[4]; /* Sender IP address. */
    unsigned char __ar_tha[6]; /* Target hardware address. */
    unsigned char __ar_tip[4]; /* Target IP address. */
  };

int flag = 0;
int main(int argc, char *argv[]){
        int fd;
        int intnum, i, j;
        int pid;
        struct ifconf ifc;
        struct ifreq buf[MAXINTERFACES];
        struct in_addr ipaddr, netmask;
        unsigned int network, range;
        char mac[6];
        int stat;
     
    if((argc == 2)&&(strcmp(argv[1], "-s") == 0)){
        flag = 1;
    }

        if((fd = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP))) == -1){
                fprintf(stderr, "socket init failed: %s \n", strerror(errno));
                exit(1);
        }
        ifc.ifc_len = sizeof(buf);
        ifc.ifc_buf = (caddr_t)buf;
        if(ioctl (fd, SIOCGIFCONF, (char *) &ifc) == -1){
                fprintf(stderr, "ioctl ifconf failed: %s \n", strerror(errno));
                exit(1);
        }
        intnum = ifc.ifc_len / sizeof (struct ifreq);
        //printf("interface num is intrface=%d\n\n\n",intrface);

        i = 0;
        fprintf(stdout, "select follow net device:\n");
        while(i < intnum){
                fprintf (stdout, "%d. net device %s: ", i+1, buf[i].ifr_name);
                if(ioctl(fd, SIOCGIFADDR, (char *) &buf[i]) == -1){
                        fprintf(stderr, "ioctl ifaddr failed: %s \n", strerror(errno));
                        exit(1);
                }
                fprintf(stdout, "%s\n", (char*)inet_ntoa(((struct sockaddr_in*)(&buf[i].ifr_addr))->sin_addr));
                i++;
        }
        fprintf(stdout, "please select one net device[1-%d]:", intnum);
        fscanf(stdin, "%d", &j);
         
        if(ioctl(fd, SIOCGIFADDR, (char *) &buf[j-1]) == -1){
                        fprintf(stderr, "ioctl ifaddr failed: %s \n", strerror(errno));
                        exit(1);
        }
        memcpy(&ipaddr, &(((struct sockaddr_in*)(&buf[j-1].ifr_addr))->sin_addr), sizeof(struct in_addr));
        if(ioctl(fd, SIOCGIFNETMASK, (char *) &buf[j-1]) == -1){
                        fprintf(stderr, "ioctl ifaddr failed: %s \n", strerror(errno));
                        exit(1);
        }
        memcpy(&netmask, &(((struct sockaddr_in*)(&buf[j-1].ifr_addr))->sin_addr), sizeof(struct in_addr));
        if (ioctl (fd, SIOCGIFHWADDR, (char *) &buf[j-1]) == -1){
        fprintf(stderr, "ioctl hwaddr failed: %s \n", strerror(errno));
        exit(1);
        }
        memcpy(mac, buf[j-1].ifr_hwaddr.sa_data, 6);
         
        network = (ntohl(ipaddr.s_addr) & ntohl(netmask.s_addr));
        range = ~ntohl(netmask.s_addr);
         
        pid = fork();
    if(pid == 0){
        getpacket(fd);
    }else{
        sendpacket(fd, mac, network, ipaddr.s_addr, range);
         
    }
        wait(&stat);
         
         
        return 0;


}


int getpacket(int fd){
    struct sockaddr addr;
    char buffer[1500];
    int recv_byte, len;
    struct ether_header eth_hdr;
    struct arpheader arp_hdr;
    bzero(&addr, sizeof(addr));
    len = sizeof(addr);
    struct in_addr ipaddr;
    fd_set fds;
    struct timeval timeout;
     
    FD_ZERO(&fds);
        FD_SET(fd, &fds);
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
    while(1){
        select(fd+1, &fds, NULL, NULL, &timeout);
                if(FD_ISSET(fd, &fds)){
            if((recv_byte = recvfrom(fd, buffer, 1500, 0, &addr, (socklen_t*)&len)) == -1){
                fprintf(stderr, "recvfrom failed: %s \n", strerror(errno));
                exit(1);
            }
            memcpy(e_hdr, buffer, sizeof(eth_hdr));
            memcpy(&arp_hdr, buffer+sizeof(eth_hdr), sizeof(arp_hdr));
            if(arp_hdr.ar_op == ntohs(2)){
                memcpy(&ipaddr, arp_hdr.__ar_sip, 4);
                if(flag){
                    fprintf(stdout, "%s, host on line\n", (char*)inet_ntoa(ipaddr));
                }else{
                    fprintf(stdout, "%s, network device may be set promisc\n", (char*)inet_ntoa(ipaddr));
                }
            }
        }else{
            break;
        }
    }
    close(fd);
    return 0;
}

int sendpacket(int fd, char *mac, unsigned int network, unsigned ipaddr, unsigned int range){
    struct ether_header eth_hdr;
    struct arpheader arp_hdr;
    int i;
    struct sockaddr addr;
    char buffer[255];
    int ip;
     
    if(flag){
        memcpy(e_hdr.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6);
    }else{
        memcpy(e_hdr.ether_dhost, "\xff\xff\xff\xff\xff\xfe", 6);
        //memcpy(e_hdr.ether_dhost, "\x01\x00\x5e\x00\x00\x01", 6);

    }
    memcpy(e_hdr.ether_shost, mac, 6);
    eth_hdr.ether_type = htons(ETHERTYPE_ARP);
     
    arp_hdr.ar_hrd = htons(1);
    arp_hdr.ar_pro = htons(0x0800);
    arp_hdr.ar_hln = 6;
    arp_hdr.ar_pln = 4;
    arp_hdr.ar_op = htons(1);
    memcpy(arp_hdr.__ar_sha, mac, 6);
    memcpy(arp_hdr.__ar_sip, &ipaddr, 4);
    memset(arp_hdr.__ar_tha, 0, 6);
    bzero(&addr, sizeof(addr));
    strcpy(addr.sa_data, "eth0" );
    i = 1;
    while(i < range){
        ip = htonl(network + i);
        memcpy(arp_hdr.__ar_tip, &ip, 4);
        memcpy(buffer, e_hdr, sizeof(eth_hdr));
        memcpy(buffer+sizeof(eth_hdr), &arp_hdr, sizeof(arp_hdr));
        if(sendto(fd, buffer, sizeof(eth_hdr)+sizeof(arp_hdr), 0, (struct sockaddr*)&addr, sizeof(addr)) == -1){
            fprintf(stderr, "sendto failed: %s, \n", strerror(errno));
            exit(1);
        }
        i++;
        usleep(1000);
    }
    close(fd);
    return 0;
  
}


阅读(957) | 评论(0) | 转发(0) |
0

上一篇:简单的Linux防火墙

下一篇:简单的内核shell

给主人留下些什么吧!~~