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>