Diff for /embedaddon/mpd/src/nat.c between versions 1.1.1.1 and 1.1.1.2

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);
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


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