У меня есть этот код с этой страницы: 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?
Как это исправить?
No. Пока ваше оборудование поддерживает его. – 0xcaff