/* ipguard.c * * Copyright (c) 2010 SeaD * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: ipguard.c,v 1.1.1.1.4.1 2021/03/17 19:44:26 misho Exp $ * */ #include "ipguard.h" char iface[IFNAMSIZ]; char ethers_name[PATH_MAX]; char log_name[PATH_MAX]; char pid_name[PATH_MAX]; char fmac[18]; char pcapf[PCAPFSIZ]; char suser[MAXLOGNAME]; int ethers_update; int fake_regen; int fake_num; int fake_time; int buffer_num; int addr_nosubst; int nofirst; int grant; int read_only; int duplex; int fixbc; int hidden; int promisc; int debug; int verbose; unsigned int all, good, grat, wgrat, zmac, zip, bad, bmac, bsip, btip, bnew, bgrat, mymac, fake, pfake, nzh, nbe, mis; char pfmac[18]; char s[128+1]; void usage(char *name) { fprintf(stdout, "%s v%s (c) %s <%s>\n\n", NAME, VERSION, AUTHOR, MAIL); fprintf(stdout, "usage: %s [-h] [-ajgrxziovd]\n", name); fprintf(stdout, " [-f ethers] [-l log] [-p pid] [-m mac] [-c filter] [-u seconds] [-k seconds]\n"); fprintf(stdout, " [-n fakes] [-t mseconds] [-b buf] [-s user] \n\n"); } void help(void) { fprintf(stdout, "available options:\n"); fprintf(stdout, " -f | -e ethers file (" ETHERSFILE ")\n"); fprintf(stdout, " -l log file (" LOGNAME "_.log)\n"); fprintf(stdout, " -p pid file (" PIDNAME "_.pid)\n"); fprintf(stdout, " -m fake mac (" FAKEMAC ")\n"); fprintf(stdout, " -c pcap expression (none)\n"); fprintf(stdout, " -u update ethers interval (%d)\n", ETHERSTO); fprintf(stdout, " -k fake regenerate time (%d)\n", FAKEREGEN); fprintf(stdout, " -n fake replies number (%d)\n", FAKENUM); fprintf(stdout, " -t time between fakes (%d)\n", FAKETIME); fprintf(stdout, " -b mac-ip buffer size (%d)\n", BUFSIZE); fprintf(stdout, " -s set user (none)\n"); fprintf(stdout, " -a no address substitution\n"); fprintf(stdout, " -j disable first mac-ip\n"); fprintf(stdout, " -g default to grant\n"); fprintf(stdout, " -r read only\n"); fprintf(stdout, " -x duplex mode\n"); fprintf(stdout, " -z fix by broadcast\n"); fprintf(stdout, " -i hidden mode\n"); fprintf(stdout, " -o promiscuous mode\n"); fprintf(stdout, " -v be verbose\n"); fprintf(stdout, " -d[d[d]] don't fork [debug [more]]\n"); fprintf(stdout, " -h this help\n"); } int main(int argc, char *argv[]) { extern char *optarg; extern int optind; int n; if (getuid()) { fprintf(stderr, "error: must be run as root to init libnet\n"); exit(EXIT_FAILURE); } srand((unsigned int) getpid()); iface[0] = fmac[0] = pfmac[0] = pcapf[0] = log_name[0] = pid_name[0] = suser[0] = '\0'; strncpy(ethers_name, ETHERSFILE, PATH_MAX); strncpy(fmac, FAKEMAC, 18); ethers_update = ETHERSTO; fake_regen = FAKEREGEN; fake_num = FAKENUM; fake_time = FAKETIME; buffer_num = BUFSIZE; addr_nosubst = nofirst = grant = read_only = duplex = fixbc = hidden = promisc = debug = verbose = 0; all = good = grat = wgrat = zmac = zip = bad = bmac = bsip = btip = bnew = bgrat = mymac = fake = pfake = nzh = nbe = mis = 0; /* Still unused letters: q:w:y and all of figures ;) */ while ((n = getopt(argc, argv, "f:e:l:p:m:c:s:u:k:n:t:b:ajgrxziovdh")) != EOF) { switch (n) { case 'f': case 'e': strncpy(ethers_name, optarg, PATH_MAX); break; case 'l': strncpy(log_name, optarg, PATH_MAX); break; case 'p': strncpy(pid_name, optarg, PATH_MAX); break; case 'm': strncpy(fmac, optarg, 18); break; case 'c': strncpy(pcapf, optarg, PCAPFSIZ); break; case 's': strncpy(suser, optarg, MAXLOGNAME); break; case 'u': ethers_update = atoi(optarg); break; case 'k': fake_regen = atoi(optarg); break; case 'n': fake_num = atoi(optarg); break; case 't': fake_time = atoi(optarg); break; case 'b': buffer_num = atoi(optarg); break; case 'a': addr_nosubst++; break; case 'j': nofirst++; break; case 'g': grant++; break; case 'r': read_only++; break; case 'x': duplex++; break; case 'z': fixbc++; break; case 'i': hidden++; break; case 'o': promisc++; break; case 'v': verbose++; break; case 'd': debug++; break; case 'h': usage(argv[0]); help(); exit(EXIT_SUCCESS); default: usage(argv[0]); exit(EXIT_FAILURE); } } if (argc > optind) { strncpy(iface, argv[optind], IFNAMSIZ); } else { usage(argv[0]); exit(EXIT_FAILURE); } if (!log_name[0]) snprintf(log_name, PATH_MAX, "%s_%s.log", LOGNAME, iface); if (!pid_name[0]) snprintf(pid_name, PATH_MAX, "%s_%s.pid", PIDNAME, iface); if (!pcapf[0]) strncpy(pcapf, "arp", 3); else { pcapf[PCAPFSIZ-10] = '\0'; strncat(pcapf, " and arp", 8); } log_open(); if (verbose) { log_str(NOTICE, "Starting", argv[0]); } if (debug > 1) { fprintf(stderr, "PARAMS:"); for (n = 1; n < argc; n++) fprintf(stderr, " %s", argv[n]); fprintf(stderr, "\n"); fprintf(stderr, "PCAP FILTER: %s\n", pcapf); } if (!debug) daemonize(); pid_creat(); packet_init(iface); if (suser[0]) set_user(); sig_init(); while (1) packet_recv(); exit_ipguard(EXIT_SUCCESS); return 0; }