Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

fw.c

Go to the documentation of this file.
00001 /*
00002  * fw.c
00003  *
00004  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: fw.c,v 1.4 2005/02/14 20:45:04 dugsong Exp $
00007  */
00008 
00009 #include "config.h"
00010 
00011 #include <sys/types.h>
00012 
00013 #include <err.h>
00014 #include <errno.h>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 
00019 #include "dnet.h"
00020 #include "mod.h"
00021 
00022 static void
00023 usage(void)
00024 {
00025         fprintf(stderr, "Usage: dnet fw show\n"
00026                         "       dnet fw add|delete allow|block in|out "
00027             "<device>|any <proto> <src>[:<sport>[-<max>]] "
00028             "<dst>[:<dport>[-<max>]] [<type>[/<code>]]\n");
00029         exit(1);
00030 }
00031 
00032 static int
00033 print_rule(const struct fw_rule *fr, void *arg)
00034 {
00035         struct protoent *pr;
00036         char proto[16], sport[16], dport[16], typecode[16];
00037 
00038         if (fr->fw_proto == 0)
00039                 proto[0] = '\0';
00040         else if ((pr = getprotobynumber(fr->fw_proto)) == NULL)
00041                 snprintf(proto, sizeof(proto), "%d ", fr->fw_proto);
00042         else
00043                 snprintf(proto, sizeof(proto), "%s ", pr->p_name);
00044 
00045         sport[0] = dport[0] = typecode[0] = '\0';
00046         
00047         switch (fr->fw_proto) {
00048         case IP_PROTO_ICMP:
00049                 if (fr->fw_sport[1] && fr->fw_dport[1]) 
00050                         snprintf(typecode, sizeof(typecode), " %d/%d",
00051                             fr->fw_sport[0], fr->fw_dport[0]);
00052                 else if (fr->fw_sport[1])
00053                         snprintf(typecode, sizeof(typecode), " %d",
00054                             fr->fw_sport[0]);
00055                 break;
00056         case IP_PROTO_TCP:
00057         case IP_PROTO_UDP:
00058                 if (fr->fw_sport[0] == fr->fw_sport[1]) {
00059                         snprintf(sport, sizeof(sport), ":%d", fr->fw_sport[0]);
00060                 } else
00061                         snprintf(sport, sizeof(sport), ":%d-%d",
00062                             fr->fw_sport[0], fr->fw_sport[1]);
00063                 
00064                 if (fr->fw_dport[0] == fr->fw_dport[1]) {
00065                         snprintf(dport, sizeof(dport), ":%d", fr->fw_dport[0]);
00066                 } else
00067                         snprintf(dport, sizeof(dport), ":%d-%d",
00068                             fr->fw_dport[0], fr->fw_dport[1]);
00069                 break;
00070         }
00071         printf("%s %s %s %s%s%s %s%s%s\n",
00072             fr->fw_op == FW_OP_ALLOW ? "allow" : "block",
00073             fr->fw_dir == FW_DIR_IN ? "in" : "out",
00074             *fr->fw_device ? fr->fw_device : "any",
00075             proto,
00076             fr->fw_src.addr_type ? addr_ntoa(&fr->fw_src) : "",
00077             sport,
00078             fr->fw_dst.addr_type ? addr_ntoa(&fr->fw_dst) : "",
00079             dport,
00080             typecode);
00081 
00082         return (0);
00083 }
00084 
00085 static int
00086 arg_to_fr(int argc, char *argv[], struct fw_rule *fr)
00087 {
00088         struct protoent *pr;
00089         char *p;
00090 
00091         if (argc < 6) {
00092                 errno = EINVAL;
00093                 return (-1);
00094         }
00095         memset(fr, 0, sizeof(*fr));
00096 
00097         fr->fw_op = strcmp(argv[0], "allow") ? FW_OP_BLOCK : FW_OP_ALLOW;
00098         
00099         fr->fw_dir = strcmp(argv[1], "in") ? FW_DIR_OUT : FW_DIR_IN;
00100 
00101         if (strcmp(argv[2], "any") != 0)
00102                 strlcpy(fr->fw_device, argv[2], sizeof(fr->fw_device));
00103         
00104         if ((pr = getprotobyname(argv[3])) != NULL)
00105                 fr->fw_proto = pr->p_proto;
00106         else
00107                 fr->fw_proto = atoi(argv[3]);
00108 
00109         p = strtok(argv[4], ":");
00110         
00111         if (addr_aton(p, &fr->fw_src) < 0)
00112                 return (-1);
00113 
00114         if ((p = strtok(NULL, ":")) != NULL) {
00115                 fr->fw_sport[0] = (uint16_t)strtol(p, &p, 10);
00116                 if (*p == '-')
00117                         fr->fw_sport[1] = (uint16_t)strtol(p + 1, NULL, 10);
00118                 else
00119                         fr->fw_sport[1] = fr->fw_sport[0];
00120         } else if (fr->fw_proto == IP_PROTO_TCP || fr->fw_proto == IP_PROTO_UDP) {
00121                 fr->fw_sport[0] = 0;
00122                 fr->fw_sport[1] = TCP_PORT_MAX;
00123         }
00124         p = strtok(argv[5], ":");
00125         
00126         if (addr_aton(p, &fr->fw_dst) < 0)
00127                 return (-1);
00128 
00129         if ((p = strtok(NULL, ":")) != NULL) {
00130                 fr->fw_dport[0] = (uint16_t)strtol(p, &p, 10);
00131                 if (*p == '-')
00132                         fr->fw_dport[1] = (uint16_t)strtol(p + 1, NULL, 10);
00133                 else
00134                         fr->fw_dport[1] = fr->fw_dport[0];
00135         } else if (fr->fw_proto == IP_PROTO_TCP || fr->fw_proto == IP_PROTO_UDP) {
00136                 fr->fw_dport[0] = 0;
00137                 fr->fw_dport[1] = TCP_PORT_MAX;
00138         }       
00139         if (argc > 6) {
00140                 if (fr->fw_proto != IP_PROTO_ICMP &&
00141                     fr->fw_proto != IP_PROTO_IGMP) {
00142                         errno = EINVAL;
00143                         return (-1);
00144                 }
00145                 fr->fw_sport[0] = (uint16_t)strtol(argv[6], &p, 10);
00146                 fr->fw_sport[1] = 0xff;
00147                 if (*p == '/') {
00148                         fr->fw_dport[0] = (uint16_t)strtol(p + 1, NULL, 10);
00149                         fr->fw_dport[1] = 0xff;
00150                 }
00151         }
00152         return (0);
00153 }
00154 
00155 int
00156 fw_main(int argc, char *argv[])
00157 {
00158         struct fw_rule fr;
00159         fw_t *fw;
00160         
00161         if (argc < 2 || *(argv[1]) == '-')
00162                 usage();
00163 
00164         if ((fw = fw_open()) == NULL)
00165                 err(1, "fw_open");
00166         
00167         if (argc == 2 && strcmp(argv[1], "show") == 0) {
00168                 if (fw_loop(fw, print_rule, NULL) < 0)
00169                         err(1, "fw_loop");
00170         } else if (argc > 2 && strcmp(argv[1], "add") == 0) {
00171                 if (arg_to_fr(argc - 2, argv + 2, &fr) < 0)
00172                         err(1, "arg_to_fr");
00173                 printf("+ ");
00174                 print_rule(&fr, NULL);
00175                 if (fw_add(fw, &fr) < 0)
00176                         err(1, "fw_add");
00177         } else if (argc > 2 && strcmp(argv[1], "delete") == 0) {
00178                 if (arg_to_fr(argc - 2, argv + 2, &fr) < 0)
00179                         err(1, "arg_to_fr");
00180                 printf("- ");
00181                 print_rule(&fr, NULL);
00182                 if (fw_delete(fw, &fr) < 0)
00183                         err(1, "fw_delete");
00184         } else
00185                 usage();
00186         
00187         fw_close(fw);
00188 
00189         exit(0);
00190 }
00191 
00192 struct mod mod_fw = {
00193         "fw",
00194         MOD_TYPE_KERN,
00195         fw_main
00196 };

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2