Annotation of embedaddon/mpd/src/nat.c, revision 1.1.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>