📄 rid.c
字号:
#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>/* Standard defines *//* Network includes and defines */#include "netconfig.h"#include "functions.h"#include <fcntl.h>/* ALL GLOBALS START WITH A CAPITAL LETTER *//* Command line option switches */u_short BatchSize = DEFAULT_BATCHSIZE;u_short NumPings = DEFAULT_NUMPINGS;u_short Sleep = DEFAULT_SLEEP;int FlgDebug = 0;int FlgExtraDebug = 0;int FlgVerbose = 0;/* Globals that everything should access. My CS teacher would hate me */pid_t PidSender = -1;pid_t PidListener = -1;struct host *Head; /* First host in link list of alive hosts */u_long NumAlive = 0; /* Number of hosts in link list */u_short NumToPing = 0; /* Number of hosts to ping */char *Device; /* The device we listen on */u_short PcapOffset; /* Offset to IP - dependent on device */u_short MaxMTU = DEFAULT_MAXMTU; /* Maximum MTU for link */u_long PcapTO = DEFAULT_PCAPTO; /* Timeout to wait between pcap read */u_long TO = DEFAULT_TO; /* Default timeout for select calls */u_short NumSends = DEFAULT_NUMSENDS; /* Number of times to send packet */u_short ConfigNum=0; /* Number of config file read/sends read *//* ICMP send/receive link list */struct icmp_item *ICMP_Send = NULL;struct icmp_item *ICMP_Recv = NULL;/* UDP send/receive link list */struct udp_item *UDP_Send = NULL;struct udp_item *UDP_Recv = NULL;/* TCP send/receive link list */struct tcp_item *TCP_Send = NULL;struct tcp_item *TCP_Recv = NULL;/* We have these here so we don't have to keep recreating them. */int RawSock; /* Our raw socket */fd_set RawFD; /* Same as above */struct host *ToPing; /* Hosts to ping */int main(int argc, char *argv[]) {extern int optind; /* option index */extern char *optarg; /* option argument */int cai; /* Current argument index in getopt */char *filename; /* input filename */char *mask_ptr; /* start IP if scanning network */int mask; /* CIDR mask */FILE *in; /* actual input file of hosts */char *tptr; /* temp pointer into char array -used in parsing command args */char line[BUFSIZE]; /* Input line from file */char perr[PCAP_ERRBUF_SIZE]; /* Generic error's in pcap routines */struct protoent *proto; /* Protocol for ICMP */int dlink; /* PCAP data link ID */pcap_t *listener; /* Listener process pcap interface */int optval, optlen; /* Max recv buffer size per nmap */struct bpf_program lcode; /* Compiled pcap code */u_int netmask; /* The netmask for this host */u_int localnet; /* Needed for pcap_compile */char l_filter[BUFSIZE]=""; /* Text code for pcap to compile */extern FILE * yyin; /* STDIN for a grammer to read */char *YYIN=NULL; /* File for our lang to read */int ret; /* Return value from function calls */struct icmp_item *temp = NULL; /* Initialize everything */ filename=mask_ptr=NULL; /* check to make sure we're root */ if(getuid()!=0) { fprintf(stderr, "You must be root to run %s\n", argv[0]); exit(FAILURE); } PidSender = getpid() & 0xFFFF; if((proto=getprotobyname("icmp"))==NULL){ perror("System doesn't understand ICMP. *aborting*\n"); exit(FAILURE); } if((RawSock = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0){ perror("Can't allocate raw ICMP socket. *aborting*\n"); exit(FAILURE); } /* Set socket buffer as large as possible to help prevent packet loss */ optval = MAX_RECV_BUF; optlen = sizeof(int); if(setsockopt(RawSock, SOL_SOCKET, SO_RCVBUF, (void *) &optval, optlen) != 0) perror("Problem setting max recv buffer. ping may loose packets\n"); /* Set socket to non-blocking */ optval = O_NONBLOCK | fcntl(RawSock, F_GETFL); fcntl(RawSock, F_SETFL, optval); /* Broadcast socket */ optval = 1; if(setsockopt(RawSock, SOL_SOCKET, SO_BROADCAST, (void *)&optval, optlen) != 0) perror("Problem broadcasting socket. continuing..\n"); /* Process input arguments */ while((cai=getopt(argc, argv, "ndbDtvchfs:")) != EOF) { switch(cai){ case 'f': if(optarg == NULL) { usage(argv[0]); exit(FAILURE); } filename = optarg; optind++; break; case 't': Sleep = atoi(argv[optind]); optind++; break; case 'd': FlgDebug = 1; break; case 'D': FlgDebug = 1; FlgExtraDebug=1; break; case 'h': usage(argv[0]); exit(SUCCESS); break; case 'b': BatchSize = atoi(argv[optind]); optind++; break; case 's': MaxMTU = atoi(argv[optind]); optind++; break; case 'c': YYIN = argv[optind]; optind++; break; case 'n': NumSends = atoi(argv[optind]); optind++; break; case 'v': FlgVerbose = 1; break; default : usage(argv[0]); exit(FAILURE); break; } } /* Get config data */ if(YYIN == NULL){ yyin = fopen(DEFAULT_YYIN, "r"); } else { yyin = fopen(YYIN, "r"); } if(yyin==NULL){ perror(NULL); exit(FAILURE); } ret = yyparse(); if(ret != 0){ fprintf(stderr, "Error in config file. *aborting*\n"); exit(FAILURE); } /* Allocate a buffer to hold a simple list of a batch of hosts to ping */ ToPing = malloc(sizeof(struct host) * BatchSize); if(ToPing == NULL){ perror("malloc error. *aborting*\n"); exit(FAILURE); } /* * Are there command line ranges/hosts? We only take a list or a filename, * not both */ if( (optind >= argc) && (filename==NULL) ) { usage(argv[0]); exit(FAILURE); } /* Process CIDR blocks */ while(optind < argc){ mask_ptr = strchr(argv[optind], '/'); if(mask_ptr){ *mask_ptr='\0'; mask_ptr++; if(!isalnum(*mask_ptr)){ usage(argv[0]); exit(FAILURE); } mask = atoi(mask_ptr); } else { printf("No mask given, assuming host scan (/32)\n"); fflush(NULL); mask=32; } /* Make sure we're scanning a reasonable size network */ if(mask < 16){ fprintf(stderr, "RID will not scan network greater than /16\n"); exit(FAILURE); } if(add_ips(argv[optind], mask) != SUCCESS){ exit(FAILURE); } optind++; } if(filename != NULL){ in=fopen(filename, "r"); while(fgets(line, sizeof(line), in)) { /* magic to avoid comments */ if((!*line) || (line[0]=='#') || (line[0]=='\'') || (line[0]==';')) continue; /* take off newline */ line[strlen(line)-1]='\0'; /* if(FlgDebug) printf("Adding %s\n", line); */ add_ip(line); } } /* clean out the remainders - Anythign less than batchsize*/ pingsweep(NumToPing); if(FlgExtraDebug) { printf("Number of hosts alive: %d\n", NumAlive); fflush(NULL); } /* * Initialize pcap device and open. */ if((Device = pcap_lookupdev(perr)) == NULL){ fprintf(stderr, "Couldn't find acceptable device. *aborting*\n"); exit(FAILURE); } if(FlgDebug) { printf("Using device: %s\n", Device); fflush(NULL); } if((listener = pcap_open_live(Device, DEFAULT_MAXMTU, 0, PcapTO,perr)) == NULL){ fprintf(stderr, "Couln't open ping listener: %s\n", pcap_geterr(listener)); exit(FAILURE); } if((dlink = pcap_datalink(listener)) < 0){ fprintf(stderr, "Cannot obtain datalink info for device %s\n", Device); exit(FAILURE); } switch(dlink){ case DLT_EN10MB: PcapOffset = 14; break; case DLT_IEEE802: PcapOffset = 22; break; case DLT_NULL: PcapOffset = 4; break; case DLT_RAW: PcapOffset = 4; break; default: PcapOffset = 14; printf("Don't know data offset for device %s", Device); printf(". Taking wild guess it's ethernet-like\n"); fflush(NULL); break; } if(pcap_lookupnet(Device, &localnet, &netmask, perr) < 0){ fprintf(stderr, "Error looking up localnet: %s\n", perr); exit(FAILURE); } if (pcap_compile(listener, &lcode, l_filter, 0, netmask) < 0){ fprintf(stderr, "Error compiling our pcap filter: %s\n", pcap_geterr(listener)); exit(FAILURE); } if (pcap_setfilter(listener, &lcode) < 0 ){ fprintf(stderr, "Failed to set the pcap filter: %s\n", pcap_geterr(listener)); exit(FAILURE); } if (FlgVerbose) { printf("%ld hosts responded during pingsweep.\n",NumAlive); fflush(NULL); } if (NumAlive == 0) exit(SUCCESS); if(FlgDebug) printlist(); switch(PidListener=fork()){ case -1: /* error in forking */ fprintf(stderr, "Error in forking: %s\n", strerror(errno)); exit(FAILURE); break; case 0: dolisten(listener); /* Child */ break; default: sleep(2); /* Wait for child to start executing */ sender(); sleep(Sleep); /* Wait for all responses before exiting */ kill(PidListener, SIGTERM); waitpid(PidListener, NULL, NULL); break; } return SUCCESS;}int add_ips(char *ip, int mask){u_long num_hosts;int res;u_long t_host;struct in_addr t_ip; /* Total number of hosts to process */ num_hosts = NumHosts[mask]; res = inet_aton(ip, &t_ip); if(res <= 0){ fprintf(stderr, "Invalid IP: %s\n", ip); return FAILURE; } t_host = ntohl(t_ip.s_addr); t_host &= MaskBits[mask]; t_ip.s_addr = htonl(t_host); while(num_hosts > 0){ if(mask != 32) t_host++; t_ip.s_addr = htonl(t_host); ToPing[NumToPing].sad.sin_family = AF_INET; ToPing[NumToPing].sad.sin_addr.s_addr = t_ip.s_addr; NumToPing++; if(NumToPing == BatchSize){ pingsweep(NumToPing); } num_hosts--; } pingsweep(NumToPing); return SUCCESS;}void add_ip(char *ip) { struct hostent *hp = NULL; hp = gethostbyname(ip); if(hp == NULL){ if(FlgDebug) printf ("Omitting host: %s\n", ip); return; } ToPing[NumToPing].sad.sin_family=AF_INET; ToPing[NumToPing].sad.sin_addr.s_addr = (*(u_long *) hp->h_addr); NumToPing++; if(NumToPing == BatchSize){ /* Every time we get a batch, ping sweep and clean out non-responding hosts */ pingsweep(NumToPing); }}void generate_ip(char *start, char *end){ struct in_addr first, second, myaddr; long x; first.s_addr = inet_addr(start); second.s_addr = inet_addr(end); for (x = ntohl(first.s_addr); x <= ntohl(second.s_addr); x++) { /* Skip broadcasts */ if ((x & 0xff) == 0) x++; myaddr.s_addr = htonl(x); /* if(flgreallydebug) printf(" Adding %s\n", inet_ntoa(myaddr)); */ /* I know, this is inefficent. But good guys are doing this, right? */ add_ip((char *)inet_ntoa(myaddr)); }}void usage(char *progname){ printf("usage: %s", progname); printf(" <options> <host or host range>\n"); printf(" -f <filename>: Filename containing host list, one per line\n"); printf(" -t <timeout>: Time to wait for responses before exiting. Default=30\n"); printf(" -b <batchsize>: Batchsize to send to at once. There is a small\n"); printf(" pause between each batch\n"); printf(" -s <snaplen>: Size of bytes to snarf up. See tcpdump man page\n"); printf(" -c <config file>: File containing patterns to match\n"); printf(" -n <number>: Number of pings to send to determine if host is up\n"); printf(" -v: verbose - displays progress messages to stdout\n"); printf(" -h: This screen\n"); printf("Copyright Jan 21 2000 David Brumley <dbrumley@stanford.edu>\n"); printf("All Rights Reserved\n"); printf("URL: http://www.theorygroup.com/Software/RID\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -