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>