网卡混杂模式探测小程序
sniffscan [-s]
-s 为探测网段中的存活主机
不加参数为探测网络中混杂模式的网卡

#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.ifr_name);
if(ioctl(fd SIOCGIFADDR (char *) &buf) == -1){
fprintf(stderr “ioctl ifaddr failed: %s \n” strerror(errno));
exit(1);
}
fprintf(stdout “%s\n” (char*)inet_ntoa(((struct sockaddr_in*)(&buf.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(0×0800);
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;

}