2015-11-22 56 views
0

我从这个网页验证码:http://usuaris.tinet.cat/sag/send_arp.htm为什么ARP回复没有发送?

#include <stdio.h> 
#include <ctype.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 

// replace following by 
// #include 
// for windows migrating start ... 

#include <netdb.h> 
#include <sys/socket.h> 
// --- not required by RH --- #include <linux/in.h> 
#include <arpa/inet.h> 
#include <linux/if_ether.h> 

// http://en.wikipedia.org/wiki/Address_Resolution_Protocol 
// hlen   - Ethernet addresses size is 6. 
// plen   - IPv4 address size is 4. 
// frtype  - 0x0806 = ARP - http://en.wikipedia.org/wiki/EtherType 
// htype   - Ethernet is 1. 
// Protocol type - for IPv4, this has the value 0x0800 
// Operation  - specifies the operation that the sender is performing: 1 for request, 2 for reply. 

#define ETH_HW_ADDR_LEN 6 
#define IP_ADDR_LEN  4 
#define ARP_FRAME_TYPE 0x0806 
#define ETHER_HW_TYPE 1 
#define IP_PROTO_TYPE 0x0800 
#define OP_ARP_REQUEST 2 

#define DEFAULT_DEVICE "wlan0" 

char usage[]={"send_arp: sends out custom ARP packet. yuri volobuev'97\n\ 
\tusage: send_arp src_ip_addr src_hw_addr targ_ip_addr tar_hw_addr\n\n"}; 

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]; 
}; 

void die(char *); 
void get_ip_addr(struct in_addr*,char*); 
void get_hw_addr(char*,char*); 

int main (int argc, char** argv) { 

    struct in_addr src_in_addr, targ_in_addr; 
    struct arp_packet pkt; 
    struct sockaddr sa; 
    int sock; 

    if (argc != 5) die(usage) ; 

    sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_RARP)) ; 
    if (sock < 0){ 
    perror("socket"); 
    exit(1); 
    } 

    pkt.frame_type  = htons(ARP_FRAME_TYPE); 
    pkt.hw_type  = htons(ETHER_HW_TYPE); 
    pkt.prot_type  = htons(IP_PROTO_TYPE); 
    pkt.hw_addr_size = ETH_HW_ADDR_LEN; 
    pkt.prot_addr_size = IP_ADDR_LEN; 
    pkt.op    = htons(OP_ARP_REQUEST); 

    get_hw_addr(pkt.targ_hw_addr, argv[4]); 
    get_hw_addr(pkt.rcpt_hw_addr, argv[4]); 
    get_hw_addr(pkt.src_hw_addr, argv[2]); 
    get_hw_addr(pkt.sndr_hw_addr, argv[2]); 

    get_ip_addr(&src_in_addr, argv[1]); 
    get_ip_addr(&targ_in_addr, argv[3]); 

    memcpy(pkt.sndr_ip_addr, &src_in_addr, IP_ADDR_LEN); 
    memcpy(pkt.rcpt_ip_addr, &targ_in_addr, IP_ADDR_LEN); 

    bzero(pkt.padding, 18); 

    strcpy(sa.sa_data, DEFAULT_DEVICE) ; 
    if (sendto(sock, &pkt,sizeof(pkt), 0, &sa,sizeof(sa)) < 0){ 
    perror("sendto"); 
    exit(1); 
    } 
    exit(0); 

} ; // main 

// main code end 


void die(char* str){ 
    fprintf(stderr,"%s\n",str); 
    exit(1); 
} ; // die 

void get_ip_addr(struct in_addr* in_addr, char* str){ 

    struct hostent *hostp; 

    in_addr->s_addr = inet_addr(str); 
    if (in_addr->s_addr == -1){ 
    if((hostp = gethostbyname(str))) 
     bcopy(hostp->h_addr, in_addr, hostp->h_length) ; 
    else { 
     fprintf(stderr, "send_arp: unknown host [%s].\n", str) ; 
     exit(1); 
    } 
    } 
} ; // get_ip_addr 

void get_hw_addr(char* buf, char* str){ 

    int i; 
    char c,val; 

    for (i=0 ; i < ETH_HW_ADDR_LEN ; i++){ 
    if(!(c = tolower(*str++))) die("Invalid hardware address"); 
    if(isdigit(c)) val = c-'0'; 
    else if(c >= 'a' && c <= 'f') val = c-'a'+10; 
    else die("Invalid hardware address"); 

    *buf = val << 4; 
    if(!(c = tolower(*str++))) die("Invalid hardware address"); 
    if(isdigit(c)) val = c-'0'; 
    else if(c >= 'a' && c <= 'f') val = c-'a'+10; 
    else die("Invalid hardware address"); 

    *buf++ |= val; 

    if (*str == ':') str++ ; 
    } ; // for loop 
} ; // get_hw_addr 

,它的工作。但是它只在源MAC地址正确时才起作用。 例如: 我的Mac是:01:23:45:67:89:AB

./send_arp 192.168.1.1 01:23:45:67:89:AB 192.168.1.2 FF:FF:FF:FF:FF:FF 

而这个包到达目标设备,但是当我改变源MAC它没有。

我正在使用tcpdump来检查它,并且在源设备和目标设备上看不到任何arp数据包。

在内核中是否有任何限制发送另一个源mac?

我该如何解决?

+0

没有。只要你的硬件支持它。 – 0xcaff

回答

0

没有限制,只要:

  • 你的操作系统支持的话(在Linux,无法保证100%的Windows,但它绝对可以作出工作,因为它适用于Hyper-V的桥接 - 可能会有一些调整,你需要做的) - 信用@caffeinatedmonkey
  • 交换机支持它

我提到这一点,第二点,因为在企业环境中的许多开关设为过滤掉他们看到伪造的MAC回复,授权每个端口的单个MAC等c。为了安全并防止L2循环。

如果您想要工作源代码,请查找arpinggarpd的源代码,并观察它是如何实现免费/不请自来的arp。

+0

哈哈,你拼错了我的名字。呃。对。 – 0xcaff

相关问题