--- embedaddon/miniupnpd/upnpredirect.c 2012/05/29 12:55:57 1.1.1.2 +++ embedaddon/miniupnpd/upnpredirect.c 2013/07/22 00:32:35 1.1.1.3 @@ -1,7 +1,7 @@ -/* $Id: upnpredirect.c,v 1.1.1.2 2012/05/29 12:55:57 misho Exp $ */ +/* $Id: upnpredirect.c,v 1.1.1.3 2013/07/22 00:32:35 misho Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2011 Thomas Bernard + * (c) 2006-2012 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -18,6 +18,7 @@ #include #include +#include "macros.h" #include "config.h" #include "upnpredirect.h" #include "upnpglobalvars.h" @@ -47,7 +48,7 @@ #define PRIu64 "llu" #endif -/* proto_atoi() +/* proto_atoi() * convert the string "UDP" or "TCP" to IPPROTO_UDP and IPPROTO_UDP */ static int proto_atoi(const char * protocol) @@ -81,7 +82,7 @@ lease_file_add(unsigned short eport, ((proto==IPPROTO_TCP)?"TCP":"UDP"), eport, iaddr, iport, timestamp, desc); fclose(fd); - + return 0; } @@ -133,14 +134,14 @@ lease_file_remove(unsigned short eport, int proto) } fclose(fdt); fclose(fd); - + if (rename(tmpfilename, lease_file) < 0) { syslog(LOG_ERR, "could not rename temporary lease file to %s", lease_file); remove(tmpfilename); } - + return 0; - + } /* reload_from_lease_file() @@ -194,7 +195,7 @@ int reload_from_lease_file() continue; } *(p++) = '\0'; - timestamp = (unsigned int)atoi(p); + iport = (unsigned short)atoi(p); p = strchr(p, ':'); if(!p) { syslog(LOG_ERR, "unrecognized data in lease file"); @@ -207,7 +208,8 @@ int reload_from_lease_file() continue; } *(desc++) = '\0'; - iport = (unsigned short)atoi(p); + /*timestamp = (unsigned int)atoi(p);*/ + timestamp = (unsigned int)strtoul(p, NULL, 10); /* trim description */ while(isspace(*desc)) desc++; @@ -218,11 +220,11 @@ int reload_from_lease_file() *(p--) = '\0'; if(timestamp > 0) { - if(timestamp <= current_time) { + if(timestamp <= (unsigned int)current_time) { syslog(LOG_NOTICE, "already expired lease in lease file"); continue; } else { - leaseduration = current_time - timestamp; + leaseduration = timestamp - current_time; } } else { leaseduration = 0; /* default value */ @@ -239,12 +241,12 @@ int reload_from_lease_file() } } fclose(fd); - + return 0; } #endif -/* upnp_redirect() +/* upnp_redirect() * calls OS/fw dependant implementation of the redirection. * protocol should be the string "TCP" or "UDP" * returns: 0 on success @@ -253,7 +255,7 @@ int reload_from_lease_file() * -3 permission check failed */ int -upnp_redirect(const char * rhost, unsigned short eport, +upnp_redirect(const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, const char * protocol, const char * desc, unsigned int leaseduration) @@ -295,7 +297,7 @@ upnp_redirect(const char * rhost, unsigned short eport } else { timestamp = (leaseduration > 0) ? time(NULL) + leaseduration : 0; syslog(LOG_INFO, "redirecting port %hu to %s:%hu protocol %s for: %s", - eport, iaddr, iport, protocol, desc); + eport, iaddr, iport, protocol, desc); return upnp_redirect_internal(rhost, eport, iaddr, iport, proto, desc, timestamp); } @@ -363,7 +365,9 @@ upnp_get_redirection_infos(unsigned short eport, const iaddr, iaddrlen, iport, desc, desclen, rhost, rhostlen, ×tamp, 0, 0); - if(r == 0 && timestamp > 0 && timestamp > (current_time = time(NULL))) { + if(r == 0 && + timestamp > 0 && + timestamp > (unsigned int)(current_time = time(NULL))) { *leaseduration = timestamp - current_time; } else { *leaseduration = 0; @@ -374,7 +378,7 @@ upnp_get_redirection_infos(unsigned short eport, const int upnp_get_redirection_infos_by_index(int index, unsigned short * eport, char * protocol, - unsigned short * iport, + unsigned short * iport, char * iaddr, int iaddrlen, char * desc, int desclen, char * rhost, int rhostlen, @@ -387,7 +391,7 @@ upnp_get_redirection_infos_by_index(int index, if(desc && (desclen > 0)) desc[0] = '\0'; - if(rhost && (rhost > 0)) + if(rhost && (rhostlen > 0)) rhost[0] = '\0'; if(get_redirect_rule_by_index(index, 0/*ifname*/, eport, iaddr, iaddrlen, iport, &proto, desc, desclen, @@ -397,7 +401,7 @@ upnp_get_redirection_infos_by_index(int index, else { current_time = time(NULL); - *leaseduration = (timestamp > current_time) + *leaseduration = (timestamp > (unsigned int)current_time) ? (timestamp - current_time) : 0; if(proto == IPPROTO_TCP) @@ -485,9 +489,9 @@ get_upnp_rules_state_list(int max_rules_number_target) tmp->to_remove = 0; if(timestamp > 0) { /* need to remove this port mapping ? */ - if(timestamp <= current_time) + if(timestamp <= (unsigned int)current_time) tmp->to_remove = 1; - else if((nextruletoclean_timestamp <= current_time) + else if((nextruletoclean_timestamp <= (unsigned int)current_time) || (timestamp < nextruletoclean_timestamp)) nextruletoclean_timestamp = timestamp; } @@ -576,526 +580,6 @@ upnp_get_portmappings_in_range(unsigned short startpor return NULL; return get_portmappings_in_range(startport, endport, proto, number); } - -#ifdef ENABLE_6FC_SERVICE -int -upnp_check_outbound_pinhole(int proto, int * timeout) -{ -#if 0 - int s, tmptimeout, tmptime_out; - switch(proto) - { - case IPPROTO_UDP: - s = retrieve_timeout("udp_timeout", timeout); - return s; - break; - case IPPROTO_UDPLITE: - s = retrieve_timeout("udp_timeout_stream", timeout); - return s; - break; - case IPPROTO_TCP: - s = retrieve_timeout("tcp_timeout_established", timeout); - return s; - break; - case 65535: - s = retrieve_timeout("udp_timeout", timeout); - s = retrieve_timeout("udp_timeout_stream", &tmptimeout); - s = retrieve_timeout("tcp_timeout_established", &tmptime_out); - if(tmptimeout %s\n", atoi(leaseTime), (int)current, leaseTmp); - - printf("\tCompare addr: %s // port: %d\n\t to addr: %s // port: %d\n", iaddr, iport, iaddr_old, iport_old); - if(r == 1 && strcmp(iaddr, iaddr_old)==0 && iport==iport_old) - { - 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); - t = upnp_update_inboundpinhole(idfound, leaseTime); - *uid = atoi(idfound); - return t; - } - else - { - syslog(LOG_INFO, "Adding pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with protocol %s and %s lease time.", raddr, rport, iaddr, iport, protocol, leaseTime); - s = upnp_add_inboundpinhole_internal(raddr, rport, iaddr, iport, protocol, uid); -#if 0 - if(rule_file_add(raddr, rport, iaddr, iport, protocol, leaseTmp, uid)<0) - return -8; - else - { - if(nextpinholetoclean_timestamp == 0 || (atoi(leaseTmp) <= nextpinholetoclean_timestamp)) - { - printf("Initializing the nextpinholetoclean variables. uid = %d\n", *uid); - snprintf(nextpinholetoclean_uid, 5, "%.4d", *uid); - nextpinholetoclean_timestamp = atoi(leaseTmp); - } - return s; - } -#endif - } -return 0; -} - -int -upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport, - const char * iaddr, unsigned short iport, - const char * proto, int * uid) -{ - int c = 9999; - char cmd[256], cmd_raw[256], cuid[42]; -#if 0 - static const char cmdval_full_udptcp[] = "ip6tables -I %s %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j ACCEPT"; - static const char cmdval_udptcp[] = "ip6tables -I %s %d -p %s -i %s --sport %hu -d %s --dport %hu -j ACCEPT"; - static const char cmdval_full_udplite[] = "ip6tables -I %s %d -p %s -i %s -s %s -d %s -j ACCEPT"; - static const char cmdval_udplite[] = "ip6tables -I %s %d -p %s -i %s -d %s -j ACCEPT"; - // raw table command - 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"; - static const char cmdval_udptcp_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s --sport %hu -d %s --dport %hu -j TRACE"; - static const char cmdval_full_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s -d %s -j TRACE"; - static const char cmdval_udplite_raw[] = "ip6tables -t raw -I PREROUTING %d -p %s -i %s -d %s -j TRACE"; -#endif - //printf("%s\n", raddr); - if(raddr!=NULL) - { -#ifdef IPPROTO_UDPLITE - if(atoi(proto) == IPPROTO_UDPLITE) - { - /* snprintf(cmd, sizeof(cmd), cmdval_full_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, iaddr); - snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udplite_raw, line_number, proto, ext_if_name, raddr, iaddr);*/ - } - else -#endif - { - /* snprintf(cmd, sizeof(cmd), cmdval_full_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, rport, iaddr, iport); - snprintf(cmd_raw, sizeof(cmd_raw), cmdval_full_udptcp_raw, line_number, proto, ext_if_name, raddr, rport, iaddr, iport);*/ - } - } - else - { -#ifdef IPPROTO_UDPLITE - if(atoi(proto) == IPPROTO_UDPLITE) - { - /*snprintf(cmd, sizeof(cmd), cmdval_udplite, miniupnpd_forward_chain, line_number, proto, ext_if_name, iaddr); - snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udplite_raw, line_number, proto, ext_if_name, iaddr);*/ - } - else -#endif - { - /*snprintf(cmd, sizeof(cmd), cmdval_udptcp, miniupnpd_forward_chain, line_number, proto, ext_if_name, rport, iaddr, iport); - snprintf(cmd_raw, sizeof(cmd_raw), cmdval_udptcp_raw, line_number, proto, ext_if_name, rport, iaddr, iport); -*/ - } - } -#ifdef DEBUG - syslog(LOG_INFO, "Adding following ip6tables rule:"); - syslog(LOG_INFO, " -> %s", cmd); - syslog(LOG_INFO, " -> %s", cmd_raw); -#endif - // TODO Add a better checking error. - if(system(cmd) < 0 || system(cmd_raw) < 0) - { - return 0; - } - srand(time(NULL)); - snprintf(cuid, sizeof(cuid), "%.4d", rand()%c); - *uid = atoi(cuid); - printf("\t_add_ uid: %s\n", cuid); - return 1; -} - -int -upnp_get_pinhole_info(const char * raddr, - unsigned short rport, - char * iaddr, - unsigned short * iport, - char * proto, - const char * uid, - char * lt) -{ - /* TODO : to be done - * Call Firewall specific code to get IPv6 pinhole infos */ - return 0; -} - -int -upnp_update_inboundpinhole(const char * uid, const char * leasetime) -{ - /* TODO : to be implemented */ -#if 0 - int r, n; - syslog(LOG_INFO, "Updating pinhole for inbound traffic with ID: %s", uid); - r = check_rule_from_file(uid, 0); - if(r < 0) - return r; - else - { - n = rule_file_update(uid, leasetime); - upnp_update_expiredpinhole(); - return n; - } -#else - return -1; -#endif -} - -int -upnp_delete_inboundpinhole(const char * uid) -{ - /* TODO : to be implemented */ -#if 0 - /* this is a alpha implementation calling ip6tables via system(), - * it can be usefull as an example to code the netfilter version */ - int r, s, linenum=0; - char cmd[256], cmd_raw[256]; - syslog(LOG_INFO, "Removing pinhole for inbound traffic with ID: %s", uid); - r = check_rule_from_file(uid, &linenum); - if(r > 0) - { - s = rule_file_remove(uid, linenum); - if(s < 0) - return s; - else - { - snprintf(cmd, sizeof(cmd), "ip6tables -t filter -D %s %d", miniupnpd_forward_chain, linenum); - snprintf(cmd_raw, sizeof(cmd_raw), "ip6tables -t raw -D PREROUTING %d", linenum -1); -#ifdef DEBUG - syslog(LOG_INFO, "Deleting ip6tables rule:"); - syslog(LOG_INFO, " -> %s", cmd); - syslog(LOG_INFO, " -> %s", cmd_raw); -#endif - // TODO Add a better checking error. - if(system(cmd) < 0 || system(cmd_raw) < 0) - { - return 0; - } - } - } - upnp_update_expiredpinhole(); - return r; -#else -return -1; -#endif -} - -/* - * Result: - * 1: Found Result - * -4: No result - * -5: Result in another table - * -6: Result in another chain - * -7: Result in a chain not a rule -*/ -int -upnp_check_pinhole_working(const char * uid, - char * eaddr, - char * iaddr, - unsigned short * eport, - unsigned short * iport, - char * protocol, - int * rulenum_used) -{ - /* TODO : to be implemented */ -#if 0 - FILE * fd; - time_t expire = time(NULL); - char buf[1024], filename[] = "/var/log/kern.log", expire_time[32]=""; - int res = -4, str_len; - - str_len = strftime(expire_time, sizeof(expire_time), "%b %d %H:%M:%S", localtime(&expire)); - - fd = fopen(filename, "r"); - if (fd==NULL) - { - syslog(LOG_ERR, "Get_rule: could not open file: %s", filename); - return -1; - } - - syslog(LOG_INFO, "Get_rule: Starting getting info in file %s for %s\n", filename, uid); - buf[sizeof(buf)-1] = 0; - while(fgets(buf, sizeof(buf)-1, fd) != NULL && res != 1) - { - //printf("line: %s\n", buf); - char * r, * t, * c, * p; - // looking for something like filter:FORWARD:rule: or filter:MINIUPNPD:rule: - r = strstr(buf, ":rule:"); - p = strstr(buf, ":policy:"); - t = strstr(buf, "TRACE:"); // table pointeur - t += 7; - c = t + 7; // chain pointeur - if(r) - { - printf("\t** Found %.*s\n", 24 ,t); - char * src, * dst, * sport, * dport, * proto, * line; - char time[15]="", src_addr[40], dst_addr[40], proto_tmp[8]; - int proto_int; - strncpy(time, buf, sizeof(time)); - /*if(compare_time(time, expire_time)<0) - { - printf("\t\tNot corresponding time\n"); - continue; - }*/ - - line = r + 6; - printf("\trule line = %d\n", atoi(line)); - - src = strstr(buf, "SRC="); - src += 4; - snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src); -#if 0 - del_char(src_addr); - add_char(src_addr); -#endif - - dst = strstr(buf, "DST="); - dst += 4; - snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst); -#if 0 - del_char(dst_addr); - add_char(dst_addr); -#endif - - proto = strstr(buf, "PROTO="); - proto += 6; - proto_int = atoi(protocol); - if(proto_int == IPPROTO_UDP) - strcpy(proto_tmp, "UDP"); - else if(proto_int == IPPROTO_TCP) - strcpy(proto_tmp, "TCP"); -#ifdef IPPROTO_UDPLITE - else if(proto_int == IPPROTO_UDPLITE) - strcpy(proto_tmp, "UDPLITE"); -#endif - else - strcpy(proto_tmp, "UnsupportedProto"); - - // printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto); - // printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto); - // TODO Check time - // Check that the paquet found in trace correspond to the one we are looking for - if( /*(strcmp(eaddr, src_addr) == 0) &&*/ (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, strlen(proto_tmp))==0)) - { - sport = strstr(buf, "SPT="); - sport += 4; - dport = strstr(buf, "DPT="); - dport += 4; - printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport)); - printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport)); - if(/*eport != atoi(sport) &&*/ *iport != atoi(dport)) - { - printf("\t\tPort not corresponding\n"); - continue; - } - printf("\ttable found: %.*s\n", 6, t); - printf("\tchain found: %.*s\n", 9, c); - // Check that the table correspond to the filter table - if(strncmp(t, "filter", 6)==0) - { - // Check that the table correspond to the MINIUPNP table - if(strncmp(c, "MINIUPNPD", 9)==0) - { - *rulenum_used = atoi(line); - res = 1; - } - else - { - res = -6; - continue; - } - } - else - { - res = -5; - continue; - } - } - else - { - printf("Packet information not corresponding\n"); - continue; - } - } - if(!r && p) - { - printf("\t** Policy case\n"); - char * src, * dst, * sport, * dport, * proto, * line; - char time[15], src_addr[40], dst_addr[40], proto_tmp[8]; - int proto_int; - strncpy(time, buf, sizeof(time)); - /*if(compare_time(time, expire_time)<0) - { - printf("\t\tNot corresponding time\n"); - continue; - }*/ - - line = p + 8; - printf("\trule line = %d\n", atoi(line)); - - src = strstr(buf, "SRC="); - src += 4; - snprintf(src_addr, sizeof(src_addr), "%.*s", 39, src); -#if 0 - del_char(src_addr); - add_char(src_addr); -#endif - - dst = strstr(buf, "DST="); - dst += 4; - snprintf(dst_addr, sizeof(dst_addr), "%.*s", 39, dst); -#if 0 - del_char(dst_addr); - add_char(dst_addr); -#endif - - proto = strstr(buf, "PROTO="); - proto += 6; - proto_int = atoi(protocol); - if(proto_int == IPPROTO_UDP) - strcpy(proto_tmp, "UDP"); - else if(proto_int == IPPROTO_TCP) - strcpy(proto_tmp, "TCP"); -#ifdef IPPROTO_UDPLITE - else if(proto_int == IPPROTO_UDPLITE) - strcpy(proto_tmp, "UDPLITE"); -#endif - else - strcpy(proto_tmp, "UnsupportedProto"); - - // printf("\tCompare eaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", eaddr, proto_tmp, src_addr, strlen(proto_tmp), proto); - // printf("\tCompare iaddr: %s // protocol: %s\n\t to addr: %s // protocol: %.*s\n", iaddr, proto_tmp, dst_addr, strlen(proto_tmp), proto); - // Check that the paquet found in trace correspond to the one we are looking for - if( (strcmp(eaddr, src_addr) == 0) && (strcmp(iaddr, dst_addr) == 0) && (strncmp(proto_tmp, proto, 5)==0)) - { - sport = strstr(buf, "SPT="); - sport += 4; - dport = strstr(buf, "DPT="); - dport += 4; - printf("\tCompare eport: %hu\n\t to port: %d\n", *eport, atoi(sport)); - printf("\tCompare iport: %hu\n\t to port: %d\n", *iport, atoi(dport)); - if(*eport != atoi(sport) && *iport != atoi(dport)) - { - printf("\t\tPort not corresponding\n"); - continue; - } - else - { - printf("Find a corresponding policy trace in the chain: %.*s\n", 10, c); - res = -7; - continue; - } - } - else - continue; - } - } - fclose(fd); - return res; -#else - return -4; -#endif -} - -int -upnp_get_pinhole_packets(const char * uid, int * packets) -{ - /* TODO : to be implemented */ -#if 0 - int line=0, r; - char cmd[256]; - r = check_rule_from_file(uid, &line); - if(r < 0) - return r; - else - { - snprintf(cmd, sizeof(cmd), "ip6tables -L MINIUPNPD %d -v", line); - return retrieve_packets(cmd, &line, packets); - } -#else - return 0; -#endif -} - -int -upnp_update_expiredpinhole(void) -{ -#if 0 - int r; - char uid[5], leaseTime[12]; - - r = get_rule_from_leasetime(uid, leaseTime); - if(r<0) - return r; - else - { - strcpy(nextpinholetoclean_uid, uid); - nextpinholetoclean_timestamp = atoi(leaseTime); - return 1; - } -#endif - return 0; -} - -int -upnp_clean_expiredpinhole() -{ -#if 0 - upnp_delete_inboundpinhole(nextpinholetoclean_uid); - - return upnp_update_expiredpinhole(); -#endif - return 0; -} -#endif /* stuff for miniupnpdctl */ #ifdef USE_MINIUPNPDCTL