Diff for /embedaddon/miniupnpd/pf/obsdrdr.c between versions 1.1 and 1.1.1.2

version 1.1, 2012/02/21 23:16:02 version 1.1.1.2, 2012/05/29 12:55:57
Line 59 Line 59
 #include "obsdrdr.h"  #include "obsdrdr.h"
 #include "../upnpglobalvars.h"  #include "../upnpglobalvars.h"
   
   /* list too keep timestamps for port mappings having a lease duration */
   struct timestamp_entry {
           struct timestamp_entry * next;
           unsigned int timestamp;
           unsigned short eport;
           short protocol;
   };
   
   static struct timestamp_entry * timestamp_list = NULL;
   
   static unsigned int
   get_timestamp(unsigned short eport, int proto)
   {
           struct timestamp_entry * e;
           e = timestamp_list;
           while(e) {
                   if(e->eport == eport && e->protocol == (short)proto)
                           return e->timestamp;
                   e = e->next;
           }
           return 0;
   }
   
   static void
   remove_timestamp_entry(unsigned short eport, int proto)
   {
           struct timestamp_entry * e;
           struct timestamp_entry * * p;
           p = &timestamp_list;
           e = *p;
           while(e) {
                   if(e->eport == eport && e->protocol == (short)proto) {
                           /* remove the entry */
                           *p = e->next;
                           free(e);
                           return;
                   }
                   p = &(e->next);
                   e = *p;
           }
   }
   
 /* anchor name */  /* anchor name */
 static const char anchor_name[] = "miniupnpd";  static const char anchor_name[] = "miniupnpd";
   
Line 138  error: Line 180  error:
 /* add_redirect_rule2() :  /* add_redirect_rule2() :
  * create a rdr rule */   * create a rdr rule */
 int  int
add_redirect_rule2(const char * ifname, unsigned short eport,add_redirect_rule2(const char * ifname,
                    const char * rhost, unsigned short eport,
                    const char * iaddr, unsigned short iport, int proto,                     const char * iaddr, unsigned short iport, int proto,
                                   const char * desc)                   const char * desc, unsigned int timestamp)
 {  {
         int r;          int r;
         struct pfioc_rule pcr;          struct pfioc_rule pcr;
Line 210  add_redirect_rule2(const char * ifname, unsigned short Line 253  add_redirect_rule2(const char * ifname, unsigned short
                 if(tag)                  if(tag)
                         strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE);                          strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE);
                 strlcpy(pcr.rule.label, desc, PF_RULE_LABEL_SIZE);                  strlcpy(pcr.rule.label, desc, PF_RULE_LABEL_SIZE);
                   if(rhost && rhost[0] != '\0' && rhost[0] != '*')
                   {
                           inet_pton(AF_INET, rhost, &pcr.rule.src.addr.v.a.addr.v4.s_addr);
                           pcr.rule.src.addr.v.a.mask.v4.s_addr = htonl(INADDR_NONE);
                   }
 #ifndef PF_NEWSTYLE  #ifndef PF_NEWSTYLE
                 pcr.rule.rpool.proxy_port[0] = iport;                  pcr.rule.rpool.proxy_port[0] = iport;
                 pcr.rule.rpool.proxy_port[1] = iport;                  pcr.rule.rpool.proxy_port[1] = iport;
Line 255  add_redirect_rule2(const char * ifname, unsigned short Line 303  add_redirect_rule2(const char * ifname, unsigned short
                 free(a);                  free(a);
 #endif  #endif
         }          }
           if(r == 0 && timestamp > 0)
           {
                   struct timestamp_entry * tmp;
                   tmp = malloc(sizeof(struct timestamp_entry));
                   if(tmp)
                   {
                           tmp->next = timestamp_list;
                           tmp->timestamp = timestamp;
                           tmp->eport = eport;
                           tmp->protocol = (short)proto;
                           timestamp_list = tmp;
                   }
           }
         return r;          return r;
 }  }
   
 /* thanks to Seth Mos for this function */  /* thanks to Seth Mos for this function */
 int  int
