Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4732346
  • 博文数量: 930
  • 博客积分: 12070
  • 博客等级: 上将
  • 技术积分: 11448
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 16:57
文章分类

全部博文(930)

文章存档

2011年(60)

2010年(220)

2009年(371)

2008年(279)

分类: LINUX

2010-01-23 14:00:06

   程序内面我比较详细的做了注释,为了代码好看,注释都是用我自己憋屈的英文注释的,将就点吧!!!呵呵,我把arp的定义copy过来了,方便你们对比着阅读....

/*
This program sends out one ARP packet with source/target IP
and Ethernet hardware addresses suuplied by the user. It
compiles and works on Linux and will probably work on any
Unix that has SOCK_PACKET. kenthy@163.com
*/

#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>

#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

#if 0
/* ARP protocol opcodes. */
#define    ARPOP_REQUEST    1        /* ARP request            */
#define    ARPOP_REPLY    2        /* ARP reply            */
#define    ARPOP_RREQUEST    3        /* RARP request            */
#define    ARPOP_RREPLY    4        /* RARP reply            */
#define    ARPOP_InREQUEST    8        /* InARP request        */
#define    ARPOP_InREPLY    9        /* InARP reply            */
#define    ARPOP_NAK    10        /* (ATM)ARP NAK            */

struct arphdr
{
    unsigned short    ar_hrd;        /* format of hardware address    */
    unsigned short    ar_pro;        /* format of protocol address    */
    unsigned char    ar_hln;        /* length of hardware address    */
    unsigned char    ar_pln;        /* length of protocol address    */
    unsigned short    ar_op;        /* ARP opcode (command)        */

#if 0
     /*
     *     Ethernet looks like this : This bit is variable sized however...
     */

    unsigned char        ar_sha[ETH_ALEN];    /* sender hardware address    */
    unsigned char        ar_sip[4];        /* sender IP address        */
    unsigned char        ar_tha[ETH_ALEN];    /* target hardware address    */
    unsigned char        ar_tip[4];        /* target IP address        */
#endif

};
#endif

#define OP_ARP_REQUEST 2
#define OP_ARP_QUEST 1
#define DEFAULT_DEVICE "eth0"

char usage[] = {"usage: send_arp src_ip_addr src_hw_addr targ_ip_addr tar_hw_addr number\n"};

struct arp_packet
{
  u_char targ_hw_addr[ETH_HW_ADDR_LEN]; //Destination l2

  u_char src_hw_addr[ETH_HW_ADDR_LEN]; //Sourecd l2

  u_short frame_type; //Type:ARP(0x0806) l2

  u_short hw_type; //Hardware type: Ethernet(0x0001) arp

  u_short prot_type;//Protocol type: IP(0x0800) arp

  u_char hw_addr_size; //Hardware size: 6 arp

  u_char prot_addr_size;//Protocol size:4 arp

  u_short op; //Opcode: request(0x0001) arp

  u_char sndr_hw_addr[ETH_HW_ADDR_LEN];//Sender MAC address arp

  u_char sndr_ip_addr[IP_ADDR_LEN]; //Sender IP address arp

  u_char rcpt_hw_addr[ETH_HW_ADDR_LEN]; //Target MAC address arp

  u_char rcpt_ip_addr[IP_ADDR_LEN]; //Target IP address arp

  u_char padding[18]; //

};

void die (char *);
void get_ip_addr (struct in_addr *, char *);
void get_hw_addr (u_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;
  int j;
  int number;

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

  number=atoi(argv[5]);
  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_QUEST); //quest, if OP_ARP_REQUEST is arp reply


  get_hw_addr(pkt.targ_hw_addr, argv[4]);
  //get_hw_addr(pkt.rcpt_hw_addr, argv[4]);

  if(pkt.targ_hw_addr[0]||
     pkt.targ_hw_addr[1]||
     pkt.targ_hw_addr[2]||
     pkt.targ_hw_addr[3]||
     pkt.targ_hw_addr[4]||
     pkt.targ_hw_addr[5]||
     pkt.targ_hw_addr[6] == 0xff)
   {
    for(j=0; j<6; j++)
      pkt.rcpt_hw_addr[j] = 0x00;
    }
  else
   {
     for(j=0; j<6; j++)
      pkt.rcpt_hw_addr[j] = pkt.targ_hw_addr[j];
    }

  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);
  for (j=0;j<number;j++)
   {
    if (sendto(sock,&pkt,sizeof(pkt),0,&sa,sizeof(sa)) < 0)
    {
     perror("sendto");
     exit(1);
    }
   }
   exit(0);
}

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

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 ", str);
    exit(1);
    }
  }
}

void get_hw_addr (u_char *buf, char *str)
{
 int i;
 unsigned int p[6];
 
 i=sscanf(str, "%x:%x:%x:%x:%x:%x", &p[0],&p[1],&p[2],
                 &p[3],&p[4],&p[5]);        

 if (i != 6)
  {
   printf("error parsing MAC\n");
   exit(1);
  }        
                
  for(i = 0; i<6; i++)
     buf[i] = p[i];
}


阅读(4502) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~