荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: gon.bbs@bbs.cqupt.edu.cn (人浮于世), 信区: Linux
标  题: 贴一个通过arp广播抢ip的程序
发信站: 幽幽黄桷兰 (Fri May  2 19:10:03 2003)
转信站: SZU!news.tiaozhan.com!news.happynet.org!CQUPT

/send an arp broadcast
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <string.h>
#include <errno.h>
#define LINELENGTH 32
#define ETH_HW_ADDR_LEN 6
#define IP_ADDR_LEN 4
#define DEV_LEN 10
struct arp_packet
{
    u_char  targ_hw_addr[ETH_HW_ADDR_LEN];
    u_char  src_hw_addr[ETH_HW_ADDR_LEN];
    u_short frame_type;
    u_short hw_type;
    u_short prot_type;
    u_char  hw_addr_size;
    u_char  prot_addr_size;
    u_short op;
    u_char  sndr_hw_addr[ETH_HW_ADDR_LEN];
    u_char  sndr_ip_addr[IP_ADDR_LEN];
    u_char  rcpt_hw_addr[ETH_HW_ADDR_LEN];
    u_char  rcpt_ip_addr[IP_ADDR_LEN];
    u_char  padding[18]; //'cos the minimum ether packet length is 60 bytes.

};
struct ifconf ifc;
int GetIfconf();
int send_arp (unsigned char*, unsigned char*, char*);
int main()
{
    struct ifreq *ifr;
    int sockfd, flags;
    void *ptr;
    char *pdev;
    char dev[DEV_LEN], temp[16];
    unsigned char mac[ETH_HW_ADDR_LEN], ip[IP_ADDR_LEN];
    if(GetIfconf() == -1)
    //Warning: the result between kernel 2.0 and 2.2 is not the same!!!
    //In kernel 2.0, it doesn't display the netcard name whose status
    //is down.
        return -1;
    if((sockfd=socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        free(ifc.ifc_buf);
        ifc.ifc_req = NULL;
        return -1;
    }
    for(ptr=ifc.ifc_buf; (caddr_t)ptr < ifc.ifc_buf+ifc.ifc_len; ){
        ifr=(struct ifreq *)ptr;
            //for the next one in buffer
        ptr += sizeof(ifr->ifr_name)+sizeof(struct sockaddr);
        strncpy(dev, ifr->ifr_name, DEV_LEN-1);
        if(strcmp(dev, "lo") == 0)  //loopback device
            continue;
        else if((pdev = strchr(dev, ':')) != NULL)
            //virtual device
            *pdev = 0;
        //get the ip address
        if(ioctl(sockfd, SIOCGIFADDR, ifr) == -1) {
            free(ifc.ifc_buf);
            ifc.ifc_req = NULL;
            close(sockfd);
            return -1;
        }
        memcpy(ip, (void *)&((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr
.s_a
dd
r, sizeof(ip));
        //get the hardware address
        if(ioctl(sockfd, SIOCGIFHWADDR, ifr) == -1) {
            free(ifc.ifc_buf);
            ifc.ifc_req = NULL;
            close(sockfd);
            return -1;
        }
        memcpy(mac, ifr->ifr_hwaddr.sa_data, ETH_HW_ADDR_LEN);
        printf("%s ", dev);
        inet_ntop(AF_INET, ip, temp, sizeof(temp));
        printf("%s ", temp);
        printf("%x:%x:%x:%x:%x:%x\n", *mac, *(mac+1), *(mac+2), *(mac+3), *(
mac+
4)
, *(mac+5));
        //send arp broadcast
        if(send_arp(ip, mac, dev) == -1) {
            printf("send arp broadcast fail in dev: %s\n", dev);
        } else {
            printf("send arp broadcast success in dev: %s\n", dev);
        }
    }  //end for of struct ifreq
    free(ifc.ifc_buf);
    ifc.ifc_req = NULL;
    close(sockfd);
    return 0;
}
//get the value of struct ifconf ifc
//global variable: struct ifconf ifc
int GetIfconf()
{
    int sockfd;
    int len, lastlen;
    void *buf;
    if((sockfd=socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        return -1;
    lastlen=0;
    len=10*sizeof(struct ifconf);
    //size of struct ifconf: 8
    //size of struct ifreq: 32
    for(;;){
        buf=malloc(len);
        ifc.ifc_len=len;
        ifc.ifc_buf=buf;
        if(ioctl(sockfd, SIOCGIFCONF, &ifc) <0) {
            free(buf);
            return -1;
        }
        else{
            if(ifc.ifc_len == lastlen)
                break;  //success, the only point to exit for()
            lastlen=ifc.ifc_len;
        }
        len += 10*sizeof(struct ifconf);
        free(buf);
    }
    return 0;
}
//Arp reply to a broadcast MAC address, the target ip address is the same
//with source address. :)
int send_arp (unsigned char *sip, unsigned char *shwa, char *dev)
{
    struct arp_packet pkt;
    struct sockaddr sa;
    int sock;
    sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ARP));
    if (sock < 0) {
        printf("create socket error, this program need root privilege.\n");
        exit(1);
    }
    memset(pkt.targ_hw_addr, 0xff, ETH_HW_ADDR_LEN);
    memcpy(pkt.src_hw_addr, shwa, ETH_HW_ADDR_LEN);
    pkt.frame_type     = htons(ETHERTYPE_ARP);  //0x0806
    pkt.hw_type        = htons(ARPHRD_ETHER);   //1
    pkt.prot_type      = htons(ETHERTYPE_IP);   //0x0800
    pkt.hw_addr_size   = ETH_HW_ADDR_LEN;       //6
    pkt.prot_addr_size = IP_ADDR_LEN;       //4
    pkt.op             = htons(ARPOP_REPLY);    //arp reply
    memcpy(pkt.sndr_hw_addr, shwa, ETH_HW_ADDR_LEN);
    memcpy(pkt.sndr_ip_addr, sip, IP_ADDR_LEN);
    memcpy(pkt.rcpt_hw_addr, shwa, ETH_HW_ADDR_LEN);
    memcpy(pkt.rcpt_ip_addr, sip, IP_ADDR_LEN);
    bzero(pkt.padding,18);
    strcpy(sa.sa_data,dev);
    if (sendto(sock,&pkt,sizeof(pkt),0,&sa,sizeof(sa)) < 0) {
         printf("sendto error\n");
     close(sock);
     return -1;
    }
    close(sock);
    return 0;
}
The result the program:
eth0 192.168.1.69 0:10:b2:4c:68:a
send arp broadcast success in dev: eth0
//eth0:1 192.168.3.69 is a virtual netcard
eth0 192.168.3.69 0:10:b2:4c:68:a
send arp broadcast success in dev: eth0
eth1 192.168.2.69 0:d0:b7:e0:8f:e1
send arp broadcast success in dev: eth1
The packets captured through: #tcpdump -b arp
15:42:07.789273 eth1 B arp reply 192.168.1.69 is-at 0:10:b2:4c:68:a (0:10:b2

:4c:68:a)
15:42:07.789273 eth1 B arp reply 192.168.3.69 is-at 0:10:b2:4c:68:a (0:10:b2

:4c:68:a)
15:42:07.789273 eth0 B arp reply 192.168.2.69 is-at 0:d0:b7:e0:8f:e1 (0:d0:b

7:e0:8f:e1)
--
※ 来源:·幽幽黄桷兰 bbs.cqupt.edu.cn·[FROM: missyou.net]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店