add_filter_rule2(const char * ifname, const char * iaddr,add_filter_rule2(const char * ifname,
                  const char * rhost, const char * iaddr,
                  unsigned short eport, unsigned short iport,                   unsigned short eport, unsigned short iport,
                                  int proto, const char * desc)                                   int proto, const char * desc)
 {  {
Line 323  add_filter_rule2(const char * ifname, const char * iad Line 385  add_filter_rule2(const char * ifname, const char * iad
                 if(tag)                  if(tag)
                         strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE);                          strlcpy(pcr.rule.tagname, tag, PF_TAG_NAME_SIZE);
   
                   if(rhost && rhost[0] != '\0' && rhost[0] != '*')
                   {
                           inet_pton(AF_INET, rhost, &pcr.rule.src.addr.v.a.addr.v4.s_addr);
                           pcr.rule.src.addr.v.a.mask.v4.s_addr = htonl(INADDR_NONE);
                   }
 #ifndef PF_NEWSTYLE  #ifndef PF_NEWSTYLE
                 pcr.rule.rpool.proxy_port[0] = eport;                  pcr.rule.rpool.proxy_port[0] = eport;
                 a = calloc(1, sizeof(struct pf_pooladdr));                  a = calloc(1, sizeof(struct pf_pooladdr));
Line 381  int Line 448  int
 get_redirect_rule(const char * ifname, unsigned short eport, int proto,  get_redirect_rule(const char * ifname, unsigned short eport, int proto,
                   char * iaddr, int iaddrlen, unsigned short * iport,                    char * iaddr, int iaddrlen, unsigned short * iport,
                   char * desc, int desclen,                    char * desc, int desclen,
                     char * rhost, int rhostlen,
                     unsigned int * timestamp,
                   u_int64_t * packets, u_int64_t * bytes)                    u_int64_t * packets, u_int64_t * bytes)
 {  {
         int i, n;          int i, n;
Line 461  get_redirect_rule(const char * ifname, unsigned short  Line 530  get_redirect_rule(const char * ifname, unsigned short 
                         inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr,                          inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr,
                                   iaddr, iaddrlen);                                    iaddr, iaddrlen);
 #endif  #endif
                           if(rhost && rhostlen > 0)
                           {
                                   if (pr.rule.src.addr.v.a.addr.v4.s_addr == 0)
                                   {
                                           rhost[0] = '\0'; /* empty string */
                                   }
                                   else
                                   {
                                           inet_ntop(AF_INET, &pr.rule.src.addr.v.a.addr.v4.s_addr,
                                                     rhost, rhostlen);
                                   }
                           }
                           if(timestamp)
                                   *timestamp = get_timestamp(eport, proto);
                         return 0;                          return 0;
                 }                  }
         }          }
Line 513  delete_redirect_rule(const char * ifname, unsigned sho Line 596  delete_redirect_rule(const char * ifname, unsigned sho
                                 syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");                                  syslog(LOG_ERR, "ioctl(dev, DIOCCHANGERULE, ...) PF_CHANGE_REMOVE: %m");
                                 goto error;                                  goto error;
                         }                          }
                           remove_timestamp_entry(eport, proto);
                         return 0;                          return 0;
                 }                  }
         }          }
