From 24919cb8f418bcd6b911e5feda4d142368650de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 27 Sep 2017 21:50:34 +0200 Subject: [PATCH] refactor stun client (send/receive) --- src/apps/natdiscovery/natdiscovery.c | 696 ++++++++++++++------------- 1 file changed, 355 insertions(+), 341 deletions(-) diff --git a/src/apps/natdiscovery/natdiscovery.c b/src/apps/natdiscovery/natdiscovery.c index 49050d3..a33f5f6 100644 --- a/src/apps/natdiscovery/natdiscovery.c +++ b/src/apps/natdiscovery/natdiscovery.c @@ -1,32 +1,32 @@ /* - * Copyright (C) 2011, 2012, 2013 Citrix Systems - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ +* Copyright (C) 2011, 2012, 2013 Citrix Systems +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the project nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ #include #include @@ -44,37 +44,23 @@ #endif //////////////////////////////////////////////////// - static int udp_fd = -1; +static int udp_fd2 = -1; + static int counter = 0; #ifdef __cplusplus -static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780, int response_port, int change_ip, int change_port, int padding) -{ + +static int stunclient_send(int sockfd, ioa_addr *remote_addr, int change_ip, int change_port, int padding, int response_port){ int ret=0; - if (response_port >= 0) { - addr_set_port(local_addr, response_port); - } - udp_fd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0); - if (udp_fd < 0) - err(-1, NULL); - - if (!addr_any(local_addr)) { - if (addr_bind(udp_fd, local_addr,0,1,UDP_SOCKET) < 0) - err(-1, NULL); - } - - - - turn::StunMsgRequest req(STUN_METHOD_BINDING); req.constructBindingRequest(); if (response_port >= 0) { - turn::StunAttrResponsePort rpa; + turn::StunAttrResponsePort rpa; rpa.setResponsePort((u16bits)response_port); try { req.addAttr(rpa); @@ -128,15 +114,21 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr int slen = get_ioa_addr_len(remote_addr); do { - len = sendto(udp_fd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr*) remote_addr, (socklen_t) slen); + len = sendto(sockfd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr*) remote_addr, (socklen_t) slen); } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); if (len < 0) - err(-1, NULL); + err(-1, NULL); } - if (addr_get_from_sock(udp_fd, local_addr) < 0) { +} + + +static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780){ + int ret=0; + + if (addr_get_from_sock(sockfd, local_addr) < 0) { printf("%s: Cannot get address from local socket\n", __FUNCTION__); } else { *port = addr_get_port(local_addr); @@ -153,10 +145,10 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr tv.tv_sec = 3; /* 3 Secs Timeout */ tv.tv_usec = 0; // Not init'ing this can cause strange errors - setsockopt(udp_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); + setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); do { - len = recv(udp_fd, ptr, to_recv - recvd, 0); + len = recv(sockfd, ptr, to_recv - recvd, 0); if (len > 0) { recvd += len; ptr += len; @@ -165,7 +157,7 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr } while (len < 0 && (errno == EINTR)); if (recvd > 0) - len = recvd; + len = recvd; buf.len = len; try { @@ -196,7 +188,7 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr addr0.getAddr(mapped_addr); if (!addr_eq(mapped_addr,reflexive_addr)){ printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); - addr_debug_print(1, &mapped_addr, "Mapped Address: "); + addr_debug_print(1, &mapped_addr, "Mapped Address: "); } else { printf("No ALG: Mapped and XOR-Mapped is equal.\n"); } @@ -211,377 +203,399 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr addr2.getAddr(response_origin); addr_debug_print(1, &response_origin, "Response origin: "); - - addr_debug_print(1, other_addr, "Other addr: "); + + addr_debug_print(1, other_addr, "Other addr: "); + } + addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); + addr_debug_print(1, local_addr, "Local addr: "); + } else { + printf("Cannot read the response\n"); } - addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); - addr_debug_print(1, local_addr, "Local addr: "); } else { - printf("Cannot read the response\n"); + printf("Wrong type of response\n"); } } else { - printf("Wrong type of response\n"); + int err_code = res.getError(); + std::string reason = res.getReason(); + + printf("The response is an error %d (%s)\n", err_code, reason.c_str()); } } else { - int err_code = res.getError(); - std::string reason = res.getReason(); - - printf("The response is an error %d (%s)\n", err_code, reason.c_str()); + printf("The response is not a reponse message\n"); } - } else { - printf("The response is not a reponse message\n"); + } catch(...) { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("STUN receive timeout..\n"); + }else{ + printf("The response is not a well formed STUN message\n"); + } + ret=1; } - } catch(...) { - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - printf("STUN receive timeout..\n"); - }else{ - printf("The response is not a well formed STUN message\n"); - } - ret=1; } } - close(udp_fd); - return ret; -} + static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780, int change_ip, int change_port, int padding){ + int ret=0; + + udp_fd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0); + if (udp_fd < 0) + err(-1, NULL); + + if (!addr_any(local_addr)) { + if (addr_bind(udp_fd, local_addr,0,1,UDP_SOCKET) < 0) + err(-1, NULL); + } + + ret=stunclient_send(udp_fd, remote_addr, change_ip, change_port, padding, -1); + ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, port, rfc5780); + close(udp_fd); + + return ret; + } #else -static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780, int response_port, int change_ip, int change_port, int padding) -{ - int ret=0; - stun_buffer buf; + static int stunclient_send(int sockfd, ioa_addr *remote_addr, int change_ip, int change_port, int padding, int response_port){ + int ret=0; + stun_buffer buf; - udp_fd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); - if (udp_fd < 0) - err(-1, NULL); + stun_prepare_binding_request(&buf); - if (!addr_any(local_addr)) { if (response_port >= 0) { - addr_set_port(local_addr, response_port); - } - if (addr_bind(udp_fd, local_addr,0,1,UDP_SOCKET) < 0) { + stun_attr_add_response_port_str((u08bits*) (buf.buf), (size_t*) &(buf.len), (u16bits) response_port); + } + if (change_ip || change_port) { + stun_attr_add_change_request_str((u08bits*) buf.buf, (size_t*) &(buf.len), change_ip, change_port); + } + if (padding) { + if(stun_attr_add_padding_str((u08bits*) buf.buf, (size_t*) &(buf.len), 1500)<0) { + printf("%s: ERROR: Cannot add padding\n",__FUNCTION__); + } + } + + { + int len = 0; + int slen = get_ioa_addr_len(remote_addr); + + do { + len = sendto(sockfd, buf.buf, buf.len, 0, (struct sockaddr*) remote_addr, (socklen_t) slen); + } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); + + if (len < 0) err(-1, NULL); - } - } - - stun_prepare_binding_request(&buf); - - if (response_port >= 0) { - stun_attr_add_response_port_str((u08bits*) (buf.buf), (size_t*) &(buf.len), (u16bits) response_port); - } - if (change_ip || change_port) { - stun_attr_add_change_request_str((u08bits*) buf.buf, (size_t*) &(buf.len), change_ip, change_port); - } - if (padding) { - if(stun_attr_add_padding_str((u08bits*) buf.buf, (size_t*) &(buf.len), 1500)<0) { - printf("%s: ERROR: Cannot add padding\n",__FUNCTION__); } } + static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780){ + int ret=0; - { - int len = 0; - int slen = get_ioa_addr_len(remote_addr); + if (addr_get_from_sock(sockfd, local_addr) < 0) { + printf("%s: Cannot get address from local socket\n", __FUNCTION__); + } else { + *port = addr_get_port(local_addr); + } - do { - len = sendto(udp_fd, buf.buf, buf.len, 0, (struct sockaddr*) remote_addr, (socklen_t) slen); - } while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN))); - if (len < 0) - err(-1, NULL); + { + int len = 0; + u08bits *ptr = buf.buf; + int recvd = 0; + const int to_recv = sizeof(buf.buf); + struct timeval tv; - } + tv.tv_sec = 3; /* 3 Secs Timeout */ + tv.tv_usec = 0; // Not init'ing this can cause strange errors - if (addr_get_from_sock(udp_fd, local_addr) < 0) { - printf("%s: Cannot get address from local socket\n", __FUNCTION__); - } else { - *port = addr_get_port(local_addr); - } + setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); - - { - int len = 0; - u08bits *ptr = buf.buf; - int recvd = 0; - const int to_recv = sizeof(buf.buf); - struct timeval tv; + do { + len = recv(sockfd, ptr, to_recv - recvd, 0); + if (len > 0) { + recvd += len; + ptr += len; + break; + } + } while (len < 0 && (errno == EINTR)); - tv.tv_sec = 3; /* 3 Secs Timeout */ - tv.tv_usec = 0; // Not init'ing this can cause strange errors - - setsockopt(udp_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); - - do { - len = recv(udp_fd, ptr, to_recv - recvd, 0); - if (len > 0) { - recvd += len; - ptr += len; - break; - } - } while (len < 0 && (errno == EINTR)); - - if (recvd > 0) + if (recvd > 0) len = recvd; - buf.len = len; + buf.len = len; - if (stun_is_command_message(&buf)) { + if (stun_is_command_message(&buf)) { - if (stun_is_response(&buf)) { + if (stun_is_response(&buf)) { - if (stun_is_success_response(&buf)) { + if (stun_is_success_response(&buf)) { - if (stun_is_binding_response(&buf)) { + if (stun_is_binding_response(&buf)) { - addr_set_any(reflexive_addr); - if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) { + addr_set_any(reflexive_addr); + if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) { - stun_attr_ref sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_OTHER_ADDRESS); - if (sar) { - *rfc5780 = 1; - printf("\n========================================\n"); - printf("RFC 5780 response %d\n",++counter); - ioa_addr mapped_addr; - addr_set_any(&mapped_addr); - if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL) >= 0) { - if (!addr_eq(&mapped_addr,reflexive_addr)){ - printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); - addr_debug_print(1, &mapped_addr, "Mapped Address: "); - }else { - printf("No ALG: Mapped and XOR-Mapped is equal.\n"); - } - } else { - printf("Not received mapped address attribute.\n"); - } - stun_attr_get_addr_str((u08bits *) buf.buf, (size_t) buf.len, sar, other_addr, NULL); - sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_RESPONSE_ORIGIN); + stun_attr_ref sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_OTHER_ADDRESS); if (sar) { - ioa_addr response_origin; - stun_attr_get_addr_str((u08bits *) buf.buf, (size_t) buf.len, sar, &response_origin, NULL); - addr_debug_print(1, &response_origin, "Response origin: "); + *rfc5780 = 1; + printf("\n========================================\n"); + printf("RFC 5780 response %d\n",++counter); + ioa_addr mapped_addr; + addr_set_any(&mapped_addr); + if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL) >= 0) { + if (!addr_eq(&mapped_addr,reflexive_addr)){ + printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n"); + addr_debug_print(1, &mapped_addr, "Mapped Address: "); + }else { + printf("No ALG: Mapped and XOR-Mapped is equal.\n"); + } + } else { + printf("Not received mapped address attribute.\n"); + } + stun_attr_get_addr_str((u08bits *) buf.buf, (size_t) buf.len, sar, other_addr, NULL); + sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_RESPONSE_ORIGIN); + if (sar) { + ioa_addr response_origin; + stun_attr_get_addr_str((u08bits *) buf.buf, (size_t) buf.len, sar, &response_origin, NULL); + addr_debug_print(1, &response_origin, "Response origin: "); + } + addr_debug_print(1, other_addr, "Other addr: "); } - addr_debug_print(1, other_addr, "Other addr: "); + addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); + addr_debug_print(1, local_addr, "Local addr: "); + } else { + printf("Cannot read the response\n"); } - addr_debug_print(1, reflexive_addr, "UDP reflexive addr"); - addr_debug_print(1, local_addr, "Local addr: "); } else { - printf("Cannot read the response\n"); + printf("Wrong type of response\n"); } } else { - printf("Wrong type of response\n"); + int err_code = 0; + u08bits err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg); + if (stun_is_error_response(&buf, &err_code, err_msg, err_msg_size)) { + printf("The response is an error %d (%s)\n", err_code, (char*) err_msg); + } else { + printf("The response is an unrecognized error\n"); + } } } else { - int err_code = 0; - u08bits err_msg[1025] = "\0"; - size_t err_msg_size = sizeof(err_msg); - if (stun_is_error_response(&buf, &err_code, err_msg, err_msg_size)) { - printf("The response is an error %d (%s)\n", err_code, (char*) err_msg); - } else { - printf("The response is an unrecognized error\n"); - } + printf("The response is not a reponse message\n"); + ret=1; } } else { - printf("The response is not a reponse message\n"); + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("STUN receive timeout..\n"); + }else{ + printf("The response is not a STUN message\n"); + } ret=1; } - } else { - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - printf("STUN receive timeout..\n"); - }else{ - printf("The response is not a STUN message\n"); - } - ret=1; } } + static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780, int change_ip, int change_port, int padding){ + int ret=0; + + udp_fd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL); + if (udp_fd < 0) + err(-1, NULL); + + if (!addr_any(local_addr)) { + if (addr_bind(udp_fd, local_addr,0,1,UDP_SOCKET) < 0) { + err(-1, NULL); + } + } + + ret=stunclient_send(udp_fd, remote_addr, change_ip, change_port, padding, -1); + ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, port, rfc5780); + + socket_closesocket(udp_fd); + return ret; + } - socket_closesocket(udp_fd); - return ret; -} #endif -//////////////// local definitions ///////////////// + //////////////// local definitions ///////////////// -static char Usage[] = - "Usage: natdiscovery [options] address\n" - "Options:\n" - " -m NAT mapping behavior discovery\n" - " -f NAT filtering behavior discovery\n" - " -c NAT collision behavior discovery\n" - " Requires an alternative IP address (-A)\n" - " -P Add 1500 byte Padding to the behavior discovery\n" + static char Usage[] = + "Usage: natdiscovery [options] address\n" + "Options:\n" + " -m NAT mapping behavior discovery\n" + " -f NAT filtering behavior discovery\n" + " -c NAT collision behavior discovery\n" + " Requires an alternative IP address (-A)\n" + " -P Add 1500 byte Padding to the behavior discovery\n" " Applicable with all except NAT Binding Lifetime discovery\n" " -p STUN server port (Default: 3478)\n" - " -L Local address to use (optional)\n" - " -A Local alrernative address to use\n" - " Used by collision behavior Discovery\n"; + " -L Local address to use (optional)\n" + " -A Local alrernative address to use\n" + " Used by collision behavior Discovery\n"; -////////////////////////////////////////////////// + ////////////////////////////////////////////////// -static void init(ioa_addr *local_addr,ioa_addr *remote_addr,int *local_port,int port, int *rfc5780, char* local_addr_string, char* remote_param) -{ - addr_set_any(local_addr); + static void init(ioa_addr *local_addr,ioa_addr *remote_addr,int *local_port,int port, int *rfc5780, char* local_addr_string, char* remote_param) + { + addr_set_any(local_addr); - if(local_addr_string[0]) { - if(make_ioa_addr((const u08bits*)local_addr_string, 0, local_addr)<0) { - err(-1,NULL); - } - } + if(local_addr_string[0]) { + if(make_ioa_addr((const u08bits*)local_addr_string, 0, local_addr)<0) { + err(-1,NULL); + } + } - *local_port = -1; - *rfc5780 = 0; + *local_port = -1; + *rfc5780 = 0; - if (make_ioa_addr((const u08bits*)remote_param, port, remote_addr) < 0) + if (make_ioa_addr((const u08bits*)remote_param, port, remote_addr) < 0) err(-1, NULL); -} + } -static void discoveryresult(const char *decision){ - printf("\n========================================\n"); - printf("%s",decision); - printf("\n========================================\n"); -} + static void discoveryresult(const char *decision){ + printf("\n========================================\n"); + printf("%s",decision); + printf("\n========================================\n"); + } -int main(int argc, char **argv) -{ - int port = DEFAULT_STUN_PORT; - char local_addr_string[256]="\0"; - char local2_addr_string[256]="\0"; - int c=0; - int mapping = 0; - int filtering = 0; - int collision = 0; - int padding = 0; - int local_port, rfc5780; - ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr; - + int main(int argc, char **argv) + { + int port = DEFAULT_STUN_PORT; + char local_addr_string[256]="\0"; + char local2_addr_string[256]="\0"; + int c=0; + int mapping = 0; + int filtering = 0; + int collision = 0; + int padding = 0; + int local_port, rfc5780; + ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr; - set_logfile("stdout"); - set_system_parameters(0); - - ns_bzero(local_addr_string, sizeof(local_addr_string)); - ns_bzero(local2_addr_string, sizeof(local2_addr_string)); - addr_set_any(&remote_addr); - addr_set_any(&other_addr); - addr_set_any(&reflexive_addr); - addr_set_any(&tmp_addr); - while ((c = getopt(argc, argv, "mfcPp:L:A:")) != -1) { - switch(c) { - case 'm': - mapping=1; - break; - case 'f': - filtering=1; - break; - case 'c': - collision=1; - break; - case 'P': - padding=1; - break; - case 'p': - port = atoi(optarg); - break; - case 'L': - STRCPY(local_addr_string, optarg); - break; - case 'A': - STRCPY(local2_addr_string, optarg); - break; - default: - fprintf(stderr,"%s\n", Usage); - exit(1); - } - } + set_logfile("stdout"); + set_system_parameters(0); - if(optind>=argc) { - fprintf(stderr, "%s\n", Usage); - exit(-1); - } - - if(collision && local2_addr_string == '\0'){ - fprintf(stderr, "Use \"-A\" to add an Alternative local IP address.\n"); - fprintf(stderr, "It is mandatory with \"-c\" collision behavior detection..\n"); - exit(-1); - } + ns_bzero(local_addr_string, sizeof(local_addr_string)); + ns_bzero(local2_addr_string, sizeof(local2_addr_string)); + addr_set_any(&remote_addr); + addr_set_any(&other_addr); + addr_set_any(&reflexive_addr); + addr_set_any(&tmp_addr); - init(&local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr_string, argv[optind]); - - if(mapping) { - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,padding); - if (addr_eq(&local_addr,&reflexive_addr)){ - discoveryresult("No NAT! (Endpoint Independent Mapping)"); + while ((c = getopt(argc, argv, "mfcPp:L:A:")) != -1) { + switch(c) { + case 'm': + mapping=1; + break; + case 'f': + filtering=1; + break; + case 'c': + collision=1; + break; + case 'P': + padding=1; + break; + case 'p': + port = atoi(optarg); + break; + case 'L': + STRCPY(local_addr_string, optarg); + break; + case 'A': + STRCPY(local2_addr_string, optarg); + break; + default: + fprintf(stderr,"%s\n", Usage); + exit(1); + } } - if(rfc5780) { - if(!addr_any(&other_addr)){ - addr_cpy(&tmp_addr, &reflexive_addr); - addr_cpy(&remote_addr, &other_addr); - addr_set_port(&remote_addr, port); + if(optind>=argc) { + fprintf(stderr, "%s\n", Usage); + exit(-1); + } - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,padding); + if(collision && local2_addr_string == '\0'){ + fprintf(stderr, "Use \"-A\" to add an Alternative local IP address.\n"); + fprintf(stderr, "It is mandatory with \"-c\" collision behavior detection..\n"); + exit(-1); + } - if(addr_eq(&tmp_addr,&reflexive_addr)){ - discoveryresult("NAT with Enpoint Independent Mapping!"); - } else { + init(&local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr_string, argv[optind]); + + if(mapping) { + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + if (addr_eq(&local_addr,&reflexive_addr)){ + discoveryresult("No NAT! (Endpoint Independent Mapping)"); + } + if(rfc5780) { + if(!addr_any(&other_addr)){ addr_cpy(&tmp_addr, &reflexive_addr); + addr_cpy(&remote_addr, &other_addr); - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,padding); + addr_set_port(&remote_addr, port); + + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + if(addr_eq(&tmp_addr,&reflexive_addr)){ - discoveryresult("NAT with Address Dependent Mapping!"); + discoveryresult("NAT with Enpoint Independent Mapping!"); } else { - discoveryresult("NAT with Address and Port Dependent Mapping!"); + addr_cpy(&tmp_addr, &reflexive_addr); + addr_cpy(&remote_addr, &other_addr); + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + if(addr_eq(&tmp_addr,&reflexive_addr)){ + discoveryresult("NAT with Address Dependent Mapping!"); + } else { + discoveryresult("NAT with Address and Port Dependent Mapping!"); + } } } - } - } - } - - init(&local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr_string, argv[optind]); - - if(filtering) { - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,padding); - if(addr_eq(&local_addr, &reflexive_addr)){ - discoveryresult("No NAT! (Endpoint Independent Mapping)"); + } } - if(rfc5780) { - if(!addr_any(&other_addr)){ - int res=0; - res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,1,1,padding); - if (!res) { - discoveryresult("NAT with Enpoint Independent Filtering!"); - } else { - res=0; - res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,1,padding); - if(!res){ - discoveryresult("NAT with Address Dependent Filtering!"); + + init(&local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr_string, argv[optind]); + + if(filtering) { + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + if(addr_eq(&local_addr, &reflexive_addr)){ + discoveryresult("No NAT! (Endpoint Independent Mapping)"); + } + if(rfc5780) { + if(!addr_any(&other_addr)){ + int res=0; + res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,1,1,padding); + if (!res) { + discoveryresult("NAT with Enpoint Independent Filtering!"); } else { - discoveryresult("NAT with Address and Port Dependent Filtering!"); + res=0; + res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,1,padding); + if(!res){ + discoveryresult("NAT with Address Dependent Filtering!"); + } else { + discoveryresult("NAT with Address and Port Dependent Filtering!"); + } } } - } - } - } + } + } - init(&local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr_string, argv[optind]); + init(&local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr_string, argv[optind]); - if(collision) { - addr_set_any(&local2_addr); + if(collision) { + addr_set_any(&local2_addr); - if(local2_addr_string[0]) { - if(make_ioa_addr((const u08bits*)local2_addr_string, 0, &local2_addr)<0) { - err(-1,NULL); - } - } + if(local2_addr_string[0]) { + if(make_ioa_addr((const u08bits*)local2_addr_string, 0, &local2_addr)<0) { + err(-1,NULL); + } + } - run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,padding); - addr_set_port(&local2_addr,addr_get_port(&local_addr)); - run_stunclient(&local2_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,padding); - } + run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + addr_set_port(&local2_addr,addr_get_port(&local_addr)); + run_stunclient(&local2_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding); + } - if (!filtering && !mapping && !collision) { - printf("Please use either -f or -c or -m parameter for Filtering or Mapping behavior discovery.\n"); - } - socket_closesocket(udp_fd); + if (!filtering && !mapping && !collision) { + printf("Please use either -f or -c or -m parameter for Filtering or Mapping behavior discovery.\n"); + } + socket_closesocket(udp_fd); + socket_closesocket(udp_fd2); - return 0; -} + return 0; + }