2015-11-22 8 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-адрес правильный. Например: My УДС: 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 

И этот пакет приходит к целевому устройству, но когда я изменить исходный макинтош он не делает.

Я использую tcpdump, чтобы проверить его, и я не вижу никакого arp-пакета на исходном устройстве и на целевом устройстве.

Есть ли какие-либо ограничения в ядре для отправки другого исходного mac?

Как это исправить?

+0

No. Пока ваше оборудование поддерживает его. – 0xcaff

ответ

0

Там нет ограничений до тех пор, как:

  • Ваша ОС поддерживает его (работает на Linux, не могу ручаться 100% для Windows, но это, безусловно, может быть сделано, чтобы работать, как это работает для Hyper-V шунтирование - там могут быть некоторые настройки вам нужно сделать) - кредит @caffeinatedmonkey
  • коммутатор поддерживает его

Я упоминаю эту вторую точку, так как многие коммутаторы в корпоративной среде настроены, чтобы отфильтровать то, что они как фиктивные ответы MAC, мандат одиночный MAC на порт et c., для обеспечения безопасности и предотвращения циклов L2.

Если вы хотите использовать исходный код, найдите источник для arping или garpd и посмотрите, как он делает бесплатный/незапрашиваемый arp.

+0

Ха-ха, ты записал мое имя неправильно. Err. правильно. – 0xcaff