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