#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/param.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> #include <netinet/in.h> #include <net/if_arp.h> #include <net/ethernet.h>
#define MAXINTERFACES 16
int getpacket(int fd);
int sendpacket(int fd, char *mac, unsigned int network, unsigned ipaddr, unsigned int range);
struct arpheader { unsigned short int ar_hrd; /* Format of hardware address. */ unsigned short int ar_pro; /* Format of protocol address. */ unsigned char ar_hln; /* Length of hardware address. */ unsigned char ar_pln; /* Length of protocol address. */ unsigned short int ar_op; /* ARP opcode (command). */
unsigned char __ar_sha[6]; /* Sender hardware address. */ unsigned char __ar_sip[4]; /* Sender IP address. */ unsigned char __ar_tha[6]; /* Target hardware address. */ unsigned char __ar_tip[4]; /* Target IP address. */ };
int flag = 0; int main(int argc, char *argv[]){ int fd; int intnum, i, j; int pid; struct ifconf ifc; struct ifreq buf[MAXINTERFACES]; struct in_addr ipaddr, netmask; unsigned int network, range; char mac[6]; int stat; if((argc == 2)&&(strcmp(argv[1], "-s") == 0)){ flag = 1; }
if((fd = socket(AF_INET, SOCK_PACKET, htons(ETHERTYPE_ARP))) == -1){ fprintf(stderr, "socket init failed: %s \n", strerror(errno)); exit(1); } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t)buf; if(ioctl (fd, SIOCGIFCONF, (char *) &ifc) == -1){ fprintf(stderr, "ioctl ifconf failed: %s \n", strerror(errno)); exit(1); } intnum = ifc.ifc_len / sizeof (struct ifreq); //printf("interface num is intrface=%d\n\n\n",intrface);
i = 0; fprintf(stdout, "select follow net device:\n"); while(i < intnum){ fprintf (stdout, "%d. net device %s: ", i+1, buf[i].ifr_name); if(ioctl(fd, SIOCGIFADDR, (char *) &buf[i]) == -1){ fprintf(stderr, "ioctl ifaddr failed: %s \n", strerror(errno)); exit(1); } fprintf(stdout, "%s\n", (char*)inet_ntoa(((struct sockaddr_in*)(&buf[i].ifr_addr))->sin_addr)); i++; } fprintf(stdout, "please select one net device[1-%d]:", intnum); fscanf(stdin, "%d", &j); if(ioctl(fd, SIOCGIFADDR, (char *) &buf[j-1]) == -1){ fprintf(stderr, "ioctl ifaddr failed: %s \n", strerror(errno)); exit(1); } memcpy(&ipaddr, &(((struct sockaddr_in*)(&buf[j-1].ifr_addr))->sin_addr), sizeof(struct in_addr)); if(ioctl(fd, SIOCGIFNETMASK, (char *) &buf[j-1]) == -1){ fprintf(stderr, "ioctl ifaddr failed: %s \n", strerror(errno)); exit(1); } memcpy(&netmask, &(((struct sockaddr_in*)(&buf[j-1].ifr_addr))->sin_addr), sizeof(struct in_addr)); if (ioctl (fd, SIOCGIFHWADDR, (char *) &buf[j-1]) == -1){ fprintf(stderr, "ioctl hwaddr failed: %s \n", strerror(errno)); exit(1); } memcpy(mac, buf[j-1].ifr_hwaddr.sa_data, 6); network = (ntohl(ipaddr.s_addr) & ntohl(netmask.s_addr)); range = ~ntohl(netmask.s_addr); pid = fork(); if(pid == 0){ getpacket(fd); }else{ sendpacket(fd, mac, network, ipaddr.s_addr, range); } wait(&stat); return 0;
}
int getpacket(int fd){ struct sockaddr addr; char buffer[1500]; int recv_byte, len; struct ether_header eth_hdr; struct arpheader arp_hdr; bzero(&addr, sizeof(addr)); len = sizeof(addr); struct in_addr ipaddr; fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(fd, &fds); timeout.tv_sec = 3; timeout.tv_usec = 0; while(1){ select(fd+1, &fds, NULL, NULL, &timeout); if(FD_ISSET(fd, &fds)){ if((recv_byte = recvfrom(fd, buffer, 1500, 0, &addr, (socklen_t*)&len)) == -1){ fprintf(stderr, "recvfrom failed: %s \n", strerror(errno)); exit(1); } memcpy(e_hdr, buffer, sizeof(eth_hdr)); memcpy(&arp_hdr, buffer+sizeof(eth_hdr), sizeof(arp_hdr)); if(arp_hdr.ar_op == ntohs(2)){ memcpy(&ipaddr, arp_hdr.__ar_sip, 4); if(flag){ fprintf(stdout, "%s, host on line\n", (char*)inet_ntoa(ipaddr)); }else{ fprintf(stdout, "%s, network device may be set promisc\n", (char*)inet_ntoa(ipaddr)); } } }else{ break; } } close(fd); return 0; }
int sendpacket(int fd, char *mac, unsigned int network, unsigned ipaddr, unsigned int range){ struct ether_header eth_hdr; struct arpheader arp_hdr; int i; struct sockaddr addr; char buffer[255]; int ip; if(flag){ memcpy(e_hdr.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6); }else{ memcpy(e_hdr.ether_dhost, "\xff\xff\xff\xff\xff\xfe", 6); //memcpy(e_hdr.ether_dhost, "\x01\x00\x5e\x00\x00\x01", 6);
} memcpy(e_hdr.ether_shost, mac, 6); eth_hdr.ether_type = htons(ETHERTYPE_ARP); arp_hdr.ar_hrd = htons(1); arp_hdr.ar_pro = htons(0x0800); arp_hdr.ar_hln = 6; arp_hdr.ar_pln = 4; arp_hdr.ar_op = htons(1); memcpy(arp_hdr.__ar_sha, mac, 6); memcpy(arp_hdr.__ar_sip, &ipaddr, 4); memset(arp_hdr.__ar_tha, 0, 6); bzero(&addr, sizeof(addr)); strcpy(addr.sa_data, "eth0" ); i = 1; while(i < range){ ip = htonl(network + i); memcpy(arp_hdr.__ar_tip, &ip, 4); memcpy(buffer, e_hdr, sizeof(eth_hdr)); memcpy(buffer+sizeof(eth_hdr), &arp_hdr, sizeof(arp_hdr)); if(sendto(fd, buffer, sizeof(eth_hdr)+sizeof(arp_hdr), 0, (struct sockaddr*)&addr, sizeof(addr)) == -1){ fprintf(stderr, "sendto failed: %s, \n", strerror(errno)); exit(1); } i++; usleep(1000); } close(fd); return 0; }
|