version 1.1.1.1, 2012/02/21 23:32:47
|
version 1.1.1.2, 2013/07/22 08:44:29
|
Line 9
|
Line 9
|
#include "nat.h" |
#include "nat.h" |
#include "iface.h" |
#include "iface.h" |
#include "netgraph.h" |
#include "netgraph.h" |
|
#ifdef NG_NAT_DESC_LENGTH |
|
#include "ngfunc.h" |
|
#endif |
#include "util.h" |
#include "util.h" |
|
|
/* |
/* |
Line 24
|
Line 27
|
SET_DISABLE, |
SET_DISABLE, |
SET_REDIRECT_PORT, |
SET_REDIRECT_PORT, |
SET_REDIRECT_ADDR, |
SET_REDIRECT_ADDR, |
SET_REDIRECT_PROTO | SET_REDIRECT_PROTO, |
| UNSET_REDIRECT_PORT, |
| UNSET_REDIRECT_ADDR, |
| UNSET_REDIRECT_PROTO |
}; |
}; |
|
|
static int NatSetCommand(Context ctx, int ac, char *av[], void *arg); |
static int NatSetCommand(Context ctx, int ac, char *av[], void *arg); |
Line 33 static int NatSetCommand(Context ctx, int ac, char *av
|
Line 39 static int NatSetCommand(Context ctx, int ac, char *av
|
* GLOBAL VARIABLES |
* GLOBAL VARIABLES |
*/ |
*/ |
|
|
|
#ifdef NG_NAT_DESC_LENGTH |
|
const struct cmdtab NatUnSetCmds[] = { |
|
{ "red-port {proto} {alias_addr} {alias_port} {local_addr} {local_port} [{remote_addr} {remote_port}]", "Redirect port", |
|
NatSetCommand, AdmitBund, 2, (void *) UNSET_REDIRECT_PORT }, |
|
{ "red-addr {alias_addr} {local_addr}", "Redirect address", |
|
NatSetCommand, AdmitBund, 2, (void *) UNSET_REDIRECT_ADDR }, |
|
{ "red-proto {proto} {alias-addr} {local_addr} [{remote-addr}]", "Redirect protocol", |
|
NatSetCommand, AdmitBund, 2, (void *) UNSET_REDIRECT_PROTO }, |
|
{ NULL }, |
|
}; |
|
#endif |
|
|
const struct cmdtab NatSetCmds[] = { |
const struct cmdtab NatSetCmds[] = { |
{ "address {addr}", "Set alias address", |
{ "address {addr}", "Set alias address", |
NatSetCommand, AdmitBund, 2, (void *) SET_ADDR }, |
NatSetCommand, AdmitBund, 2, (void *) SET_ADDR }, |
Line 100 static int
|
Line 118 static int
|
NatSetCommand(Context ctx, int ac, char *av[], void *arg) |
NatSetCommand(Context ctx, int ac, char *av[], void *arg) |
{ |
{ |
NatState const nat = &ctx->bund->iface.nat; |
NatState const nat = &ctx->bund->iface.nat; |
|
IfaceState const iface = &ctx->bund->iface; |
|
#ifdef NG_NAT_DESC_LENGTH |
|
char path[NG_PATHSIZ]; |
|
union { |
|
u_char buf[sizeof(struct ng_mesg) + sizeof(uint32_t)]; |
|
struct ng_mesg reply; |
|
} u; |
|
uint32_t *const nat_id = (uint32_t *)(void *)u.reply.data; |
|
|
|
snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, (char *)&ctx->bund->name); |
|
#endif |
|
|
if (ac == 0) |
if (ac == 0) |
return(-1); |
return(-1); |
switch ((intptr_t)arg) { |
switch ((intptr_t)arg) { |
Line 130 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
Line 159 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
|
|
#ifdef NG_NAT_DESC_LENGTH |
#ifdef NG_NAT_DESC_LENGTH |
case SET_REDIRECT_PORT: |
case SET_REDIRECT_PORT: |
|
case UNSET_REDIRECT_PORT: |
{ |
{ |
struct protoent *proto; |
struct protoent *proto; |
struct in_addr l_addr, a_addr, r_addr; |
struct in_addr l_addr, a_addr, r_addr; |
int lp, ap, rp = 0, k; | int lp, ap, rp = 0; |
| uint32_t k; |
|
|
/* Parse */ |
/* Parse */ |
if (ac != 5 && ac != 7) |
if (ac != 5 && ac != 7) |
Line 158 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
Line 189 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
Error("Incorrect remote port number \"%s\"", av[6]); |
Error("Incorrect remote port number \"%s\"", av[6]); |
} |
} |
/* OK */ |
/* OK */ |
for (k=0;k<NM_PORT;k++) { | if ((intptr_t)arg == SET_REDIRECT_PORT) { |
if (nat->nrpt_id[k] == 0) { | for (k=0;k<NM_PORT;k++) { |
memcpy(&nat->nrpt[k].local_addr, &l_addr, sizeof(struct in_addr)); | if (nat->nrpt_id[k] == 0) { |
memcpy(&nat->nrpt[k].alias_addr, &a_addr, sizeof(struct in_addr)); | memcpy(&nat->nrpt[k].local_addr, &l_addr, sizeof(struct in_addr)); |
nat->nrpt[k].local_port = lp; | memcpy(&nat->nrpt[k].alias_addr, &a_addr, sizeof(struct in_addr)); |
nat->nrpt[k].alias_port = ap; | nat->nrpt[k].local_port = lp; |
if (ac == 7) { | nat->nrpt[k].alias_port = ap; |
memcpy(&nat->nrpt[k].remote_addr, &r_addr, sizeof(struct in_addr)); | if (ac == 7) { |
nat->nrpt[k].remote_port = rp; | memcpy(&nat->nrpt[k].remote_addr, &r_addr, sizeof(struct in_addr)); |
| nat->nrpt[k].remote_port = rp; |
| } |
| nat->nrpt[k].proto = (uint8_t)proto->p_proto; |
| snprintf(nat->nrpt[k].description, NG_NAT_DESC_LENGTH, "nat-port-%d", k); |
| nat->nrpt_id[k] = -1; |
| if (iface->up && iface->nat_up) { |
| if (NgFuncSendQuery(path, NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PORT, |
| &nat->nrpt[k], sizeof(struct ng_nat_redirect_port), |
| &u.reply, sizeof(u), NULL) == 0) |
| nat->nrpt_id[k] = *nat_id; |
| } |
| break; |
} |
} |
nat->nrpt[k].proto = (uint8_t)proto->p_proto; |
|
snprintf(nat->nrpt[k].description, NG_NAT_DESC_LENGTH, "nat-port-%d", k); |
|
nat->nrpt_id[k] = 1; |
|
break; |
|
} |
} |
|
if (k == NM_PORT) |
|
Error("max number of redirect-port \"%d\" reached", NM_PORT); |
|
} else { |
|
struct ng_nat_redirect_port tmp_rule; |
|
|
|
bzero(&tmp_rule, sizeof(struct ng_nat_redirect_port)); |
|
memcpy(&tmp_rule.local_addr, &l_addr, sizeof(struct in_addr)); |
|
memcpy(&tmp_rule.alias_addr, &a_addr, sizeof(struct in_addr)); |
|
tmp_rule.local_port = lp; |
|
tmp_rule.alias_port = ap; |
|
if (ac == 7) { |
|
memcpy(&tmp_rule.remote_addr, &r_addr, sizeof(struct in_addr)); |
|
tmp_rule.remote_port = rp; |
|
} |
|
tmp_rule.proto = (uint8_t)proto->p_proto; |
|
/* hack to fill misaligned space */ |
|
snprintf(tmp_rule.description, NG_NAT_DESC_LENGTH, "nat-port-0"); |
|
for (k=0;k<NM_PORT;k++) { |
|
if ((nat->nrpt_id[k] != 0) && (memcmp(&tmp_rule, &nat->nrpt[k], |
|
sizeof(struct ng_nat_redirect_port)-NG_NAT_DESC_LENGTH) == 0)) { |
|
if (iface->up && iface->nat_up) { |
|
if (NgSendMsg(gLinksCsock, path, NGM_NAT_COOKIE, |
|
NGM_NAT_REDIRECT_DELETE, &k, sizeof(k)) < 0) { |
|
Perror("Can't delete nat rule"); |
|
break; |
|
} |
|
} |
|
nat->nrpt_id[k] = 0; |
|
bzero(&nat->nrpt[k], sizeof(struct ng_nat_redirect_port)); |
|
break; |
|
} |
|
} |
|
if (k == NM_PORT) |
|
Error("Rule not found"); |
} |
} |
if (k == NM_PORT) |
|
Error("max number of redirect-port \"%d\" reached", NM_PORT); |
|
} |
} |
break; |
break; |
|
|
case SET_REDIRECT_ADDR: |
case SET_REDIRECT_ADDR: |
|
case UNSET_REDIRECT_ADDR: |
{ |
{ |
struct in_addr l_addr, a_addr; |
struct in_addr l_addr, a_addr; |
int k; | uint32_t k; |
|
|
/* Parse */ |
/* Parse */ |
if (ac != 2) |
if (ac != 2) |
Line 193 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
Line 265 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
Error("bad local IP address \"%s\"", av[1]); |
Error("bad local IP address \"%s\"", av[1]); |
|
|
/* OK */ |
/* OK */ |
for (k=0;k<NM_ADDR;k++) { | if ((intptr_t)arg == SET_REDIRECT_ADDR) { |
if (nat->nrad_id[k] == 0) { | for (k=0;k<NM_ADDR;k++) { |
memcpy(&nat->nrad[k].local_addr, &l_addr, sizeof(struct in_addr)); | if (nat->nrad_id[k] == 0) { |
memcpy(&nat->nrad[k].alias_addr, &a_addr, sizeof(struct in_addr)); | memcpy(&nat->nrad[k].local_addr, &l_addr, sizeof(struct in_addr)); |
snprintf(nat->nrad[k].description, NG_NAT_DESC_LENGTH, "nat-addr-%d", k); | memcpy(&nat->nrad[k].alias_addr, &a_addr, sizeof(struct in_addr)); |
nat->nrad_id[k] = 1; | snprintf(nat->nrad[k].description, NG_NAT_DESC_LENGTH, "nat-addr-%d", k); |
break; | nat->nrad_id[k] = -1; |
| if (iface->up && iface->nat_up) { |
| if (NgFuncSendQuery(path, NGM_NAT_COOKIE, NGM_NAT_REDIRECT_ADDR, |
| &nat->nrad[k], sizeof(struct ng_nat_redirect_addr), |
| &u.reply, sizeof(u), NULL) == 0) |
| nat->nrad_id[k] = *nat_id; |
| } |
| break; |
| } |
} |
} |
|
if (k == NM_ADDR) |
|
Error("max number of redirect-addr \"%d\" reached", NM_ADDR); |
|
} else { |
|
struct ng_nat_redirect_addr tmp_rule; |
|
|
|
bzero(&tmp_rule, sizeof(struct ng_nat_redirect_addr)); |
|
memcpy(&tmp_rule.local_addr, &l_addr, sizeof(struct in_addr)); |
|
memcpy(&tmp_rule.alias_addr, &a_addr, sizeof(struct in_addr)); |
|
/* hack to fill misaligned space */ |
|
snprintf(tmp_rule.description, NG_NAT_DESC_LENGTH, "nat-addr-0"); |
|
for (k=0;k<NM_ADDR;k++) { |
|
if ((nat->nrad_id[k] != 0) && (memcmp(&tmp_rule, &nat->nrad[k], |
|
sizeof(struct ng_nat_redirect_addr)-NG_NAT_DESC_LENGTH) == 0)) { |
|
if (iface->up && iface->nat_up) { |
|
if (NgSendMsg(gLinksCsock, path, NGM_NAT_COOKIE, |
|
NGM_NAT_REDIRECT_DELETE, &k, sizeof(k)) < 0) { |
|
Perror("Can't delete nat rule"); |
|
break; |
|
} |
|
} |
|
nat->nrad_id[k] = 0; |
|
bzero(&nat->nrad[k], sizeof(struct ng_nat_redirect_addr)); |
|
break; |
|
} |
|
} |
|
if (k == NM_ADDR) |
|
Error("Rule not found"); |
} |
} |
if (k == NM_ADDR) |
|
Error("max number of redirect-addr \"%d\" reached", NM_ADDR); |
|
} |
} |
break; |
break; |
|
|
case SET_REDIRECT_PROTO: |
case SET_REDIRECT_PROTO: |
|
case UNSET_REDIRECT_PROTO: |
{ |
{ |
struct protoent *proto; |
struct protoent *proto; |
struct in_addr l_addr, a_addr, r_addr; |
struct in_addr l_addr, a_addr, r_addr; |
int k; | uint32_t k; |
|
|
/* Parse */ |
/* Parse */ |
if (ac != 3 && ac != 4) |
if (ac != 3 && ac != 4) |
Line 228 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
Line 334 NatSetCommand(Context ctx, int ac, char *av[], void *a
|
} |
} |
|
|
/* OK */ |
/* OK */ |
for (k=0;k<NM_PROTO;k++) { | if ((intptr_t)arg == SET_REDIRECT_PROTO) { |
if (nat->nrpr_id[k] == 0) { | for (k=0;k<NM_PROTO;k++) { |
memcpy(&nat->nrpr[k].local_addr, &l_addr, sizeof(struct in_addr)); | if (nat->nrpr_id[k] == 0) { |
memcpy(&nat->nrpr[k].alias_addr, &a_addr, sizeof(struct in_addr)); | memcpy(&nat->nrpr[k].local_addr, &l_addr, sizeof(struct in_addr)); |
if (ac == 4) | memcpy(&nat->nrpr[k].alias_addr, &a_addr, sizeof(struct in_addr)); |
memcpy(&nat->nrpr[k].remote_addr, &r_addr, sizeof(struct in_addr)); | if (ac == 4) |
nat->nrpr[k].proto = (uint8_t)proto->p_proto; | memcpy(&nat->nrpr[k].remote_addr, &r_addr, sizeof(struct in_addr)); |
snprintf(nat->nrpr[k].description, NG_NAT_DESC_LENGTH, "nat-proto-%d", k); | nat->nrpr[k].proto = (uint8_t)proto->p_proto; |
nat->nrpr_id[k] = 1; | snprintf(nat->nrpr[k].description, NG_NAT_DESC_LENGTH, "nat-proto-%d", k); |
break; | nat->nrpr_id[k] = -1; |
| if (iface->up && iface->nat_up) { |
| if (NgFuncSendQuery(path, NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PROTO, |
| &nat->nrpr[k], sizeof(struct ng_nat_redirect_proto), |
| &u.reply, sizeof(u), NULL) == 0) |
| nat->nrpr_id[k] = *nat_id; |
| } |
| break; |
| } |
} |
} |
|
if (k == NM_PROTO) |
|
Error("max number of redirect-proto \"%d\" reached", NM_PROTO); |
|
} else { |
|
struct ng_nat_redirect_proto tmp_rule; |
|
|
|
bzero(&tmp_rule, sizeof(struct ng_nat_redirect_proto)); |
|
memcpy(&tmp_rule.local_addr, &l_addr, sizeof(struct in_addr)); |
|
memcpy(&tmp_rule.alias_addr, &a_addr, sizeof(struct in_addr)); |
|
if (ac == 4) { |
|
memcpy(&tmp_rule.remote_addr, &r_addr, sizeof(struct in_addr)); |
|
} |
|
tmp_rule.proto = (uint8_t)proto->p_proto; |
|
/* hack to fill misaligned space */ |
|
snprintf(tmp_rule.description, NG_NAT_DESC_LENGTH, "nat-proto-0"); |
|
for (k=0;k<NM_PROTO;k++) { |
|
if ((nat->nrpr_id[k] != 0) && (memcmp(&tmp_rule, &nat->nrpr[k], |
|
sizeof(struct ng_nat_redirect_proto)-NG_NAT_DESC_LENGTH) == 0)) { |
|
if (iface->up && iface->nat_up) { |
|
if (NgSendMsg(gLinksCsock, path, NGM_NAT_COOKIE, |
|
NGM_NAT_REDIRECT_DELETE, &k, sizeof(k)) < 0) { |
|
Perror("Can't delete nat rule"); |
|
break; |
|
} |
|
} |
|
nat->nrpr_id[k] = 0; |
|
bzero(&nat->nrpr[k], sizeof(struct ng_nat_redirect_proto)); |
|
break; |
|
} |
|
} |
|
if (k == NM_PROTO) |
|
Error("Rule not found"); |
} |
} |
if (k == NM_PROTO) |
|
Error("max number of redirect-proto \"%d\" reached", NM_PROTO); |
|
} |
} |
break; |
break; |
#endif |
#endif |
Line 268 int
|
Line 411 int
|
NatStat(Context ctx, int ac, char *av[], void *arg) |
NatStat(Context ctx, int ac, char *av[], void *arg) |
{ |
{ |
NatState const nat = &ctx->bund->iface.nat; |
NatState const nat = &ctx->bund->iface.nat; |
|
#ifdef NGM_NAT_LIBALIAS_INFO |
|
IfaceState const iface = &ctx->bund->iface; |
|
union { |
|
u_char buf[sizeof(struct ng_mesg) + sizeof(struct ng_nat_libalias_info)]; |
|
struct ng_mesg reply; |
|
} u; |
|
struct ng_nat_libalias_info *const li = \ |
|
(struct ng_nat_libalias_info *)(void *)u.reply.data; |
|
char path[NG_PATHSIZ]; |
|
#endif |
char buf[48]; |
char buf[48]; |
int k; |
int k; |
|
|
Line 279 NatStat(Context ctx, int ac, char *av[], void *arg)
|
Line 432 NatStat(Context ctx, int ac, char *av[], void *arg)
|
#ifdef NG_NAT_DESC_LENGTH |
#ifdef NG_NAT_DESC_LENGTH |
Printf("Redirect ports:\r\n"); |
Printf("Redirect ports:\r\n"); |
for (k=0;k<NM_PORT;k++) { |
for (k=0;k<NM_PORT;k++) { |
if (nat->nrpt_id[k]) { | if (nat->nrpt_id[k] != 0) { |
struct protoent *proto; |
struct protoent *proto; |
char li[15], ai[15], ri[15]; | char li[16], ai[16], ri[16]; |
inet_ntop(AF_INET, &nat->nrpt[k].local_addr, li, sizeof(li)); |
inet_ntop(AF_INET, &nat->nrpt[k].local_addr, li, sizeof(li)); |
inet_ntop(AF_INET, &nat->nrpt[k].alias_addr, ai, sizeof(ai)); |
inet_ntop(AF_INET, &nat->nrpt[k].alias_addr, ai, sizeof(ai)); |
inet_ntop(AF_INET, &nat->nrpt[k].remote_addr, ri, sizeof(ri)); |
inet_ntop(AF_INET, &nat->nrpt[k].remote_addr, ri, sizeof(ri)); |
proto = getprotobynumber(nat->nrpt[k].proto); |
proto = getprotobynumber(nat->nrpt[k].proto); |
Printf("\t%s %s:%d %s:%d %s:%d\r\n", proto->p_name, | Printf("\t%s %s:%d %s:%d %s:%d (%sactive)\r\n", proto->p_name, |
ai, nat->nrpt[k].alias_port, li, nat->nrpt[k].local_port, |
ai, nat->nrpt[k].alias_port, li, nat->nrpt[k].local_port, |
ri, nat->nrpt[k].remote_port); | ri, nat->nrpt[k].remote_port, nat->nrpt_id[k]<0?"in":""); |
} |
} |
} |
} |
Printf("Redirect address:\r\n"); |
Printf("Redirect address:\r\n"); |
for (k=0;k<NM_ADDR;k++) { |
for (k=0;k<NM_ADDR;k++) { |
if (nat->nrad_id[k]) { | if (nat->nrad_id[k] != 0) { |
char li[15], ai[15]; | char li[16], ai[16]; |
inet_ntop(AF_INET, &nat->nrad[k].local_addr, li, sizeof(li)); |
inet_ntop(AF_INET, &nat->nrad[k].local_addr, li, sizeof(li)); |
inet_ntop(AF_INET, &nat->nrad[k].alias_addr, ai, sizeof(ai)); |
inet_ntop(AF_INET, &nat->nrad[k].alias_addr, ai, sizeof(ai)); |
Printf("\t%s %s\r\n", ai, li); | Printf("\t%s %s (%sactive)\r\n", ai, li, nat->nrad_id[k]<0?"in":""); |
} |
} |
} |
} |
Printf("Redirect proto:\r\n"); |
Printf("Redirect proto:\r\n"); |
for (k=0;k<NM_PROTO;k++) { |
for (k=0;k<NM_PROTO;k++) { |
if (nat->nrpr_id[k]) { | if (nat->nrpr_id[k] != 0) { |
struct protoent *proto; |
struct protoent *proto; |
char li[15], ai[15], ri[15]; | char li[16], ai[16], ri[16]; |
proto = getprotobynumber(nat->nrpr[k].proto); |
proto = getprotobynumber(nat->nrpr[k].proto); |
inet_ntop(AF_INET, &nat->nrpr[k].local_addr, li, sizeof(li)); |
inet_ntop(AF_INET, &nat->nrpr[k].local_addr, li, sizeof(li)); |
inet_ntop(AF_INET, &nat->nrpr[k].alias_addr, ai, sizeof(ai)); |
inet_ntop(AF_INET, &nat->nrpr[k].alias_addr, ai, sizeof(ai)); |
inet_ntop(AF_INET, &nat->nrpr[k].remote_addr, ri, sizeof(ri)); |
inet_ntop(AF_INET, &nat->nrpr[k].remote_addr, ri, sizeof(ri)); |
Printf("\t%s %s %s %s\r\n", proto->p_name, ai, li, ri); | Printf("\t%s %s %s %s (%sactive)\r\n", proto->p_name, |
| ai, li, ri, nat->nrpr_id[k]<0?"in":""); |
} |
} |
} |
} |
#endif |
#endif |
Printf("NAT options:\r\n"); |
Printf("NAT options:\r\n"); |
OptStat(ctx, &nat->options, gConfList); |
OptStat(ctx, &nat->options, gConfList); |
|
#ifdef NGM_NAT_LIBALIAS_INFO |
|
if (Enabled(&nat->options, NAT_CONF_LOG) && iface->up && iface->nat_up) { |
|
snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, \ |
|
(char *)&ctx->bund->name); |
|
Printf("LibAlias statistic:\r\n"); |
|
if (NgFuncSendQuery(path, NGM_NAT_COOKIE, NGM_NAT_LIBALIAS_INFO, |
|
NULL, 0, &u.reply, sizeof(u), NULL) < 0) |
|
Perror("Can't get LibAlis stats"); |
|
Printf("\ticmpLinkCount : %u\r\n", li->icmpLinkCount); |
|
Printf("\tudpLinkCount : %u\r\n", li->udpLinkCount); |
|
Printf("\ttcpLinkCount : %u\r\n", li->tcpLinkCount); |
|
Printf("\tsctpLinkCount : %u\r\n", li->sctpLinkCount); |
|
Printf("\tpptpLinkCount : %u\r\n", li->pptpLinkCount); |
|
Printf("\tprotoLinkCount : %u\r\n", li->protoLinkCount); |
|
Printf("\tfragmentIdLinkCount : %u\r\n", li->fragmentIdLinkCount); |
|
Printf("\tfragmentPtrLinkCount : %u\r\n", li->fragmentPtrLinkCount); |
|
Printf("\tsockCount : %u\r\n", li->sockCount); |
|
} |
|
#endif |
return(0); |
return(0); |
} |
} |