Annotation of embedaddon/mpd/src/nat.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * nat.c
        !             4:  *
        !             5:  * Written by Alexander Motin <mav@FreeBSD.org>
        !             6:  */
        !             7: 
        !             8: #include "ppp.h"
        !             9: #include "nat.h"
        !            10: #include "iface.h"
        !            11: #include "netgraph.h"
        !            12: #include "util.h"
        !            13: 
        !            14: /*
        !            15:  * DEFINITIONS
        !            16:  */
        !            17: 
        !            18: /* Set menu options */
        !            19: 
        !            20:   enum {
        !            21:     SET_ADDR,
        !            22:     SET_TARGET,
        !            23:     SET_ENABLE,
        !            24:     SET_DISABLE,
        !            25:     SET_REDIRECT_PORT,
        !            26:     SET_REDIRECT_ADDR,
        !            27:     SET_REDIRECT_PROTO
        !            28:   };
        !            29: 
        !            30: static int     NatSetCommand(Context ctx, int ac, char *av[], void *arg);
        !            31:   
        !            32: /*
        !            33:  * GLOBAL VARIABLES
        !            34:  */
        !            35: 
        !            36:   const struct cmdtab NatSetCmds[] = {
        !            37:     { "address {addr}",                "Set alias address",
        !            38:        NatSetCommand, AdmitBund, 2, (void *) SET_ADDR },
        !            39:     { "target {addr}",         "Set target address",
        !            40:        NatSetCommand, AdmitBund, 2, (void *) SET_TARGET },
        !            41: #ifdef NG_NAT_DESC_LENGTH
        !            42:     { "red-port {proto} {alias_addr} {alias_port} {local_addr} {local_port} [{remote_addr} {remote_port}]",    "Redirect port",
        !            43:        NatSetCommand, AdmitBund, 2, (void *) SET_REDIRECT_PORT },
        !            44:     { "red-addr {alias_addr} {local_addr}",    "Redirect address",
        !            45:        NatSetCommand, AdmitBund, 2, (void *) SET_REDIRECT_ADDR },
        !            46:     { "red-proto {proto} {alias-addr} {local_addr} [{remote-addr}]",   "Redirect protocol",
        !            47:        NatSetCommand, AdmitBund, 2, (void *) SET_REDIRECT_PROTO },
        !            48: #endif
        !            49:     { "enable [opt ...]",              "Enable option",
        !            50:        NatSetCommand, AdmitBund, 2, (void *) SET_ENABLE },
        !            51:     { "disable [opt ...]",             "Disable option",
        !            52:        NatSetCommand, AdmitBund, 2, (void *) SET_DISABLE },
        !            53:     { NULL },
        !            54:   };
        !            55: 
        !            56: /*
        !            57:  * INTERNAL VARIABLES
        !            58:  */
        !            59: 
        !            60:   static const struct confinfo gConfList[] = {
        !            61:     { 0,       NAT_CONF_LOG,                   "log"           },
        !            62:     { 0,       NAT_CONF_INCOMING,              "incoming"      },
        !            63:     { 0,       NAT_CONF_SAME_PORTS,            "same-ports"    },
        !            64:     { 0,       NAT_CONF_UNREG_ONLY,            "unreg-only"    },
        !            65:     { 0,       0,                              NULL            },
        !            66:   };
        !            67: 
        !            68: /*
        !            69:  * NatInit()
        !            70:  */
        !            71: 
        !            72: void
        !            73: NatInit(Bund b)
        !            74: {
        !            75:   NatState     const nat = &b->iface.nat;
        !            76: 
        !            77:   /* Default configuration */
        !            78:   u_addrclear(&nat->alias_addr);
        !            79:   u_addrclear(&nat->target_addr);
        !            80:   Disable(&nat->options, NAT_CONF_LOG);
        !            81:   Enable(&nat->options, NAT_CONF_INCOMING);
        !            82:   Enable(&nat->options, NAT_CONF_SAME_PORTS);
        !            83:   Disable(&nat->options, NAT_CONF_UNREG_ONLY);
        !            84: #ifdef NG_NAT_DESC_LENGTH
        !            85:   bzero(nat->nrpt, sizeof(nat->nrpt));
        !            86:   bzero(nat->nrpt_id, sizeof(nat->nrpt_id));
        !            87:   bzero(nat->nrad, sizeof(nat->nrad));
        !            88:   bzero(nat->nrad_id, sizeof(nat->nrad_id));
        !            89:   bzero(nat->nrpr, sizeof(nat->nrpr));
        !            90:   bzero(nat->nrpr_id, sizeof(nat->nrpr_id));
        !            91: #endif
        !            92: }
        !            93: 
        !            94: 
        !            95: /*
        !            96:  * NatSetCommand()
        !            97:  */
        !            98: 
        !            99: static int
        !           100: NatSetCommand(Context ctx, int ac, char *av[], void *arg)
        !           101: {
        !           102:   NatState     const nat = &ctx->bund->iface.nat;
        !           103: 
        !           104:   if (ac == 0)
        !           105:     return(-1);
        !           106:   switch ((intptr_t)arg) {
        !           107:     case SET_TARGET:
        !           108: #ifndef NG_NAT_LOG
        !           109:        Error("Target address setting is unsupported by current kernel");
        !           110: #endif
        !           111:     /* FALL */
        !           112:     case SET_ADDR:
        !           113:       {
        !           114:        struct u_addr   addr;
        !           115: 
        !           116:        /* Parse */
        !           117:        if (ac != 1)
        !           118:          return(-1);
        !           119:        if (!ParseAddr(av[0], &addr, ALLOW_IPV4))
        !           120:          Error("bad IP address \"%s\"", av[0]);
        !           121: 
        !           122:        /* OK */
        !           123:        if ((intptr_t)arg == SET_ADDR) {
        !           124:            nat->alias_addr = addr;
        !           125:        } else {
        !           126:            nat->target_addr = addr;
        !           127:        }
        !           128:       }
        !           129:       break;
        !           130: 
        !           131: #ifdef NG_NAT_DESC_LENGTH
        !           132:     case SET_REDIRECT_PORT:
        !           133:       {
        !           134:        struct protoent *proto;
        !           135:        struct in_addr  l_addr, a_addr, r_addr;
        !           136:        int lp, ap, rp = 0, k;
        !           137: 
        !           138:        /* Parse */
        !           139:        if (ac != 5 && ac != 7)
        !           140:          return(-1);
        !           141:        if ((proto = getprotobyname(av[0])) == 0)
        !           142:          Error("bad PROTO name \"%s\"", av[0]);
        !           143:        if (!inet_aton (av[1], &a_addr))
        !           144:          Error("bad alias IP address \"%s\"", av[1]);
        !           145:        ap = atoi(av[2]);
        !           146:        if (ap <= 0 || ap > 65535)
        !           147:          Error("Incorrect alias port number \"%s\"", av[2]);
        !           148:        if (!inet_aton (av[3], &l_addr))
        !           149:          Error("bad local IP address \"%s\"", av[3]);
        !           150:        lp = atoi(av[4]);
        !           151:        if (lp <= 0 || lp > 65535)
        !           152:          Error("Incorrect local port number \"%s\"", av[4]);
        !           153:        if (ac == 7) {
        !           154:          if (!inet_aton (av[5], &r_addr))
        !           155:            Error("bad remote IP address \"%s\"", av[5]);
        !           156:          rp = atoi(av[6]);
        !           157:          if (rp <= 0 || rp > 65535)
        !           158:            Error("Incorrect remote port number \"%s\"", av[6]);
        !           159:        }
        !           160:        /* OK */
        !           161:        for (k=0;k<NM_PORT;k++) {
        !           162:          if (nat->nrpt_id[k] == 0) {
        !           163:            memcpy(&nat->nrpt[k].local_addr, &l_addr, sizeof(struct in_addr));
        !           164:            memcpy(&nat->nrpt[k].alias_addr, &a_addr, sizeof(struct in_addr));
        !           165:            nat->nrpt[k].local_port = lp;
        !           166:            nat->nrpt[k].alias_port = ap;
        !           167:            if (ac == 7) {
        !           168:              memcpy(&nat->nrpt[k].remote_addr, &r_addr, sizeof(struct in_addr));
        !           169:              nat->nrpt[k].remote_port = rp;
        !           170:            }
        !           171:            nat->nrpt[k].proto = (uint8_t)proto->p_proto;
        !           172:            snprintf(nat->nrpt[k].description, NG_NAT_DESC_LENGTH, "nat-port-%d", k);
        !           173:            nat->nrpt_id[k] = 1;
        !           174:            break;
        !           175:          }
        !           176:        }
        !           177:        if (k == NM_PORT)
        !           178:          Error("max number of redirect-port \"%d\" reached", NM_PORT);
        !           179:       }
        !           180:       break;
        !           181: 
        !           182:     case SET_REDIRECT_ADDR:
        !           183:       {
        !           184:        struct in_addr  l_addr, a_addr;
        !           185:        int k;
        !           186: 
        !           187:        /* Parse */
        !           188:        if (ac != 2)
        !           189:          return(-1);
        !           190:        if (!inet_aton (av[0], &a_addr))
        !           191:          Error("bad alias IP address \"%s\"", av[0]);
        !           192:        if (!inet_aton (av[1], &l_addr))
        !           193:          Error("bad local IP address \"%s\"", av[1]);
        !           194: 
        !           195:        /* OK */
        !           196:        for (k=0;k<NM_ADDR;k++) {
        !           197:          if (nat->nrad_id[k] == 0) {
        !           198:            memcpy(&nat->nrad[k].local_addr, &l_addr, sizeof(struct in_addr));
        !           199:            memcpy(&nat->nrad[k].alias_addr, &a_addr, sizeof(struct in_addr));
        !           200:            snprintf(nat->nrad[k].description, NG_NAT_DESC_LENGTH, "nat-addr-%d", k);
        !           201:            nat->nrad_id[k] = 1;
        !           202:            break;
        !           203:          }
        !           204:        }
        !           205:        if (k == NM_ADDR)
        !           206:          Error("max number of redirect-addr \"%d\" reached", NM_ADDR);
        !           207:       }
        !           208:       break;
        !           209: 
        !           210:     case SET_REDIRECT_PROTO:
        !           211:       {
        !           212:        struct protoent *proto;
        !           213:        struct in_addr  l_addr, a_addr, r_addr;
        !           214:        int k;
        !           215: 
        !           216:        /* Parse */
        !           217:        if (ac != 3 && ac != 4)
        !           218:          return(-1);
        !           219:        if ((proto = getprotobyname(av[0])) == 0)
        !           220:          Error("bad PROTO name \"%s\"", av[0]);
        !           221:        if (!inet_aton (av[1], &a_addr))
        !           222:          Error("bad alias IP address \"%s\"", av[1]);
        !           223:        if (!inet_aton (av[2], &l_addr))
        !           224:          Error("bad local IP address \"%s\"", av[2]);
        !           225:        if (ac == 4) {
        !           226:          if (!inet_aton (av[3], &r_addr))
        !           227:            Error("bad remote IP address \"%s\"", av[3]);
        !           228:        }
        !           229: 
        !           230:        /* OK */
        !           231:        for (k=0;k<NM_PROTO;k++) {
        !           232:          if (nat->nrpr_id[k] == 0) {
        !           233:            memcpy(&nat->nrpr[k].local_addr, &l_addr, sizeof(struct in_addr));
        !           234:            memcpy(&nat->nrpr[k].alias_addr, &a_addr, sizeof(struct in_addr));
        !           235:            if (ac == 4)
        !           236:              memcpy(&nat->nrpr[k].remote_addr, &r_addr, sizeof(struct in_addr));
        !           237:            nat->nrpr[k].proto = (uint8_t)proto->p_proto;
        !           238:            snprintf(nat->nrpr[k].description, NG_NAT_DESC_LENGTH, "nat-proto-%d", k);
        !           239:            nat->nrpr_id[k] = 1;
        !           240:            break;
        !           241:          }
        !           242:        }
        !           243:        if (k == NM_PROTO)
        !           244:          Error("max number of redirect-proto \"%d\" reached", NM_PROTO);
        !           245:       }
        !           246:       break;
        !           247: #endif
        !           248: 
        !           249:     case SET_ENABLE:
        !           250:       EnableCommand(ac, av, &nat->options, gConfList);
        !           251:       break;
        !           252: 
        !           253:     case SET_DISABLE:
        !           254:       DisableCommand(ac, av, &nat->options, gConfList);
        !           255:       break;
        !           256: 
        !           257:     default:
        !           258:       assert(0);
        !           259:   }
        !           260:   return(0);
        !           261: }
        !           262: 
        !           263: /*
        !           264:  * NatStat()
        !           265:  */
        !           266: 
        !           267: int
        !           268: NatStat(Context ctx, int ac, char *av[], void *arg)
        !           269: {
        !           270:     NatState   const nat = &ctx->bund->iface.nat;
        !           271:     char       buf[48];
        !           272:     int k;
        !           273: 
        !           274:     Printf("NAT configuration:\r\n");
        !           275:     Printf("\tAlias addresses : %s\r\n", 
        !           276:        u_addrtoa(&nat->alias_addr,buf,sizeof(buf)));
        !           277:     Printf("\tTarget addresses: %s\r\n", 
        !           278:        u_addrtoa(&nat->target_addr,buf,sizeof(buf)));
        !           279: #ifdef NG_NAT_DESC_LENGTH
        !           280:     Printf("Redirect ports:\r\n");
        !           281:     for (k=0;k<NM_PORT;k++) {
        !           282:       if (nat->nrpt_id[k]) {
        !           283:        struct protoent *proto;
        !           284:        char    li[15], ai[15], ri[15];
        !           285:        inet_ntop(AF_INET, &nat->nrpt[k].local_addr, li, sizeof(li));
        !           286:        inet_ntop(AF_INET, &nat->nrpt[k].alias_addr, ai, sizeof(ai));
        !           287:        inet_ntop(AF_INET, &nat->nrpt[k].remote_addr, ri, sizeof(ri));
        !           288:        proto = getprotobynumber(nat->nrpt[k].proto);
        !           289:        Printf("\t%s %s:%d %s:%d %s:%d\r\n", proto->p_name,
        !           290:            ai, nat->nrpt[k].alias_port, li, nat->nrpt[k].local_port,
        !           291:            ri, nat->nrpt[k].remote_port);
        !           292:       }
        !           293:     }
        !           294:     Printf("Redirect address:\r\n");
        !           295:     for (k=0;k<NM_ADDR;k++) {
        !           296:       if (nat->nrad_id[k]) {
        !           297:        char    li[15], ai[15];
        !           298:        inet_ntop(AF_INET, &nat->nrad[k].local_addr, li, sizeof(li));
        !           299:        inet_ntop(AF_INET, &nat->nrad[k].alias_addr, ai, sizeof(ai));
        !           300:        Printf("\t%s %s\r\n", ai, li);
        !           301:       }
        !           302:     }
        !           303:     Printf("Redirect proto:\r\n");
        !           304:     for (k=0;k<NM_PROTO;k++) {
        !           305:       if (nat->nrpr_id[k]) {
        !           306:        struct protoent *proto;
        !           307:        char    li[15], ai[15], ri[15];
        !           308:        proto = getprotobynumber(nat->nrpr[k].proto);
        !           309:        inet_ntop(AF_INET, &nat->nrpr[k].local_addr, li, sizeof(li));
        !           310:        inet_ntop(AF_INET, &nat->nrpr[k].alias_addr, ai, sizeof(ai));
        !           311:        inet_ntop(AF_INET, &nat->nrpr[k].remote_addr, ri, sizeof(ri));
        !           312:        Printf("\t%s %s %s %s\r\n", proto->p_name, ai, li, ri);
        !           313:       }
        !           314:     }
        !           315: #endif
        !           316:     Printf("NAT options:\r\n");
        !           317:     OptStat(ctx, &nat->options, gConfList);
        !           318:     return(0);
        !           319: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>