Add PPTP runtime and GUI
[tomato.git] / release / src / router / miniupnpd / upnppermissions.c
blob912723a522a3f60af1f9110575619482db2295ab
1 /* $Id: upnppermissions.c,v 1.14 2009/12/22 17:21:43 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
8 #include <ctype.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <syslog.h>
13 #include <arpa/inet.h>
14 #include <unistd.h>
15 #include "config.h"
16 #include "upnppermissions.h"
18 int
19 read_permission_line(struct upnpperm * perm,
20 char * p)
22 char * q;
23 int n_bits;
25 /* first token: (allow|deny) */
26 while(isspace(*p))
27 p++;
28 if(0 == memcmp(p, "allow", 5))
30 perm->type = UPNPPERM_ALLOW;
31 p += 5;
33 else if(0 == memcmp(p, "deny", 4))
35 perm->type = UPNPPERM_DENY;
36 p += 4;
38 else
40 return -1;
43 /* second token: eport or eport_min-eport_max */
44 while(isspace(*p))
45 p++;
46 if(!isdigit(*p))
47 return -1;
48 for(q = p; isdigit(*q); q++);
49 if(*q=='-')
51 *q = '\0';
52 perm->eport_min = (u_short)atoi(p);
53 q++;
54 p = q;
55 while(isdigit(*q))
56 q++;
57 *q = '\0';
58 perm->eport_max = (u_short)atoi(p);
60 else
62 *q = '\0';
63 perm->eport_min = perm->eport_max = (u_short)atoi(p);
65 p = q + 1;
66 while(isspace(*p))
67 p++;
69 /* third token: ip/mask */
70 if(!isdigit(*p))
71 return -1;
72 for(q = p; isdigit(*q) || (*q == '.'); q++);
73 if(*q=='/')
75 *q = '\0';
76 if(!inet_aton(p, &perm->address))
77 return -1;
78 q++;
79 p = q;
80 while(isdigit(*q) || (*q == '.'))
81 q++;
82 *q = '\0';
84 unsigned short i, mask[4];
85 unsigned char *am = (unsigned char *) &(perm->mask.s_addr);
86 if (sscanf(p, "%3hu.%3hu.%3hu.%3hu", &mask[0], &mask[1], &mask[2], &mask[3]) == 4)
88 for (i = 0; i < 4; i++)
89 am[i] = (unsigned char) mask[i];
91 else
93 n_bits = atoi(p);
94 perm->mask.s_addr = htonl(n_bits ? (0xffffffff << (32 - n_bits)) : 0);
97 else
99 *q = '\0';
100 if(!inet_aton(p, &perm->address))
101 return -1;
102 perm->mask.s_addr = 0xffffffff;
104 p = q + 1;
106 /* fourth token: iport or iport_min-iport_max */
107 while(isspace(*p))
108 p++;
109 if(!isdigit(*p))
110 return -1;
111 for(q = p; isdigit(*q); q++);
112 if(*q=='-')
114 *q = '\0';
115 perm->iport_min = (u_short)atoi(p);
116 q++;
117 p = q;
118 while(isdigit(*q))
119 q++;
120 *q = '\0';
121 perm->iport_max = (u_short)atoi(p);
123 else
125 *q = '\0';
126 perm->iport_min = perm->iport_max = (u_short)atoi(p);
128 #ifdef DEBUG
129 printf("perm rule added : %s %hu-%hu %08x/%08x %hu-%hu\n",
130 (perm->type==UPNPPERM_ALLOW)?"allow":"deny",
131 perm->eport_min, perm->eport_max, ntohl(perm->address.s_addr),
132 ntohl(perm->mask.s_addr), perm->iport_min, perm->iport_max);
133 #endif
134 return 0;
137 #ifdef USE_MINIUPNPDCTL
138 void
139 write_permlist(int fd, const struct upnpperm * permary,
140 int nperms)
142 int l;
143 const struct upnpperm * perm;
144 int i;
145 char buf[128];
146 write(fd, "Permissions :\n", 14);
147 for(i = 0; i<nperms; i++)
149 perm = permary + i;
150 l = snprintf(buf, sizeof(buf), "%02d %s %hu-%hu %08x/%08x %hu-%hu\n",
152 (perm->type==UPNPPERM_ALLOW)?"allow":"deny",
153 perm->eport_min, perm->eport_max, ntohl(perm->address.s_addr),
154 ntohl(perm->mask.s_addr), perm->iport_min, perm->iport_max);
155 if(l<0)
156 return;
157 write(fd, buf, l);
160 #endif
162 /* match_permission()
163 * returns: 1 if eport, address, iport matches the permission rule
164 * 0 if no match */
165 static int
166 match_permission(const struct upnpperm * perm,
167 u_short eport, struct in_addr address, u_short iport)
169 if( (eport < perm->eport_min) || (perm->eport_max < eport))
170 return 0;
171 if( (iport < perm->iport_min) || (perm->iport_max < iport))
172 return 0;
173 if( (address.s_addr & perm->mask.s_addr)
174 != (perm->address.s_addr & perm->mask.s_addr) )
175 return 0;
176 return 1;
180 check_upnp_rule_against_permissions(const struct upnpperm * permary,
181 int n_perms,
182 u_short eport, struct in_addr address,
183 u_short iport)
185 int i;
186 for(i=0; i<n_perms; i++)
188 if(match_permission(permary + i, eport, address, iport))
190 syslog(LOG_DEBUG,
191 "UPnP permission rule %d matched : port mapping %s",
192 i, (permary[i].type == UPNPPERM_ALLOW)?"accepted":"rejected"
194 return (permary[i].type == UPNPPERM_ALLOW);
197 syslog(LOG_DEBUG, "no permission rule matched : accept by default (n_perms=%d)", n_perms);
198 return 1; /* Default : accept */