Annotation of embedaddon/miniupnpd/upnppinhole.c, revision 1.1
1.1 ! misho 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 */
! 7:
! 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>
! 16:
! 17: #include <stdio.h>
! 18: #include <ctype.h>
! 19: #include <unistd.h>
! 20:
! 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
! 36:
! 37: #ifdef ENABLE_6FC_SERVICE
! 38: #if 0
! 39: int
! 40: upnp_check_outbound_pinhole(int proto, int * timeout)
! 41: {
! 42: int s, tmptimeout, tmptime_out;
! 43: switch(proto)
! 44: {
! 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)
! 62: {
! 63: if(tmptimeout<*timeout)
! 64: *timeout = tmptimeout;
! 65: }
! 66: else
! 67: {
! 68: if(tmptime_out<*timeout)
! 69: *timeout = tmptimeout;
! 70: }
! 71: return s;
! 72: break;
! 73: default:
! 74: return -5;
! 75: break;
! 76: }
! 77: return 0;
! 78: }
! 79: #endif
! 80:
! 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)
! 87: */
! 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)
! 96: {
! 97: int r;
! 98: time_t current;
! 99: unsigned int timestamp;
! 100: struct in6_addr address;
! 101:
! 102: if(inet_pton(AF_INET6, iaddr, &address) < 0)
! 103: {
! 104: syslog(LOG_ERR, "inet_pton(%s) : %m", iaddr);
! 105: return 0;
! 106: }
! 107: current = time(NULL);
! 108: timestamp = current + leasetime;
! 109: r = 0;
! 110:
! 111: #if 0
! 112: if(r == 1 && strcmp(iaddr, iaddr_old)==0 && iport==iport_old)
! 113: {
! 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;
! 118: }
! 119: else
! 120: #endif
! 121: {
! 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
! 129: }
! 130: }
! 131:
! 132: #if 0
! 133: int
! 134: upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
! 135: const char * iaddr, unsigned short iport,
! 136: const char * proto, int * uid)
! 137: {
! 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)
! 153: {
! 154: #ifdef IPPROTO_UDPLITE
! 155: if(atoi(proto) == IPPROTO_UDPLITE)
! 156: {
! 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);*/
! 159: }
! 160: else
! 161: #endif
! 162: {
! 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);*/
! 165: }
! 166: }
! 167: else
! 168: {
! 169: #ifdef IPPROTO_UDPLITE
! 170: if(atoi(proto) == IPPROTO_UDPLITE)
! 171: {
! 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);*/
! 174: }
! 175: else
! 176: #endif
! 177: {
! 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);
! 180: */
! 181: }
! 182: }
! 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)
! 190: {
! 191: return 0;
! 192: }
! 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;
! 198: }
! 199: #endif
! 200:
! 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
! 208: */
! 209: int
! 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)
! 218: {
! 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;*/
! 225:
! 226: r = get_pinhole_info(uid, raddr, raddrlen, rport,
! 227: iaddr, iaddrlen, iport, proto,
! 228: leasetime ? ×tamp : 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;
! 239: }
! 240: if(packets)
! 241: *packets = (unsigned int)packets_tmp;
! 242: }
! 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
! 251: }
! 252:
! 253: int
! 254: upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime)
! 255: {
! 256: #if defined(USE_PF) || defined(USE_NETFILTER)
! 257: unsigned int timestamp;
! 258:
! 259: timestamp = time(NULL) + leasetime;
! 260: return update_pinhole(uid, timestamp);
! 261: #else
! 262: UNUSED(uid); UNUSED(leasetime);
! 263:
! 264: return -42; /* not implemented */
! 265: #endif
! 266: }
! 267:
! 268: int
! 269: upnp_delete_inboundpinhole(unsigned short uid)
! 270: {
! 271: #if defined(USE_PF) || defined(USE_NETFILTER)
! 272: return delete_pinhole(uid);
! 273: #else
! 274: UNUSED(uid);
! 275:
! 276: return -1;
! 277: #endif
! 278: }
! 279:
! 280: #if 0
! 281: /*
! 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
! 288: */
! 289: int
! 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)
! 297: {
! 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;
! 304:
! 305: str_len = strftime(expire_time, sizeof(expire_time), "%b %d %H:%M:%S", localtime(&expire));
! 306:
! 307: fd = fopen(filename, "r");
! 308: if (fd==NULL)
! 309: {
! 310: syslog(LOG_ERR, "Get_rule: could not open file: %s", filename);
! 311: return -1;
! 312: }
! 313:
! 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)
! 317: {
! 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)
! 327: {
! 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)
! 334: {
! 335: printf("\t\tNot corresponding time\n");
! 336: continue;
! 337: }*/
! 338:
! 339: line = r + 6;
! 340: printf("\trule line = %d\n", atoi(line));
! 341:
! 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
! 349:
! 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
! 357:
! 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");
! 371:
! 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))
! 377: {
! 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))
! 385: {
! 386: printf("\t\tPort not corresponding\n");
! 387: continue;
! 388: }
! 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)
! 393: {
! 394: // Check that the table correspond to the MINIUPNP table
! 395: if(strncmp(c, "MINIUPNPD", 9)==0)
! 396: {
! 397: *rulenum_used = atoi(line);
! 398: res = 1;
! 399: }
! 400: else
! 401: {
! 402: res = -6;
! 403: continue;
! 404: }
! 405: }
! 406: else
! 407: {
! 408: res = -5;
! 409: continue;
! 410: }
! 411: }
! 412: else
! 413: {
! 414: printf("Packet information not corresponding\n");
! 415: continue;
! 416: }
! 417: }
! 418: if(!r && p)
! 419: {
! 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)
! 426: {
! 427: printf("\t\tNot corresponding time\n");
! 428: continue;
! 429: }*/
! 430:
! 431: line = p + 8;
! 432: printf("\trule line = %d\n", atoi(line));
! 433:
! 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
! 441:
! 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
! 449:
! 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");
! 463:
! 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))
! 468: {
! 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))
! 476: {
! 477: printf("\t\tPort not corresponding\n");
! 478: continue;
! 479: }
! 480: else
! 481: {
! 482: printf("Find a corresponding policy trace in the chain: %.*s\n", 10, c);
! 483: res = -7;
! 484: continue;
! 485: }
! 486: }
! 487: else
! 488: continue;
! 489: }
! 490: }
! 491: fclose(fd);
! 492: return res;
! 493: #else
! 494: return -42; /* to be implemented */
! 495: #endif
! 496: }
! 497: #endif
! 498:
! 499: int
! 500: upnp_clean_expired_pinholes(unsigned int * next_timestamp)
! 501: {
! 502: #if defined(USE_PF) || defined(USE_NETFILTER)
! 503: return clean_pinhole_list(next_timestamp);
! 504: #else
! 505: UNUSED(next_timestamp);
! 506:
! 507: return 0; /* nothing to do */
! 508: #endif
! 509: }
! 510: #endif
! 511:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>