首页 文章

为什么arp回复不发送?

提问于
浏览
0

我从这个页面有这个代码:http://usuaris.tinet.cat/sag/send_arp.htm

#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?

我该如何解决?

1 回答

  • 0

    只要有以下内容就没有限制:

    • 你的操作系统支持它(适用于Linux,不能100%用于Windows,但它当然可以工作,因为它适用于Hyper-V桥接 - 你可能需要做一些调整) - 归功于@caffeinatedmonkey

    • 交换机支持它

    我提到了第二点,因为公司环境中的许多交换机被设置为过滤掉他们所看到的伪造的MAC回复,为每个端口等要求单个MAC,以确保安全并防止L2环路 .

    如果您想要工作源代码,请查找arpinggarpd的来源,并观察它如何做无偿/未经请求的arp .

相关问题