Stealth Mode script
[tomato.git] / release / src / router / miniupnpd / upnppinhole.c
blob31c2183fd98575306b8f4ccc88a93f88ac71d46a
1 /* $Id: upnppinhole.c,v 1.4 2012/05/08 20:41:45 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2012 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
8 #include <stdlib.h>
9 #include <string.h>
10 #include <syslog.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <net/if.h>
15 #include <arpa/inet.h>
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <unistd.h>
21 #include "macros.h"
22 #include "config.h"
23 #include "upnpredirect.h"
24 #include "upnpglobalvars.h"
25 #include "upnpevents.h"
26 #if defined(USE_NETFILTER)
27 #include "netfilter/iptpinhole.h"
28 #endif
29 #if defined(USE_PF)
30 #include "pf/pfpinhole.h"
31 #endif
32 #if defined(USE_IPF)
33 #endif
34 #if defined(USE_IPFW)
35 #endif
37 #ifdef ENABLE_6FC_SERVICE
38 #if 0
39 int
40 upnp_check_outbound_pinhole(int proto, int * timeout)
42 int s, tmptimeout, tmptime_out;
43 switch(proto)
45 case IPPROTO_UDP:
46 s = retrieve_timeout("udp_timeout", timeout);
47 return s;
48 break;
49 case IPPROTO_UDPLITE:
50 s = retrieve_timeout("udp_timeout_stream", timeout);
51 return s;
52 break;
53 case IPPROTO_TCP:
54 s = retrieve_timeout("tcp_timeout_established", timeout);
55 return s;
56 break;
57 case 65535:
58 s = retrieve_timeout("udp_timeout", timeout);
59 s = retrieve_timeout("udp_timeout_stream", &tmptimeout);
60 s = retrieve_timeout("tcp_timeout_established", &tmptime_out);
61 if(tmptimeout<tmptime_out)
63 if(tmptimeout<*timeout)
64 *timeout = tmptimeout;
66 else
68 if(tmptime_out<*timeout)
69 *timeout = tmptimeout;
71 return s;
72 break;
73 default:
74 return -5;
75 break;
77 return 0;
79 #endif
81 /* upnp_add_inboundpinhole()
82 * returns: 0 on success
83 * -1 failed to add pinhole
84 * -2 already created
85 * -3 inbound pinhole disabled
86 * TODO : return uid on success (positive) or error value (negative)
88 int
89 upnp_add_inboundpinhole(const char * raddr,
90 unsigned short rport,
91 const char * iaddr,
92 unsigned short iport,
93 int proto,
94 unsigned int leasetime,
95 int * uid)
97 int r;
98 time_t current;
99 unsigned int timestamp;
100 struct in6_addr address;
102 if(inet_pton(AF_INET6, iaddr, &address) < 0)
104 syslog(LOG_ERR, "inet_pton(%s) : %m", iaddr);
105 return 0;
107 current = time(NULL);
108 timestamp = current + leasetime;
109 r = 0;
111 #if 0
112 if(r == 1 && strcmp(iaddr, iaddr_old)==0 && iport==iport_old)
114 syslog(LOG_INFO, "Pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with protocol %s already done. Updating it.", raddr, rport, iaddr_old, iport_old, protocol);
115 t = upnp_update_inboundpinhole(idfound, leaseTime);
116 *uid = atoi(idfound);
117 return t;
119 else
120 #endif
122 #if defined(USE_PF) || defined(USE_NETFILTER)
123 *uid = add_pinhole (0/*ext_if_name*/, raddr, rport,
124 iaddr, iport, proto, timestamp);
125 return 1;
126 #else
127 return -42; /* not implemented */
128 #endif
132 #if 0
134 upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
135 const char * iaddr, unsigned short iport,
136 const char * proto, int * uid)
138 int c = 9999;
139 char cmd[256], cmd_raw[256], cuid[42];
140 #if 0
141 static const char cmdval_full_udptcp[] = "ip6tables -I %s %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j ACCEPT";
142 static const char cmdval_udptcp[] = "ip6tables -I %s %d -p %s -i %s --sport %hu -d %s --dport %hu -j ACCEPT";
143 static const char cmdval_full_udplite[] = "ip6tables -I %s %d -p %s -i %s -s %s -d %s -j ACCEPT";
144 static const char cmdval_udplite[] = "ip6tables -I %s %d -p %s -i %s -d %s -j ACCEPT";
145 // raw table command
146 static const char cmdval_full_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j TRACE";
147 static const char cmdval_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s --sport %hu -d %s --dport %hu -j TRACE";
148 static const char cmdval_full_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s -d %s -j TRACE";
149 static const char cmdval_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -d %s -j TRACE";
150 #endif
151 /*printf("%s\n", raddr);*/
152 if(raddr!=NULL)
154 #ifdef IPPROTO_UDPLITE
155 if(atoi(proto) == IPPROTO_UDPLITE)
157 /* snprintf(cmd, sizeof(cmd), cmdval_full_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, iaddr);
158 snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udplite_raw, line_number, proto, ext_if_name, raddr, iaddr);*/
160 else
161 #endif
163 /* snprintf(cmd, sizeof(cmd), cmdval_full_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);
164 snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udptcp_raw, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);*/
167 else
169 #ifdef IPPROTO_UDPLITE
170 if(atoi(proto) == IPPROTO_UDPLITE)
172 /*snprintf(cmd, sizeof(cmd), cmdval_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, iaddr);
173 snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udplite_raw, line_number, proto, ext_if_name, iaddr);*/
175 else
176 #endif
178 /*snprintf(cmd, sizeof(cmd), cmdval_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, rport, iaddr, iport);
179 snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udptcp_raw, line_number, proto, ext_if_name, rport, iaddr, iport);
183 #ifdef DEBUG
184 syslog(LOG_INFO, "Adding following ip6tables rule:");
185 syslog(LOG_INFO, " -> %s", cmd);
186 syslog(LOG_INFO, " -> %s", cmd_raw);
187 #endif
188 /* TODO Add a better checking error.*/
189 if(system(cmd) < 0 || system(cmd_raw) < 0)
191 return 0;
193 srand(time(NULL));
194 snprintf(cuid, sizeof(cuid), "%.4d", rand()%c);
195 *uid = atoi(cuid);
196 printf("\t_add_ uid: %s\n", cuid);
197 return 1;
199 #endif
201 /* upnp_get_pinhole_info()
202 * return values :
203 * 0 OK
204 * -1 Internal error
205 * -2 NOT FOUND (no such entry)
206 * ..
207 * -42 Not implemented
210 upnp_get_pinhole_info(unsigned short uid,
211 char * raddr, int raddrlen,
212 unsigned short * rport,
213 char * iaddr, int iaddrlen,
214 unsigned short * iport,
215 int * proto,
216 unsigned int * leasetime,
217 unsigned int * packets)
219 /* Call Firewall specific code to get IPv6 pinhole infos */
220 #if defined(USE_PF) || defined(USE_NETFILTER)
221 int r;
222 unsigned int timestamp;
223 u_int64_t packets_tmp;
224 /*u_int64_t bytes_tmp;*/
226 r = get_pinhole_info(uid, raddr, raddrlen, rport,
227 iaddr, iaddrlen, iport, proto,
228 leasetime ? &timestamp : NULL,
229 packets ? &packets_tmp : NULL,
230 NULL/*&bytes_tmp*/);
231 if(r >= 0) {
232 if(leasetime) {
233 time_t current_time;
234 current_time = time(NULL);
235 if(timestamp > (unsigned int)current_time)
236 *leasetime = timestamp - current_time;
237 else
238 *leasetime = 0;
240 if(packets)
241 *packets = (unsigned int)packets_tmp;
243 return r;
244 #else
245 UNUSED(uid);
246 UNUSED(raddr); UNUSED(raddrlen); UNUSED(rport);
247 UNUSED(iaddr); UNUSED(iaddrlen); UNUSED(iport);
248 UNUSED(proto); UNUSED(leasetime); UNUSED(packets);
249 return -42; /* not implemented */
250 #endif
254 upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime)
256 #if defined(USE_PF) || defined(USE_NETFILTER)
257 unsigned int timestamp;
259 timestamp = time(NULL) + leasetime;
260 return update_pinhole(uid, timestamp);
261 #else
262 UNUSED(uid); UNUSED(leasetime);
264 return -42; /* not implemented */
265 #endif
269 upnp_delete_inboundpinhole(unsigned short uid)
271 #if defined(USE_PF) || defined(USE_NETFILTER)
272 return delete_pinhole(uid);
273 #else
274 UNUSED(uid);
276 return -1;
277 #endif
280 #if 0
282 * Result:
283 * 1: Found Result
284 * -4: No result
285 * -5: Result in another table
286 * -6: Result in another chain
287 * -7: Result in a chain not a rule
290 upnp_check_pinhole_working(const char * uid,
291 char * eaddr,
292 char * iaddr,
293 unsigned short * eport,
294 unsigned short * iport,
295 char * protocol,
296 int * rulenum_used)
298 /* TODO : to be implemented */
299 #if 0
300 FILE * fd;
301 time_t expire = time(NULL);
302 char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]="";
303 int res = -4, str_len;
305 str_len = strftime(expire_time, sizeof(expire_time), "%b %d %H:%M:%S", localtime(&expire));
307 fd = fopen(filename, "r");
308 if (fd==NULL)
310 syslog(LOG_ERR, "Get_rule: could not open file: %s", filename);
311 return -1;
314 syslog(LOG_INFO, "Get_rule: Starting getting info in file %s for %s\n", filename, uid);
315 buf[sizeof(buf)-1] = 0;
316 while(fgets(buf, sizeof(buf)-1, fd) != NULL && res != 1)
318 //printf("line: %s\n", buf);
319 char * r, * t, * c, * p;
320 // looking for something like filter:FORWARD:rule: or filter:MINIUPNPD:rule:
321 r = strstr(buf, ":rule:");
322 p = strstr(buf, ":policy:");
323 t = strstr(buf, "TRACE:"); // table pointeur
324 t += 7;
325 c = t + 7; // chain pointeur
326 if(r)
328 printf("\t** Found %.*s\n", 24 ,t);
329 char * src, * dst, * sport, * dport, * proto, * line;
330 char time[15]="", src_addr[40], dst_addr[40], proto_tmp[8];
331 int proto_int;
332 strncpy(time, buf, sizeof(time));
333 /*if(compare_time(time, expire_time)<0)
335 printf("\t\tNot corresponding time\n");
336 continue;
339 line = r + 6;
340 printf("\trule line = %d\n", atoi(line));
342 src = strstr(buf, "SRC=");
343 src += 4;
344 snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src);
345 #if 0
346 del_char(src_addr);
347 add_char(src_addr);
348 #endif
350 dst = strstr(buf, "DST=");
351 dst += 4;
352 snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst);
353 #if 0
354 del_char(dst_addr);
355 add_char(dst_addr);
356 #endif
358 proto = strstr(buf, "PROTO=");
359 proto += 6;
360 proto_int = atoi(protocol);
361 if(proto_int == IPPROTO_UDP)
362 strcpy(proto_tmp, "UDP");
363 else if(proto_int == IPPROTO_TCP)
364 strcpy(proto_tmp, "TCP");
365 #ifdef IPPROTO_UDPLITE
366 else if(proto_int == IPPROTO_UDPLITE)
367 strcpy(proto_tmp, "UDPLITE");
368 #endif
369 else
370 strcpy(proto_tmp, "UnsupportedProto");
372 // printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto);
373 // printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto);
374 // TODO Check time
375 // Check that the paquet found in trace correspond to the one we are looking for
376 if( /*(strcmp(eaddr, src_addr) == 0) &&*/ (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, strlen(proto_tmp))==0))
378 sport = strstr(buf, "SPT=");
379 sport += 4;
380 dport = strstr(buf, "DPT=");
381 dport += 4;
382 printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport));
383 printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport));
384 if(/*eport != atoi(sport) &&*/ *iport != atoi(dport))
386 printf("\t\tPort not corresponding\n");
387 continue;
389 printf("\ttable found: %.*s\n", 6, t);
390 printf("\tchain found: %.*s\n", 9, c);
391 // Check that the table correspond to the filter table
392 if(strncmp(t, "filter", 6)==0)
394 // Check that the table correspond to the MINIUPNP table
395 if(strncmp(c, "MINIUPNPD", 9)==0)
397 *rulenum_used = atoi(line);
398 res = 1;
400 else
402 res = -6;
403 continue;
406 else
408 res = -5;
409 continue;
412 else
414 printf("Packet information not corresponding\n");
415 continue;
418 if(!r && p)
420 printf("\t** Policy case\n");
421 char * src, * dst, * sport, * dport, * proto, * line;
422 char time[15], src_addr[40], dst_addr[40], proto_tmp[8];
423 int proto_int;
424 strncpy(time, buf, sizeof(time));
425 /*if(compare_time(time, expire_time)<0)
427 printf("\t\tNot corresponding time\n");
428 continue;
431 line = p + 8;
432 printf("\trule line = %d\n", atoi(line));
434 src = strstr(buf, "SRC=");
435 src += 4;
436 snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src);
437 #if 0
438 del_char(src_addr);
439 add_char(src_addr);
440 #endif
442 dst = strstr(buf, "DST=");
443 dst += 4;
444 snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst);
445 #if 0
446 del_char(dst_addr);
447 add_char(dst_addr);
448 #endif
450 proto = strstr(buf, "PROTO=");
451 proto += 6;
452 proto_int = atoi(protocol);
453 if(proto_int == IPPROTO_UDP)
454 strcpy(proto_tmp, "UDP");
455 else if(proto_int == IPPROTO_TCP)
456 strcpy(proto_tmp, "TCP");
457 #ifdef IPPROTO_UDPLITE
458 else if(proto_int == IPPROTO_UDPLITE)
459 strcpy(proto_tmp, "UDPLITE");
460 #endif
461 else
462 strcpy(proto_tmp, "UnsupportedProto");
464 // printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto);
465 // printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto);
466 // Check that the paquet found in trace correspond to the one we are looking for
467 if( (strcmp(eaddr, src_addr) == 0) && (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, 5)==0))
469 sport = strstr(buf, "SPT=");
470 sport += 4;
471 dport = strstr(buf, "DPT=");
472 dport += 4;
473 printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport));
474 printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport));
475 if(*eport != atoi(sport) && *iport != atoi(dport))
477 printf("\t\tPort not corresponding\n");
478 continue;
480 else
482 printf("Find a corresponding policy trace in the chain: %.*s\n", 10, c);
483 res = -7;
484 continue;
487 else
488 continue;
491 fclose(fd);
492 return res;
493 #else
494 return -42; /* to be implemented */
495 #endif
497 #endif
500 upnp_clean_expired_pinholes(unsigned int * next_timestamp)
502 #if defined(USE_PF) || defined(USE_NETFILTER)
503 return clean_pinhole_list(next_timestamp);
504 #else
505 UNUSED(next_timestamp);
507 return 0; /* nothing to do */
508 #endif
510 #endif