/* * run -- an nmap wrapper * * checks nmap options and, if all is well, spawns nmap */ #include #include #include #include #define TARGET "169.237.7.61" #define NMAP "/usr/local/bin/nmap" #define NMAP0 "nmap" #define PATH "PATH=/usr/bin:/bin:/usr/sbin:/sbin"; #define IFS "IFS= \t\n"; /* valid options -- allow probing, verbose, fragmentation, and ping analysis */ char *okopts[] = { "-sT", "-sF", "-sX", "-sN", "-sP", "-sU", "-sA", "-sW", "-sR", "-P0", "-PT", "-PS", "-PI", "-O", "-f", "-v", "-vv", "-F", "-sS", NULL, }; /* valid options -- these require numeric arg to the options */ char *numargopts[] = { "-g", "-M", "--max_rtt_timeout", "--min_rtt_timeout", "--initial_rtt_timeout", NULL, }; /* valid options -- these require lists to the options */ char *listargopts[] = { "-p", NULL, }; /* * returns 1 if s points to a number with optional surrounding spaces * 0 otherwise */ int isnum(char *s) { int count = 0; /* need at least 1 digit */ /* skip leading spaces */ while(isspace(*s)) s++; /* count digits as you skip over them */ while(isdigit(*s)){ s++; count++; } /* skip trailing spaces */ while(isspace(*s)) s++; /* you need at least 1 digit and s pointing to NUL byte */ return(count && !*s); } /* * returns 1 if s points to a list of comma-separated numbers and ranges * (a range is num-num); 0 otherwise */ int islist(char *s) { int count = 0; /* need at least 1 digit */ /* skip leading spaces */ while(isspace(*s)) s++; /* skip numbers, list */ while(*s){ /* just look for chars here */ if (!isdigit(*s) && *s != '-' && *s != ',') return(0); count++; s++; } /* skip trailing spaces */ while(isspace(*s)) s++; /* you need at least 1 list and s pointing to NUL byte */ return(count && !*s); } /* * report errors and drop dead! */ void error(char *s, char *p) { fprintf(stderr, s, p); fprintf(stderr, "\n"); exit(1); } /* * the BIG enchilada * this checks the options and if valid spawns the nmap program */ int main(int argc, char *argv[]) { char *ncarg[1000]; /* args to nmap */ char *env[1000]; /* environment -- okay, MAY be overkill! */ int i; /* counter in various loops */ int okay; /* 1 when option determined valid, else 0 */ char **p; /* loops through lists of strings */ /* the name of the program to spawn */ ncarg[0] = NMAP0; /* * loop through list of options * if it's valid, add it to the options array ncarg * if not, kiss the user goodbye */ for(i = 1; i < argc && i < 998; i++){ okay = 0; /* * first option check: see if it doesn't require * an argument -- check okopts list */ for(p = okopts; *p != NULL; p++) if (strcmp(argv[i], *p) == 0){ /* bingo! we're cool */ okay = 1; ncarg[i] = argv[i]; break; } if (okay) continue; /* * not a valid option so far -- * see if it takes a number */ for(p = numargopts; *p != NULL; p++) if (strncmp(argv[i], *p, strlen(*p)) == 0){ ncarg[i] = argv[i]; if (strlen(argv[i]) == strlen(*p)){ i++; ncarg[i] = argv[i]; } else argv[i] += strlen(*p); if (argv[i] == NULL || !isnum(argv[i])){ error("need number after %s", *p); exit(1); } okay = 1; break; } if (okay) continue; /* * not a valid option so far -- * see if it takes a list */ for(p = listargopts; *p != NULL; p++) if (strncmp(argv[i], *p, strlen(*p)) == 0){ ncarg[i] = argv[i]; if (strlen(argv[i]) == strlen(*p)){ i++; ncarg[i] = argv[i]; } else argv[i] += strlen(*p); if (argv[i] == NULL || !islist(argv[i])){ error("need list after %s", *p); exit(1); } okay = 1; break; } /* * if it's not valid, give error and quit */ if (!okay){ error("%s: unknown or disallowed option\n", argv[i]); exit(1); } } /* * all's okay -- set up the rest of the argument list * and the environment */ ncarg[i] = TARGET; ncarg[i+1] = NULL; env[0] = PATH; env[1] = IFS; env[2] = NULL; /* * spawn it */ if (execve(NMAP, ncarg, env) < 0){ perror("execv: nmap"); exit(1); } /* * should NEVER get here! */ exit(0); }