/* * Copyright (c) 1993 Daniel Boulet * * Redistribution and use in source forms, with and without modification, * are permitted provided that this entire comment appears intact. * * Redistribution in binary form may occur without any restrictions. * Obviously, it would be nice if you gave credit where credit is due * but requiring it would be too onerous. * * This software is provided ``AS IS'' without any warranties of any kind. * */ /* * Linux port (c) 1994 Bob Beck * * Redistribution and use in source forms, with and without modification, * are permitted provided that this entire comment appears intact. * * This software is provided ``AS IS'' without any warranties of any kind. * */ /* * Drastically cleaned up: Alan Cox Dec 1st 1994. */ /* * Command line interface for IP firewall facility */ /* $Header: /usr/brule/dept/beck/ipfirewall/RCS/ipfirewall.c,v 1.1 1994/07/28 00:06:11 beck Exp $ */ /* $Log: ipfirewall.c,v $ * Revision 1.1 1994/07/28 00:06:11 beck * Initial revision * */ #include #ifdef _LINUX_TYPES_H /* Yep. it's Linux */ #ifndef LINUX #define LINUX #endif #endif #include #define IPFIREWALL #include #include #include #include #include #ifndef LINUX #include #else #include /* Until it gets into stdinc */ #endif #include #include #include #include #include #ifdef LINUX #include #define IPVERSION 4 #endif typedef enum { IPF_BLOCKING = 0, IPF_FORWARDING = 1, IPF_ACCOUNTING = 2 } ipf_kind; static char *ipf_names[3] = {"blocking", "forwarding", "accounting"}; static long ipf_addfunc[3] = {IP_FW_ADD_BLK, IP_FW_ADD_FWD, IP_ACCT_ADD}; static long ipf_delfunc[3] = {IP_FW_DEL_BLK, IP_FW_DEL_FWD, IP_ACCT_DEL}; void show_usage () { fprintf (stderr, "ipfirewall: {\n"); fprintf (stderr, " list ...\n"); fprintf (stderr, " |\n"); fprintf (stderr, " flush\n"); fprintf (stderr, " |\n"); fprintf (stderr, " checkb[locking] ...\n"); fprintf (stderr, " |\n"); fprintf (stderr, " checkf[orwarding] ...\n"); fprintf (stderr, " |\n"); fprintf (stderr, " addb[lock] ...\n"); fprintf (stderr, " |\n"); fprintf (stderr, " addf[orwarding] ...\n"); fprintf (stderr, " }\n"); fprintf (stderr, " adda[ccounting] ...\n"); fprintf (stderr, " }\n"); } /* * I'm not sure that this is practical ... */ void show_help () { abort (); fprintf (stderr, "ipfirewall: {\n"); fprintf (stderr, " list\n"); fprintf (stderr, " |\n"); fprintf (stderr, " flush\n"); fprintf (stderr, " |\n"); fprintf (stderr, " checkb[locking] \n"); fprintf (stderr, " |\n"); fprintf (stderr, " checkf[orwarding] \n"); fprintf (stderr, " |\n"); fprintf (stderr, " addb[lock] \n"); fprintf (stderr, " |\n"); fprintf (stderr, " addf[orwarding] \n"); fprintf (stderr, " }\n"); fprintf (stderr, " adda[ccounting] \n"); fprintf (stderr, " }\n"); fprintf (stderr, "where\n"); fprintf (stderr, " ::= : /* for TCP or UDP */\n"); fprintf (stderr, " ::= /* for ICMP */\n"); fprintf (stderr, " ::= ... | \n"); fprintf (stderr, " ::= | \n"); fprintf (stderr, " ::= an integer in the range 1-65535\n"); fprintf (stderr, " ::= an integer in the range 0-255\n"); } static char * fmtip (u_long uaddr) { static char tbuf[100]; sprintf (tbuf, "%d.%d.%d.%d", ((char *) &uaddr)[0] & 0xff, ((char *) &uaddr)[1] & 0xff, ((char *) &uaddr)[2] & 0xff, ((char *) &uaddr)[3] & 0xff); return (&tbuf[0]); } static void print_ports (int cnt, int range, u_short * ports) { int ix; char *pad; if (range) { if (cnt < 2) { fprintf (stderr, "ipfirewall: range flag set but only %d ports\n", cnt); abort (); } printf ("%d:%d", ports[0], ports[1]); ix = 2; pad = " "; } else { ix = 0; pad = ""; } while (ix < cnt) { printf ("%s%d", pad, ports[ix]); pad = " "; ix += 1; } } int do_setsockopt (char *what, int fd, int proto, int cmd, void *data, int datalen, int ok_errno) { char *cmdname; switch (cmd) { case IP_FW_FLUSH: cmdname = "IP_FW_FLUSH"; break; case IP_FW_CHK_BLK: cmdname = "IP_FW_CHK_BLK"; break; case IP_FW_CHK_FWD: cmdname = "IP_FW_CHK_FWD"; break; case IP_FW_ADD_BLK: cmdname = "IP_FW_ADD_BLK"; break; case IP_FW_ADD_FWD: cmdname = "IP_FW_ADD_FWD"; break; case IP_FW_DEL_BLK: cmdname = "IP_FW_DEL_BLK"; break; case IP_FW_DEL_FWD: cmdname = "IP_FW_DEL_FWD"; break; case IP_ACCT_ADD: cmdname = "IP_ACCT_ADD"; break; case IP_ACCT_DEL: cmdname = "IP_ACCT_DEL"; break; default: fprintf (stderr, "ipfirewall: unknown command (%d) passed to do_setsockopt - bye!\n", cmd); abort (); } if (fd < 0) { printf ("setsockopt(%d, %d, %s, 0x%x, 0x%x)\n", fd, proto, cmdname, (int) data, datalen); if (cmd == IP_FW_CHK_BLK || cmd == IP_FW_CHK_FWD) { struct iphdr *ip = (struct iphdr *) data; struct tcphdr *tcp = (struct tcphdr *) &(((int *) ip)[ip->ihl]); if (ip->ihl != sizeof (struct iphdr) / sizeof (int)) { fprintf (stderr, "ip header length %d, should be %d\n", ip->ihl, sizeof (struct iphdr) / sizeof (int)); } if (ip->protocol != IPPROTO_TCP && ip->protocol != IPPROTO_UDP) abort (); printf ("data = struct iphdr : struct %shdr {\n", ip->protocol == IPPROTO_TCP ? "tcp" : "udp"); printf ("\tsrc=%s ", fmtip (ip->saddr)); printf ("%d\n", ntohs (tcp->th_sport)); printf ("\tdst=%s ", fmtip (ip->daddr)); printf ("%d\n", ntohs (tcp->th_dport)); printf ("}\n"); } else if (cmd == IP_FW_ADD_BLK || cmd == IP_FW_ADD_FWD || cmd == IP_ACCT_ADD) { struct ip_fw *fp = (struct ip_fw *) data; int fmt_ports; printf ("data = struct ip_fw {\n"); if (fp->flags & IP_FW_F_ACCEPT) { printf ("\taccept "); } else { printf ("\tdeny "); } switch (fp->flags & IP_FW_F_KIND) { case IP_FW_F_ALL: printf ("\tuniversal\n"); fmt_ports = 0; break; case IP_FW_F_TCP: printf ("tcp\n"); fmt_ports = 1; break; case IP_FW_F_UDP: printf ("udp\n"); fmt_ports = 1; break; case IP_FW_F_ICMP: printf ("icmp\n"); fmt_ports = 0; break; } printf ("\tsrc=%s:", fmtip (fp->src.s_addr)); printf ("%s ", fmtip (fp->src_mask.s_addr)); if (fmt_ports) { print_ports (fp->n_src_p, fp->flags & IP_FW_F_SRNG, &fp->ports[0]); } else if (fp->flags & (IP_FW_F_SRNG | IP_FW_F_DRNG)) { abort (); } else if (fp->n_src_p > 0 || fp->n_dst_p > 0) { abort (); } printf ("\n"); printf ("\tdst=%s:", fmtip (fp->dst.s_addr)); printf ("%s ", fmtip (fp->dst_mask.s_addr)); if (fmt_ports) { print_ports (fp->n_dst_p, fp->flags & IP_FW_F_DRNG, &fp->ports[fp->n_src_p]); } printf ("\n"); printf ("}\n"); } } else { if (setsockopt (fd, proto, cmd, data, datalen) < 0) { if (errno == ok_errno) { return (errno); } perror ("ipfirewall: setsockopt"); exit (1); } } return (0); } void show_parms (char **argv) { while (*argv) { printf ("%s ", *argv++); } } int get_protocol (char *arg, void (*cmd_usage) (ipf_kind), ipf_kind kind) { if (arg == NULL) { fprintf (stderr, "ipfirewall: missing protocol name\n"); } else if (strcmp (arg, "tcp") == 0) { return (IP_FW_F_TCP); } else if (strcmp (arg, "udp") == 0) { return (IP_FW_F_UDP); } else if (strcmp (arg, "icmp") == 0) { return (IP_FW_F_ICMP); } else if (strcmp (arg, "all") == 0) { return (IP_FW_F_ALL); } else { fprintf (stderr, "illegal protocol name \"%s\"\n", arg); } (*cmd_usage) (kind); exit (1); return (0); } void get_ipaddr (char *arg, struct in_addr *addr, struct in_addr *mask, void (*usage) (ipf_kind), ipf_kind kind) { char *p, *tbuf; int period_cnt, non_digit; struct hostent *hptr; if (arg == NULL) { fprintf (stderr, "ipfirewall: missing ip address\n"); exit (1); } period_cnt = 0; non_digit = 0; for (p = arg; *p != '\0' && *p != '/' && *p != ':'; p += 1) { if (*p == '.') { if (p > arg && *(p - 1) == '.') { fprintf (stderr, "ipfirewall: two periods in a row in ip address (%s)\n", arg); exit (1); } period_cnt += 1; } else if (!isdigit (*p)) { non_digit = 1; } } tbuf = malloc (p - arg + 1); strncpy (tbuf, arg, p - arg); tbuf[p - arg] = '\0'; if (non_digit) { hptr = gethostbyname (tbuf); if (hptr == NULL) { fprintf (stderr, "ipfirewall: unknown host \"%s\"\n", tbuf); exit (1); } if (hptr->h_length != sizeof (struct in_addr)) { fprintf (stderr, "ipfirewall: hostentry addr length = %d, expected %d (i.e. sizeof(struct in_addr))\n", hptr->h_length, sizeof (struct in_addr)); exit (1); } bcopy (hptr->h_addr, addr, sizeof (struct in_addr)); } else { if (period_cnt == 3) { int a1, a2, a3, a4, matched; if ((matched = sscanf (tbuf, "%d.%d.%d.%d", &a1, &a2, &a3, &a4)) != 4) { fprintf (stderr, "ipfirewall: Only %d fields matched in IP address!\n", matched); /* should this exit here? or catch it later? -BB */ } if (a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) { fprintf (stderr, "ipfirewall: number too large in ip address (%s)\n", arg); exit (1); } ((char *) addr)[0] = a1; ((char *) addr)[1] = a2; ((char *) addr)[2] = a3; ((char *) addr)[3] = a4; } else if (strcmp (tbuf, "0") == 0) { ((char *) addr)[0] = 0; ((char *) addr)[1] = 0; ((char *) addr)[2] = 0; ((char *) addr)[3] = 0; } else { fprintf (stderr, "ipfirewall: incorrect ip address format \"%s\" (expected 3 periods)\n", tbuf); exit (1); } } free (tbuf); if (mask == NULL) { if (*p != '\0') { fprintf (stderr, "ipfirewall: ip netmask not allowed here (%s)\n", (char *) addr); exit (1); } } else { if (*p == ':') { get_ipaddr (p + 1, mask, NULL, usage, kind); } else if (*p == '/') { int bits; char *end; p += 1; if (*p == '\0') { fprintf (stderr, "ipfirewall: missing mask value (%s)\n", arg); exit (1); } else if (!isdigit (*p)) { fprintf (stderr, "ipfirewall: non-numeric mask value (%s)\n", arg); exit (1); } bits = strtol (p, &end, 10); if (*end != '\0') { fprintf (stderr, "ipfirewall: junk after mask (%s)\n", arg); exit (1); } if (bits < 0 || bits > sizeof (u_long) * 8) { fprintf (stderr, "ipfirewall: mask length value out of range (%s)\n", arg); exit (1); } if (bits == 0) { /* left shifts of 32 aren't defined */ mask->s_addr = 0; } else { ((char *) mask)[0] = (-1 << (32 - bits)) >> 24; ((char *) mask)[1] = (-1 << (32 - bits)) >> 16; ((char *) mask)[2] = (-1 << (32 - bits)) >> 8; ((char *) mask)[3] = (-1 << (32 - bits)) >> 0; } } else if (*p == '\0') { mask->s_addr = 0xffffffff; } else { fprintf (stderr, "ipfirewall: junk after ip address (%s)\n", arg); exit (1); } /* * Mask off any bits in the address that are zero in the mask. * This allows the user to describe a network by specifying * any host on the network masked with the network's netmask. */ addr->s_addr &= mask->s_addr; } } u_short get_one_port (char *arg, void (*usage) (ipf_kind), ipf_kind kind, const char *proto_name) { int slen = strlen (arg); if (slen > 0 && strspn (arg, "0123456789") == slen) { int port; char *end; port = strtol (arg, &end, 10); if (*end != '\0') { fprintf (stderr, "ipfirewall: illegal port number (%s)\n", arg); exit (1); } if (port <= 0 || port > 65535) { fprintf (stderr, "ipfirewall: port number out of range (%d)\n", port); exit (1); } return (port); } else { struct servent *sptr; sptr = getservbyname (arg, proto_name); if (sptr == NULL) { fprintf (stderr, "ipfirewall: unknown %s service \"%s\"\n", proto_name, arg); exit (1); } return (ntohs (sptr->s_port)); } } int get_ports (char ***argv_ptr, u_short * ports, int min_ports, int max_ports, void (*usage) (ipf_kind), ipf_kind kind, const char *proto_name) { int ix; char *arg; int sign; ix = 0; sign = 1; while ((arg = **argv_ptr) != NULL && strcmp (arg, "from") != 0 && strcmp (arg, "to") != 0) { char *p; /* * Check that we havn't found too many port numbers. * We do this here instead of with another condition on the while loop * so that the caller can assume that the next parameter is NOT a port number. */ if (ix >= max_ports) { fprintf (stderr, "ipfirewall: too many port numbers (max %d, got at least %d, next parm=\"%s\")\n", max_ports, max_ports + 1, arg); exit (1); } if ((p = strchr (arg, ':')) == NULL) { ports[ix++] = get_one_port (arg, usage, kind, proto_name); } else { if (ix > 0) { fprintf (stderr, "ipfirewall: port ranges are only allowed for the first port value pair (%s)\n", arg); exit (1); } if (max_ports > 1) { char *tbuf; tbuf = malloc ((p - arg) + 1); strncpy (tbuf, arg, p - arg); tbuf[p - arg] = '\0'; ports[ix++] = get_one_port (tbuf, usage, kind, proto_name); ports[ix++] = get_one_port (p + 1, usage, kind, proto_name); sign = -1; } else { fprintf (stderr, "ipfirewall: port range not allowed here (%s)\n", arg); exit (1); } } *argv_ptr += 1; } if (ix < min_ports) { if (min_ports == 1) { fprintf (stderr, "ipfirewall: missing port number%s\n", max_ports == 1 ? "" : "(s)"); } else { fprintf (stderr, "ipfirewall: not enough port numbers (expected %d, got %d)\n", min_ports, ix); } exit (1); } return (sign * ix); } void check_usage (ipf_kind kind) { fprintf (stderr, "usage: ipfirewall check%s ...\n", ipf_names[kind]); } void check (ipf_kind kind, int socket_fd, char **argv) { int protocol; struct iphdr *packet; char *proto_name; packet = (struct iphdr *) malloc (sizeof (struct iphdr) + sizeof (struct tcphdr)); packet->version = IPVERSION; packet->ihl = sizeof (struct iphdr) / sizeof (int); printf ("check%s ", kind == IPF_BLOCKING ? "blocking" : "forwarding"); show_parms (argv); printf ("\n"); proto_name = *argv++; protocol = get_protocol (proto_name, check_usage, kind); switch (protocol) { case IP_FW_F_TCP: packet->protocol = IPPROTO_TCP; break; case IP_FW_F_UDP: packet->protocol = IPPROTO_UDP; break; default: fprintf (stderr, "ipfirewall: can only check TCP or UDP packets\n"); break; } if (*argv == NULL) { fprintf (stderr, "ipfirewall: missing \"from\" from keyword\n"); exit (1); } if (strcmp (*argv, "from") == 0) { argv += 1; get_ipaddr (*argv++, (struct in_addr *) &packet->saddr, NULL, check_usage, kind); if (protocol == IP_FW_F_TCP || protocol == IP_FW_F_UDP) { get_ports (&argv, &((struct tcphdr *) (&packet[1]))->th_sport, 1, 1, check_usage, kind, proto_name); ((struct tcphdr *) (&packet[1]))->th_sport = htons ( ((struct tcphdr *) (&packet[1]))->th_sport ); } } else { fprintf (stderr, "ipfirewall: expected \"from\" keyword, got \"%s\"\n", *argv); exit (1); } if (*argv == NULL) { fprintf (stderr, "ipfirewall: missing \"to\" from keyword\n"); exit (1); } if (strcmp (*argv, "to") == 0) { argv += 1; get_ipaddr (*argv++, (struct in_addr *) &packet->daddr, NULL, check_usage, kind); if (protocol == IP_FW_F_TCP || protocol == IP_FW_F_UDP) { get_ports (&argv, &((struct tcphdr *) (&packet[1]))->th_dport, 1, 1, check_usage, kind, proto_name); ((struct tcphdr *) (&packet[1]))->th_dport = htons ( ((struct tcphdr *) (&packet[1]))->th_dport ); } } else { fprintf (stderr, "ipfirewall: expected \"to\" keyword, got \"%s\"\n", *argv); exit (1); } if (*argv == NULL) { if (do_setsockopt (kind == IPF_BLOCKING ? "checkblocking" : "checkforwarding", socket_fd, IPPROTO_IP, kind == IPF_BLOCKING ? IP_FW_CHK_BLK : IP_FW_CHK_FWD, packet, sizeof (struct iphdr) + sizeof (struct tcphdr), EACCES ) == 0 ) { printf ("packet accepted by %s firewall\n", kind == IPF_BLOCKING ? "blocking" : "forwarding"); } else { printf ("packet rejected by %s firewall\n", kind == IPF_BLOCKING ? "blocking" : "forwarding"); } return; } else { fprintf (stderr, "ipfirewall: extra parameters at end of command ("); show_parms (argv); fprintf (stderr, ")\n"); exit (1); } } void add_usage (ipf_kind kind) { fprintf (stderr, "usage: ipfirewall add%s ...\n", ipf_names[kind]); } void add (ipf_kind kind, int socket_fd, char **argv) { int protocol, accept_firewall, src_range, dst_range; struct ip_fw firewall; char *proto_name; printf ("add%s ", ipf_names[kind]); show_parms (argv); printf ("\n"); if (kind != IPF_ACCOUNTING) { if (*argv == NULL) { fprintf (stderr, "ipfirewall: missing \"accept\" or \"deny\" keyword\n"); exit (1); } if (strcmp (*argv, "deny") == 0) { accept_firewall = 0; } else if (strcmp (*argv, "accept") == 0) { accept_firewall = IP_FW_F_ACCEPT; } else { fprintf (stderr, "ipfirewall: expected \"accept\" or \"deny\", got \"%s\"\n", *argv); exit (1); } argv += 1; } else accept_firewall = 0; proto_name = *argv++; protocol = get_protocol (proto_name, add_usage, kind); if (*argv == NULL) { fprintf (stderr, "ipfirewall: missing \"from\" keyword\n"); exit (1); } if (strcmp (*argv, "from") == 0) { argv++; get_ipaddr (*argv++, &firewall.src, &firewall.src_mask, add_usage, kind); if (protocol == IP_FW_F_TCP || protocol == IP_FW_F_UDP) { int cnt; cnt = get_ports (&argv, &firewall.ports[0], 0, IP_FW_MAX_PORTS, add_usage, kind, proto_name); if (cnt < 0) { src_range = IP_FW_F_SRNG; cnt = -cnt; } else { src_range = 0; } firewall.n_src_p = cnt; } else { firewall.n_src_p = 0; src_range = 0; } } else { fprintf (stderr, "ipfirewall: expected \"from\", got \"%s\"\n", *argv); exit (1); } if (*argv == NULL) { fprintf (stderr, "ipfirewall: missing \"to\" keyword\n"); exit (1); } if (strcmp (*argv, "to") == 0) { argv++; get_ipaddr (*argv++, &firewall.dst, &firewall.dst_mask, add_usage, kind); if (protocol == IP_FW_F_TCP || protocol == IP_FW_F_UDP) { int cnt; cnt = get_ports (&argv, &firewall.ports[firewall.n_src_p], 0, IP_FW_MAX_PORTS - firewall.n_src_p, add_usage, kind, proto_name); if (cnt < 0) { dst_range = IP_FW_F_DRNG; cnt = -cnt; } else { dst_range = 0; } firewall.n_dst_p = cnt; } else { firewall.n_dst_p = 0; dst_range = 0; } } else { fprintf (stderr, "ipfirewall: expected \"to\", got \"%s\"\n", *argv); exit (1); } if (*argv == NULL) { firewall.flags = protocol | accept_firewall | src_range | dst_range; (void) do_setsockopt (ipf_names[kind], socket_fd, IPPROTO_IP, ipf_addfunc[kind], &firewall, sizeof (firewall), 0 ); } else { fprintf (stderr, "ipfirewall: extra parameters at end of command ("); show_parms (argv); fprintf (stderr, ")\n"); exit (1); } } static int count_mask(unsigned long mask) { int ct; for(ct=0;(mask&0x80000000);ct++) mask<<=1; return ct; } void list_file(char *path, int acct) { FILE * f=fopen(path,"r"); char buf[256]; unsigned long sa,da,sm,dm; unsigned short nsp, ndp; unsigned long npkt, nbyt; unsigned int ports[10]; int flags; if(f==NULL) { perror(path); exit(1); } fgets(buf,255,f); /* Title */ while(fgets(buf,255,f)) { unsigned int *pp=&ports[0]; sscanf(buf,"%lX/%lX->%lX/%lX %X %u %u %lu %lu %u %u %u %u %u %u %u %u %u %u", &sa,&sm,&da,&dm,&flags, &nsp, &ndp, &npkt, &nbyt, &ports[0],&ports[1],&ports[2],&ports[3],&ports[4], &ports[5],&ports[6],&ports[7],&ports[8],&ports[9]); if(!acct) { if(flags&IP_FW_F_ACCEPT) printf("Accept "); else printf("Reject "); } else printf("%lu packets (%lu bytes) matching: ", npkt,nbyt); if(flags&IP_FW_F_ALL) printf("all from "); else if(flags&IP_FW_F_TCP) printf("TCP from "); else if(flags&IP_FW_F_UDP) printf("UDP from "); else printf("ICMP from "); if(sm==0) printf("anywhere to "); else printf("%s/%d to ",fmtip(htonl(sa)),count_mask(sm)); if(dm==0) printf("anywhere"); else printf("%s/%d", fmtip(htonl(da)),count_mask(dm)); if(flags&(IP_FW_F_TCP|IP_FW_F_UDP)) { printf(" Ports: "); if(nsp==0) printf("any "); else { if(flags&IP_FW_F_SRNG) { printf("%u-%u ",pp[0],pp[1]); pp+=2; nsp-=2; } while(nsp-->0) printf("%u ",*pp++); } printf("to"); if(ndp==0) printf(" any"); else { if(flags&IP_FW_F_DRNG) { printf(" %u-%u",pp[0],pp[1]); pp+=2; } while(ndp-->0) printf(" %u",*pp++); } } printf("\n"); } fclose(f); } void list(int socket_fd, char **argv) { if(*argv==NULL && **argv) { fprintf(stderr,"blocking, forwarding or accounting keyword expected.\n"); exit(1); } if(strncmp(*argv,"blocking",strlen(*argv))==0) { list_file("/proc/net/ip_block",0); return; } if(strncmp(*argv,"forwarding",strlen(*argv))==0) { list_file("/proc/net/ip_forward",0); return; } if(strncmp(*argv,"accounting",strlen(*argv))==0) { list_file("/proc/net/ip_acct",1); return; } fprintf(stderr,"Found '%s': 'blocking', 'forwarding' or 'accounting' keyword expected.\n",*argv); exit(1); } void main (argc, argv) int argc; char **argv; { int socket_fd; socket_fd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); if (socket_fd < 0) { perror ("ipfirewall:"); exit(1); } if (argc == 1) { show_usage (); exit (1); } if (strcmp (argv[1], "list") == 0) { list(socket_fd, &argv[2]); } else if (strcmp (argv[1], "flush") == 0) { #ifdef LINUX /* Same kludge as above, see above ranting and griping -BB */ unsigned long fred = 1; (void) do_setsockopt (argv[1], socket_fd, IPPROTO_IP, IP_FW_FLUSH, &fred, sizeof (unsigned long), 0); #else (void) do_setsockopt (argv[1], socket_fd, IPPROTO_IP, IP_FLUSH_FIREWALLS, NULL, 0, 0); #endif } else if (strlen (argv[1]) >= strlen ("checkb") && strncmp (argv[1], "checkblocking", strlen (argv[1])) == 0) { check (IPF_BLOCKING, socket_fd, &argv[2]); } else if (strlen (argv[1]) >= strlen ("checkf") && strncmp (argv[1], "checkforwarding", strlen (argv[1])) == 0) { check (IPF_FORWARDING, socket_fd, &argv[2]); } else if (strlen (argv[1]) >= strlen ("addb") && strncmp (argv[1], "addblocking", strlen (argv[1])) == 0) { add (IPF_BLOCKING, socket_fd, &argv[2]); } else if (strlen (argv[1]) >= strlen ("addf") && strncmp (argv[1], "addforwarding", strlen (argv[1])) == 0) { add (IPF_FORWARDING, socket_fd, &argv[2]); } else if (strlen (argv[1]) >= strlen ("adda") && strncmp (argv[1], "addaccounting", strlen (argv[1])) == 0) { add (IPF_ACCOUNTING, socket_fd, &argv[2]); } else { fprintf (stderr, "ipfirewall: unknown command \"%s\"\n", argv[1]); show_usage (); exit (1); } exit (0); }