- 论坛徽章:
- 0
|
试着用RARP协议求解,发现不能实现,以下用ARP协议遍历本地局域网的IP的实现方法,望各位提出意见。
以下是完整代码:
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <net/if.h>
#include <netdb.h>
#include <errno.h>
int socket_init(void);
int check_arp(char *, u_char *, char *);
int main(int argc, char *argv[])
{
struct sockaddr_in in_addr;
struct ethhdr *eth_hdr;
int sock, recv_len, addr_len;
char buffer[65535];
struct sockaddr_in my_ip;
u_char ip_addr[4], hw_addr[6];
unsigned int ip_min, ip_max;
int ret = 0;
memset(&in_addr, 0x0, sizeof(struct sockaddr_in));
if(argc < 2)
{
printf("The parameter is not specified\n");
exit(-1);
}
get_host_addr(hw_addr,&my_ip);
memcpy(ip_addr, (void *)(&my_ip.sin_addr), 4);
ip_min = inet_addr(inet_ntoa(my_ip.sin_addr)) & 0x00ffffff;
ip_max = inet_addr(inet_ntoa(my_ip.sin_addr)) | 0xff000000;
sock = socket_init();
while(1)
{
if(ip_min >= ip_max)
break;
arp_send(sock, ip_addr, hw_addr, ip_min);
addr_len = sizeof(in_addr);
recv_len = recvfrom(sock, buffer, sizeof(buffer), 0,
(struct sockaddr *)&in_addr, &addr_len);
eth_hdr = (struct ethhdr *)buffer;
switch(ntohs(eth_hdr->h_proto))
{
default:
break;
case 0x0806: //ARP packet
ret = check_arp(buffer, hw_addr, argv[1]);
if(ret == 0) goto Exit;
break;
}
memset(buffer, 0x0, sizeof(buffer));
ip_min = ip_min + 0x01000000;
}
Exit:
close(sock);
return 0;
}
int socket_init()
{
struct ifreq ifr;
int sock;
memset(&ifr, 0x0, sizeof(struct ifreq));
if((sock = socket(AF_INET, SOCK_PACKET, htons(0x0003))) < 0)
{
printf("Failed to socket(errno=%d)\n", errno);
exit(-1);
}
strcpy(ifr.ifr_name, "eth0");
if(ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
{
printf("Failed to ioctl(errno=%d)\n", errno);
exit(-1);
}
ifr.ifr_flags |= IFF_PROMISC;
if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
{
printf("Failed to ioctl(errno=%d)\n", errno);
exit(-1);
}
return sock;
}
int arp_send(sock,my_ip,hw_addr,ip)
int sock;
u_char my_ip[4],hw_addr[6];
unsigned int ip;
{
struct ethhdr *eth_hdr;
struct ether_arp *arp;
struct sockaddr sa;
u_char *arp_packet;
unsigned int pack_len;
pack_len = sizeof(struct ethhdr) + sizeof(struct ether_arp);
arp_packet = (u_char *)malloc(pack_len);
eth_hdr = (struct ethhdr *)arp_packet;
arp = (struct ether_arp *)(arp_packet + sizeof(struct ethhdr));
memset(eth_hdr->h_dest, 0xfffffff, sizeof(eth_hdr->h_dest));
memcpy(eth_hdr->h_source, hw_addr, 6);
eth_hdr->h_proto = htons(ETHERTYPE_ARP);
arp->arp_hrd = htons(ARPHRD_ETHER);
arp->arp_pro = htons(0x0800);
arp->arp_hln = 6;
arp->arp_pln = 4;
arp->arp_op = htons(ARPOP_REQUEST);
memcpy(arp->arp_sha, hw_addr, 6);
memcpy(arp->arp_spa, my_ip, 4);
memset(arp->arp_tha, 0xfffffff, sizeof(arp->arp_tha));
memcpy(arp->arp_tpa, (void *)&ip, 4);
strcpy(sa.sa_data, "eth0");
if(sendto(sock, arp_packet, pack_len, 0, &sa, sizeof(sa)) < 0)
{
printf("Failed to sendto(errno=%d)\n", errno);
exit(-1);
}
free(arp_packet);
return 0;
}
int check_arp(char *buff, u_char *hw_addr, char *dhw_addr)
{
struct ethhdr *eth_hdr;
struct ether_arp *arp;
u_char shw_addr[24];
memset(shw_addr, 0, sizeof(shw_addr));
eth_hdr = (struct ethhdr *)buff;
arp =(struct ether_arp *)(buff + sizeof(struct ethhdr));
if(arp->arp_op != htons(ARPOP_REPLY))
return -1;
if(memcmp(arp->arp_tha, hw_addr, 6) != 0)
return -1;
sprintf(shw_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
arp->arp_sha[0], arp->arp_sha[1], arp->arp_sha[2],
arp->arp_sha[3], arp->arp_sha[4], arp->arp_sha[5]);
if(!strcmp(shw_addr, dhw_addr))
{
printf("%-12s:[%02x:%02x:%02x:%02x:%02x:%02x]\n%-12s:[%d.%d.%d.%d]\n",
"HWaddr",
arp->arp_sha[0], arp->arp_sha[1], arp->arp_sha[2],
arp->arp_sha[3], arp->arp_sha[4], arp->arp_sha[5],
"inet addr",
arp->arp_spa[0],arp->arp_spa[1],arp->arp_spa[2],arp->arp_spa[3]);
return 0;
}
return -1;
}
int get_host_addr(hw_addr,my_ip)
struct sockaddr_in *my_ip;
u_char *hw_addr;
{
struct ifreq ifr;
int sock;
if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("Failed to socket(errno=%d)\n", errno);
exit(-1);
}
strcpy(ifr.ifr_name, "eth0");
if(ioctl(sock, SIOCGIFADDR, &ifr) < 0)
{
printf("Failed to ioctl(errno=%d)\n", errno);
exit(-1);
}
my_ip->sin_addr = ((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr;
if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
{
printf("Failed to ioctl(errno=%d)\n", errno);
exit(-1);
}
memcpy(hw_addr, ifr.ifr_hwaddr.sa_data, 6);
close(sock);
return 0;
} |
|