Example #1
0
static int get_pmp_pubaddr(char *pub_addr)
{
	int r = 0, i = 0, max = 5;
	natpmpresp_t response;
	char *pubaddr = NULL;
	fd_set fds;
	natpmp_t natpmp;
	const char *err = NULL;

	if ((r = initnatpmp(&natpmp)) < 0) {
		err = "init failed";
		goto end;
	}

	if ((r = sendpublicaddressrequest(&natpmp)) < 0) {
		err = "pub addr req failed";
		goto end;
	}

	do {
		struct timeval timeout = { 1, 0 };
		i++;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for PMP %d/%d\n", i, max);

		FD_ZERO(&fds);
		FD_SET(natpmp.s, &fds);

		if ((r = getnatpmprequesttimeout(&natpmp, &timeout)) < 0) {
			err = "get timeout failed";
			goto end;
		}

		if ((r = select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) < 0) {
			err = "select failed";
			goto end;
		}
		r = readnatpmpresponseorretry(&natpmp, &response);
	} while (r == NATPMP_TRYAGAIN && i < max);

	if (r < 0) {
		err = "general error";
		goto end;
	}

	pubaddr = inet_ntoa(response.pnu.publicaddress.addr);
	switch_copy_string(pub_addr, pubaddr, IP_LEN);
	nat_globals.nat_type = SWITCH_NAT_TYPE_PMP;

	closenatpmp(&natpmp);

  end:

	if (err) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error checking for PMP [%s]\n", err);
	}

	return r;
}
Example #2
0
void
tr_natpmpClose (tr_natpmp * nat)
{
    if (nat)
    {
        closenatpmp (&nat->natpmp);
        tr_free (nat);
    }
}
Example #3
0
void natpmp_uninit(struct natpmp_handle_t **handle)
{
	// Remove all port mapping associated with this host
	struct natpmp_handle_t *m = *handle;
	sendnewportmappingrequest(&m->natpmp, NATPMP_PROTOCOL_TCP, 0, 0, 0);
	sendnewportmappingrequest(&m->natpmp, NATPMP_PROTOCOL_UDP, 0, 0, 0);
	closenatpmp(&m->natpmp);
	free(*handle);
	*handle = NULL;
}
/** Tear down the NAT-PMP connection stored in <b>backend_state</b>.*/
int
tor_natpmp_cleanup(tor_fw_options_t *tor_fw_options, void *backend_state)
{
  natpmp_state_t *state = (natpmp_state_t *) backend_state;
  int r = 0;
  if (tor_fw_options->verbose)
    fprintf(stdout, "V: natpmp cleanup...\n");
  r = closenatpmp(&(state->natpmp));
  if (tor_fw_options->verbose)
    fprintf(stdout, "V: closing natpmp socket: %d\n", r);
  return r;
}
Example #5
0
static switch_status_t switch_nat_add_mapping_pmp(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t * external_port)
{
	switch_status_t status = SWITCH_STATUS_FALSE;
	natpmpresp_t response;
	int r;
	natpmp_t natpmp;

	initnatpmp(&natpmp);

	if (proto == SWITCH_NAT_TCP) {
		sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_TCP, port, port, 31104000);
	} else if (proto == SWITCH_NAT_UDP) {
		sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_UDP, port, port, 31104000);
	}

	do {
		fd_set fds;
		struct timeval timeout = { 1, 0 };
		FD_ZERO(&fds);
		FD_SET(natpmp.s, &fds);
		getnatpmprequesttimeout(&natpmp, &timeout);
		select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
		r = readnatpmpresponseorretry(&natpmp, &response);
	} while (r == NATPMP_TRYAGAIN);

	if (r == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "mapped public port %hu protocol %s to localport %hu\n",
						  response.pnu.newportmapping.mappedpublicport,
						  response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
						  (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : "UNKNOWN"), response.pnu.newportmapping.privateport);
		if (external_port) {
			*external_port = response.pnu.newportmapping.mappedpublicport;
		} else if (response.pnu.newportmapping.mappedpublicport != response.pnu.newportmapping.privateport) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "External port %hu protocol %s was not available, it was instead mapped to %hu\n",
							  response.pnu.newportmapping.privateport,
							  response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
							  (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : "UNKNOWN"), response.pnu.newportmapping.mappedpublicport);
		}

		status = SWITCH_STATUS_SUCCESS;
	}

	closenatpmp(&natpmp);

	return status;
}
Example #6
0
static switch_status_t switch_nat_del_mapping_pmp(switch_port_t port, switch_nat_ip_proto_t proto)
{
	switch_status_t status = SWITCH_STATUS_FALSE;
	natpmpresp_t response;
	int r;
	natpmp_t natpmp;

	initnatpmp(&natpmp);

	if (proto == SWITCH_NAT_TCP) {
		sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_TCP, port, port, 0);
	} else if (proto == SWITCH_NAT_UDP) {
		sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_UDP, port, port, 0);
	}

	do {
		fd_set fds;
		struct timeval timeout;
		FD_ZERO(&fds);
		FD_SET(natpmp.s, &fds);
		getnatpmprequesttimeout(&natpmp, &timeout);
		select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
		r = readnatpmpresponseorretry(&natpmp, &response);
	} while (r == NATPMP_TRYAGAIN);

	if (r == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unmapped public port %hu protocol %s to localport %hu\n", response.pnu.newportmapping.privateport,	/* This might be wrong but its so 0 isn't displayed */
						  response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
						  (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : "UNKNOWN"), response.pnu.newportmapping.privateport);
		status = SWITCH_STATUS_SUCCESS;
	}

	closenatpmp(&natpmp);

	return status;
}
Example #7
0
/* sample code for using libnatpmp */
int main(int argc, char * * argv)
{
	natpmp_t natpmp;
	natpmpresp_t response;
	int r;
	int sav_errno;
	struct timeval timeout;
	fd_set fds;
	int i;
	int protocol = 0;
	uint16_t privateport = 0;
	uint16_t publicport = 0;
	uint32_t lifetime = 3600;
	int command = 0;
	int forcegw = 0;
	in_addr_t gateway = 0;
	struct in_addr gateway_in_use;

#ifdef WIN32
	WSADATA wsaData;
	int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if(nResult != NO_ERROR)
	{
		fprintf(stderr, "WSAStartup() failed.\n");
		return -1;
	}
#endif

	/* argument parsing */
	for(i=1; i<argc; i++) {
		if(argv[i][0] == '-') {
			switch(argv[i][1]) {
			case 'h':
				usage(stdout, argv[0]);
				return 0;
			case 'g':
				forcegw = 1;
				if(argc < i + 1) {
					fprintf(stderr, "Not enough arguments for option -%c\n", argv[i][1]);
					return 1;
				}
				gateway = inet_addr(argv[++i]);
				break;
			case 'a':
				command = 'a';
				if(argc < i + 4) {
					fprintf(stderr, "Not enough arguments for option -%c\n", argv[i][1]);
					return 1;
				}
				i++;
				if(1 != sscanf(argv[i], "%hu", &publicport)) {
					fprintf(stderr, "%s is not a correct 16bits unsigned integer\n", argv[i]);
					return 1;
				}
				i++;
				if(1 != sscanf(argv[i], "%hu", &privateport)) {
					fprintf(stderr, "%s is not a correct 16bits unsigned integer\n", argv[i]);
					return 1;
				}
				i++;
				if(0 == strcasecmp(argv[i], "tcp"))
					protocol = NATPMP_PROTOCOL_TCP;
				else if(0 == strcasecmp(argv[i], "udp"))
					protocol = NATPMP_PROTOCOL_UDP;
				else {
					fprintf(stderr, "%s is not a valid protocol\n", argv[i]);
					return 1;
				}
				if(argc > i + 1) {
					if(1 != sscanf(argv[i+1], "%u", &lifetime)) {
						fprintf(stderr, "%s is not a correct 32bits unsigned integer\n", argv[i]);
					} else {
						i++;
					}
				}
				break;
			default:
				fprintf(stderr, "Unknown option %s\n", argv[i]);
				usage(stderr, argv[0]);
				return 1;
			}
		} else {
			fprintf(stderr, "Unknown option %s\n", argv[i]);
			usage(stderr, argv[0]);
			return 1;
		}
	}

	/* initnatpmp() */
	r = initnatpmp(&natpmp, forcegw, gateway);
	printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS");
	if(r<0)
		return 1;

	gateway_in_use.s_addr = natpmp.gateway;
	printf("using gateway : %s\n", inet_ntoa(gateway_in_use));

	/* sendpublicaddressrequest() */
	r = sendpublicaddressrequest(&natpmp);
	printf("sendpublicaddressrequest returned %d (%s)\n",
	       r, r==2?"SUCCESS":"FAILED");
	if(r<0)
		return 1;

	do {
		FD_ZERO(&fds);
		FD_SET(natpmp.s, &fds);
		getnatpmprequesttimeout(&natpmp, &timeout);
		r = select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
		if(r<0) {
			fprintf(stderr, "select()");
			return 1;
		}
		r = readnatpmpresponseorretry(&natpmp, &response);
		sav_errno = errno;
		printf("readnatpmpresponseorretry returned %d (%s)\n",
		       r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
		if(r<0 && r!=NATPMP_TRYAGAIN) {
#ifdef ENABLE_STRNATPMPERR
			fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n",
			        strnatpmperr(r));
#endif
			fprintf(stderr, "  errno=%d '%s'\n",
			        sav_errno, strerror(sav_errno));
		}
	} while(r==NATPMP_TRYAGAIN);
	if(r<0)
		return 1;

	/* TODO : check that response.type == 0 */
	printf("Public IP address : %s\n", inet_ntoa(response.pnu.publicaddress.addr));
	printf("epoch = %u\n", response.epoch);

	if(command == 'a') {
		/* sendnewportmappingrequest() */
		r = sendnewportmappingrequest(&natpmp, protocol,
        	                      privateport, publicport,
								  lifetime);
		printf("sendnewportmappingrequest returned %d (%s)\n",
		       r, r==12?"SUCCESS":"FAILED");
		if(r < 0)
			return 1;

		do {
			FD_ZERO(&fds);
			FD_SET(natpmp.s, &fds);
			getnatpmprequesttimeout(&natpmp, &timeout);
			select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
			r = readnatpmpresponseorretry(&natpmp, &response);
			printf("readnatpmpresponseorretry returned %d (%s)\n",
			       r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED"));
		} while(r==NATPMP_TRYAGAIN);
		if(r<0) {
#ifdef ENABLE_STRNATPMPERR
			fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n",
			        strnatpmperr(r));
#endif
			return 1;
		}

		printf("Mapped public port %hu protocol %s to local port %hu "
		       "liftime %u\n",
	    	   response.pnu.newportmapping.mappedpublicport,
			   response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
			    (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" :
			     "UNKNOWN"),
			   response.pnu.newportmapping.privateport,
			   response.pnu.newportmapping.lifetime);
		printf("epoch = %u\n", response.epoch);
	}

	r = closenatpmp(&natpmp);
	printf("closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED");
	if(r<0)
		return 1;

	return 0;
}
NATPMPInterface::~NATPMPInterface() {
	closenatpmp(&p->natpmp);
}