1 /* $Id: upnppermissions.c,v 1.14 2009/12/22 17:21:43 nanard Exp $ */
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 */
13 #include <arpa/inet.h>
16 #include "upnppermissions.h"
19 read_permission_line(struct upnpperm
* perm
,
25 /* first token: (allow|deny) */
28 if(0 == memcmp(p
, "allow", 5))
30 perm
->type
= UPNPPERM_ALLOW
;
33 else if(0 == memcmp(p
, "deny", 4))
35 perm
->type
= UPNPPERM_DENY
;
43 /* second token: eport or eport_min-eport_max */
48 for(q
= p
; isdigit(*q
); q
++);
52 perm
->eport_min
= (u_short
)atoi(p
);
58 perm
->eport_max
= (u_short
)atoi(p
);
63 perm
->eport_min
= perm
->eport_max
= (u_short
)atoi(p
);
69 /* third token: ip/mask */
72 for(q
= p
; isdigit(*q
) || (*q
== '.'); q
++);
76 if(!inet_aton(p
, &perm
->address
))
80 while(isdigit(*q
) || (*q
== '.'))
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
];
94 perm
->mask
.s_addr
= htonl(n_bits
? (0xffffffff << (32 - n_bits
)) : 0);
100 if(!inet_aton(p
, &perm
->address
))
102 perm
->mask
.s_addr
= 0xffffffff;
106 /* fourth token: iport or iport_min-iport_max */
111 for(q
= p
; isdigit(*q
); q
++);
115 perm
->iport_min
= (u_short
)atoi(p
);
121 perm
->iport_max
= (u_short
)atoi(p
);
126 perm
->iport_min
= perm
->iport_max
= (u_short
)atoi(p
);
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
);
137 #ifdef USE_MINIUPNPDCTL
139 write_permlist(int fd
, const struct upnpperm
* permary
,
143 const struct upnpperm
* perm
;
146 write(fd
, "Permissions :\n", 14);
147 for(i
= 0; i
<nperms
; 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
);
162 /* match_permission()
163 * returns: 1 if eport, address, iport matches the permission rule
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
))
171 if( (iport
< perm
->iport_min
) || (perm
->iport_max
< iport
))
173 if( (address
.s_addr
& perm
->mask
.s_addr
)
174 != (perm
->address
.s_addr
& perm
->mask
.s_addr
) )
180 check_upnp_rule_against_permissions(const struct upnpperm
* permary
,
182 u_short eport
, struct in_addr address
,
186 for(i
=0; i
<n_perms
; i
++)
188 if(match_permission(permary
+ i
, eport
, address
, iport
))
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 */