/* add a description to the list of redirection descriptions */ static void add_redirect_desc(unsigned short eport, int proto, const char * eaddr, const char * iaddr, unsigned short iport, const char * ifname, const char * desc, int enabled) { NP_UPNP_INFO("enter add_redirect_desc, enabled arg is %d\n", enabled); struct rdr_desc * p; size_t l; /* set a default description if none given */ if(!desc) desc = "miniupnpd"; l = strlen(desc) + 1; p = (struct rdr_desc *)malloc(sizeof(struct rdr_desc) + l); if(p) { p->next = rdr_desc_list; p->eport = eport; p->proto = (short)proto; p->enabled = enabled; memcpy(p->eaddr, eaddr, 16); memcpy(p->iaddr, iaddr, 16); p->iport = iport; memcpy(p->ifname, ifname, 16); memcpy(p->str, desc, (sizeof(p->str) < l)?sizeof(p->str):l); p->str[sizeof(p->str) - 1] = '\0'; rdr_desc_list = p; } /* begin 2030707506 zhoujianchun 00203875 2010-03-07 added for UPnP */ check_and_delete_last_entry(); /* end 2030707506 zhoujianchun 00203875 2010-03-07 added for UPnP */ #ifdef DEBUG list_redirect_rule(ext_if_name); #endif }
int main(int argc, char ** argv) { unsigned short eport, iport; const char * iaddr; printf("Usage %s <ext_port> <internal_ip> <internal_port>\n", argv[0]); if(argc<4) return -1; openlog("testiptcrdr", LOG_PERROR|LOG_CONS, LOG_LOCAL0); eport = (unsigned short)atoi(argv[1]); iaddr = argv[2]; iport = (unsigned short)atoi(argv[3]); printf("trying to redirect port %hu to %s:%hu\n", eport, iaddr, iport); if(addnatrule(IPPROTO_TCP, eport, iaddr, iport, NULL) < 0) return -1; if(add_filter_rule(IPPROTO_TCP, NULL, iaddr, iport) < 0) return -1; /* test */ { unsigned short p1, p2; char addr[16]; int proto2; char desc[256]; char rhost[256]; unsigned int timestamp; u_int64_t packets, bytes; desc[0] = '\0'; if(get_redirect_rule_by_index(0, "", &p1, addr, sizeof(addr), &p2, &proto2, desc, sizeof(desc), rhost, sizeof(rhost), ×tamp, &packets, &bytes) < 0) { printf("rule not found\n"); } else { printf("redirected port %hu to %s:%hu proto %d packets=%" PRIu64 " bytes=%" PRIu64 "\n", p1, addr, p2, proto2, packets, bytes); } } printf("trying to list nat rules :\n"); list_redirect_rule(argv[1]); printf("deleting\n"); delete_redirect_and_filter_rules(eport, IPPROTO_TCP); return 0; }
/* get_redirect_rule_by_index() * return -1 when the rule was not found */ int get_redirect_rule_by_index(int index, char * ifname, unsigned short * eport, char * iaddr, int iaddrlen, unsigned short * iport, int * proto, char * desc, int desclen, char * rhost, int rhostlen, unsigned int * timestamp, u_int64_t * packets, u_int64_t * bytes, int *penabled) { NP_UPNP_INFO("enter get_redirect_rule_by_index\n"); NP_UPNP_INFO("index is %d\n", index); #ifdef DEBUG list_redirect_rule(ext_if_name); #endif int i = 0; struct rdr_desc * p; if(!desc || (desclen == 0)) return -1; for(p = rdr_desc_list; p; p = p->next, i++) { if(i == index) { NP_UPNP_DEBUG("**** i == index ****\n"); if (ifname != NULL) strncpy(ifname, p->ifname, 16); if (eport != NULL) *eport = p->eport; if (iaddr != NULL) strncpy(iaddr, p->iaddr, iaddrlen); if (iport != NULL) *iport = p->iport; if (proto != NULL) *proto = (int)p->proto; if (desc != NULL) strncpy(desc, p->str, desclen); if(penabled != NULL) *penabled = p->enabled; return 0; } } return -1; }