ARP协议的c语言实现源代码【转载】收藏
什么是ARP协议
英文原义:Address Resolution Protocol
中文释义:(RFC-826)地址解析协议
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define src_addr "192.168.0.239"
#define device "eth0"
#define fill_buf "aaaaaaaaaaaa"
int socket_id;
char *target = src_addr;
int send_count = 0;
int recv_count = 0;
struct in_addr src, dst;
struct sockaddr_ll me, he;
struct timeval send_time, recv_time;
struct in_addr get_src_ip(char * devices)
{
struct sockaddr_in saddr;
int sock_id = socket(AF_INET, SOCK_DGRAM, 0); if (sock_id < 0) {
perror("socket");
exit(2);
}
if (devices) {
if (setsockopt(sock_id, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1)
perror("WARNING: interface is ignored");
}
int alen = sizeof(saddr);
memset(&saddr, 0, sizeof(saddr));
saddr.sin_port = htons(0x1000);
saddr.sin_family = AF_INET;
if (connect(sock_id, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
perror("connect");
exit(2);
}
if (getsockname(sock_id, (struct sockaddr*)&saddr, &alen) == -1) {
perror("getsockname");
exit(2);
}
close(sock_id);
return saddr.sin_addr;
}
int check_device(char* if_dev, int ss)
{
int ifindex;
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, if_dev, IFNAMSIZ-1);
if (ioctl(ss, SIOCGIFINDEX, &ifr) < 0) {
fprintf(stderr, "arping: unknown iface %s\n", if_dev);
exit(2);
}
ifindex = ifr.ifr_ifindex;
if (ioctl(ss, SIOCGIFFLAGS, (char*)&ifr)) {
perror("ioctl(SIOCGIFFLAGS)");
exit(2);
}
if (!(ifr.ifr_flags&IFF_UP)) {
printf("Interface \"%s\" is down\n", if_dev);
exit(2);
}
if (ifr.ifr_flags&(IFF_NOARP|IFF_LOOPBACK)) {
printf("Interface \"%s\" is not ARPable\n", if_dev);
exit(2);
return ifindex;
} // check_device()
int socket_init()
{
int s, s_errno;
s = socket(PF_PACKET, SOCK_DGRAM, 0);
s_errno = errno;
me.sll_family = AF_PACKET;
me.sll_ifindex = check_device(device, s);
me.sll_protocol = htons(ETH_P_ARP);
if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) {
perror("bind");
exit(2);
}
int alen = sizeof(me);
if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
perror("getsockname");
exit(2);
}
if (me.sll_halen == 0) {
printf("Interface \"%s\" is not ARPable (no ll address)\n", device);
exit(2);
}
he = me;
memset(he.sll_addr, -1, he.sll_halen); // set dmac addr FF:FF:FF:FF:FF:FF
return s;
}
int
create_pkt(unsigned char * buf, struct in_addr src, struct in_addr dst, struct sockaddr_ll * FROM, struct sockaddr_ll * TO)
{
struct arphdr *ah = (struct arphdr*) buf;
unsigned char *p = (unsigned char *)(ah+1);
ah->ar_hrd = htons(FROM->sll_hatype);
if (ah->ar_hrd == htons(ARPHRD_FDDI))
ah->ar_hrd = htons(ARPHRD_ETHER);
ah->ar_pro = htons(ETH_P_IP);
ah->ar_hln = FROM->sll_halen;
ah->ar_pln = 4;
ah->ar_op = htons(ARPOP_REQUEST);
memcpy(p, &FROM->sll_addr, ah->ar_hln);
p+=FROM->sll_halen;
memcpy(p, &src, 4);