Line 578  get_redirect_rule_by_index(int index, Line 662  get_redirect_rule_by_index(int index,
                            char * ifname, unsigned short * eport,                             char * ifname, unsigned short * eport,
                            char * iaddr, int iaddrlen, unsigned short * iport,                             char * iaddr, int iaddrlen, unsigned short * iport,
                            int * proto, char * desc, int desclen,                             int * proto, char * desc, int desclen,
                              char * rhost, int rhostlen,
                              unsigned int * timestamp,
                            u_int64_t * packets, u_int64_t * bytes)                             u_int64_t * packets, u_int64_t * bytes)
 {  {
         int n;          int n;
Line 660  get_redirect_rule_by_index(int index, Line 746  get_redirect_rule_by_index(int index,
         inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr,          inet_ntop(AF_INET, &pr.rule.rdr.addr.v.a.addr.v4.s_addr,
                   iaddr, iaddrlen);                    iaddr, iaddrlen);
 #endif  #endif
           if(rhost && rhostlen > 0)
           {
                   if (pr.rule.src.addr.v.a.addr.v4.s_addr == 0)
                   {
                           rhost[0] = '\0'; /* empty string */
                   }
                   else
                   {
                           inet_ntop(AF_INET, &pr.rule.src.addr.v.a.addr.v4.s_addr,
                                     rhost, rhostlen);
                   }
           }
           if(timestamp)
                   *timestamp = get_timestamp(*eport, *proto);
         return 0;          return 0;
 error:  error:
         return -1;          return -1;
 }  }
   
   /* return an (malloc'ed) array of "external" port for which there is
    * a port mapping. number is the size of the array */
   unsigned short *
   get_portmappings_in_range(unsigned short startport, unsigned short endport,
                             int proto, unsigned int * number)
   {
           unsigned short * array;
           unsigned int capacity;
           int i, n;
           unsigned short eport;
           struct pfioc_rule pr;
   
           *number = 0;
           if(dev<0) {
                   syslog(LOG_ERR, "pf device is not open");
                   return NULL;
           }
           capacity = 128;
           array = calloc(capacity, sizeof(unsigned short));
           if(!array)
           {
                   syslog(LOG_ERR, "get_portmappings_in_range() : calloc error");
                   return NULL;
           }
           memset(&pr, 0, sizeof(pr));
           strlcpy(pr.anchor, anchor_name, MAXPATHLEN);
   #ifndef PF_NEWSTYLE
           pr.rule.action = PF_RDR;
   #endif
           if(ioctl(dev, DIOCGETRULES, &pr) < 0)
           {
                   syslog(LOG_ERR, "ioctl(dev, DIOCGETRULES, ...): %m");
                   free(array);
                   return NULL;
           }
           n = pr.nr;
           for(i=0; i<n; i++)
           {
                   pr.nr = i;
                   if(ioctl(dev, DIOCGETRULE, &pr) < 0)
                   {
                           syslog(LOG_ERR, "ioctl(dev, DIOCGETRULE): %m");
                           continue;
                   }
                   eport = ntohs(pr.rule.dst.port[0]);
                   if( (eport == ntohs(pr.rule.dst.port[1]))
                     && (pr.rule.proto == proto)
                     && (startport <= eport) && (eport <= endport) )
                   {
                           if(*number >= capacity)
                           {
                                   /* need to increase the capacity of the array */
                                   capacity += 128;
                                   array = realloc(array, sizeof(unsigned short)*capacity);
                                   if(!array)
                                   {
                                           syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity);
                                           *number = 0;
                                           return NULL;
                                   }
                           }
                           array[*number] = eport;
                           (*number)++;
                   }
           }
           return array;
   }
   
 /* this function is only for testing */  /* this function is only for testing */
 #if TEST  #if TEST
 void  void
Line 695  list_rules(void) Line 863  list_rules(void)
                 pr.nr = i;                  pr.nr = i;
                 if(ioctl(dev, DIOCGETRULE, &pr) < 0)                  if(ioctl(dev, DIOCGETRULE, &pr) < 0)
                         perror("DIOCGETRULE");                          perror("DIOCGETRULE");
                printf(" %s %d:%d -> %d:%d  proto %d keep_state=%d action=%d\n",                printf(" %s %s %d:%d -> %d:%d  proto %d keep_state=%d action=%d\n",
                         pr.rule.ifname,                          pr.rule.ifname,
                           inet_ntop(AF_INET, &pr.rule.src.addr.v.a.addr.v4.s_addr, buf, 32);
                         (int)ntohs(pr.rule.dst.port[0]),                          (int)ntohs(pr.rule.dst.port[0]),
                         (int)ntohs(pr.rule.dst.port[1]),                          (int)ntohs(pr.rule.dst.port[1]),
 #ifndef PF_NEWSTYLE  #ifndef PF_NEWSTYLE

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


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