/* upnp_add_inboundpinhole() * returns: 0 on success * -1 failed to add pinhole * -2 already created * -3 inbound pinhole disabled */ int upnp_add_inboundpinhole(const char * raddr, unsigned short rport, const char * iaddr, unsigned short iport, const char * protocol, const char * leaseTime, int * uid) { int r, s, t, lt=0; char iaddr_old[40]="", proto[6]="", idfound[5]="", leaseTmp[12]; // IPv6 Modification snprintf(proto, sizeof(proto), "%.5d", atoi(protocol)); unsigned short iport_old = 0; time_t current = time(NULL); /*struct in6_addr address; // IPv6 Modification if(inet_pton(AF_INET6, iaddr, &address) < 0) // IPv6 Modification { return 0; }*/ #if 0 r = get_rule_from_file(raddr, rport, iaddr_old, &iport_old, proto, 0, 0, idfound); #endif r = 0; lt = (int) current + atoi(leaseTime); snprintf(leaseTmp, sizeof(leaseTmp), "%d", lt); NP_UPNP_DEBUG("LeaseTime: %d / %d -> %s\n", atoi(leaseTime), (int)current, leaseTmp); NP_UPNP_DEBUG("\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) { NP_UPNP_DEBUG("Pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with protocol %s already done. Updating it.\n", raddr, rport, iaddr_old, iport_old, protocol); t = upnp_update_inboundpinhole(idfound, leaseTime); *uid = atoi(idfound); return t; } else { NP_UPNP_DEBUG("Adding pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with protocol %s and %s lease time.\n", 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; }
/* upnp_add_inboundpinhole() * returns: 1 on success * -1 Pinhole space exhausted * -4 invalid arguments * -42 not implemented * TODO : return uid on success (positive) or error value (negative) */ int upnp_add_inboundpinhole(const char * raddr, unsigned short rport, const char * iaddr, unsigned short iport, int proto, char * desc, unsigned int leasetime, int * uid) { int r; time_t current; unsigned int timestamp; struct in6_addr address; r = inet_pton(AF_INET6, iaddr, &address); if(r <= 0) { syslog(LOG_ERR, "inet_pton(%d, %s, %p) FAILED", AF_INET6, iaddr, &address); return -4; } current = time(NULL); timestamp = current + leasetime; r = 0; *uid = upnp_find_inboundpinhole(raddr, rport, iaddr, iport, proto, NULL, 0, NULL); if(*uid >= 0) { syslog(LOG_INFO, "Pinhole for inbound traffic from [%s]:%hu to [%s]:%hu with proto %d found uid=%d. Updating it.", raddr, rport, iaddr, iport, proto, *uid); r = upnp_update_inboundpinhole(*uid, timestamp); return (r >= 0) ? 1 : r; } #if defined(USE_PF) || defined(USE_NETFILTER) *uid = add_pinhole (0/*ext_if_name*/, raddr, rport, iaddr, iport, proto, desc, timestamp); return *uid >= 0 ? 1 : -1; #else return -42; /* not implemented */ #endif }