version 1.1, 2012/02/21 23:16:02
|
version 1.1.1.2, 2012/05/29 12:55:57
|
Line 1
|
Line 1
|
/* $Id$ */ |
/* $Id$ */ |
/* MiniUPnP project |
/* MiniUPnP project |
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ |
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ |
* (c) 2006-2010 Thomas Bernard | * (c) 2006-2011 Thomas Bernard |
* This software is subject to the conditions detailed |
* This software is subject to the conditions detailed |
* in the LICENCE file provided within the distribution */ |
* in the LICENCE file provided within the distribution */ |
|
|
Line 63
|
Line 63
|
#include "natpmp.h" |
#include "natpmp.h" |
#endif |
#endif |
#include "commonrdr.h" |
#include "commonrdr.h" |
|
#include "upnputils.h" |
|
#ifdef USE_IFACEWATCHER |
|
#include "ifacewatcher.h" |
|
#endif |
|
|
#ifndef DEFAULT_CONFIG |
#ifndef DEFAULT_CONFIG |
#define DEFAULT_CONFIG "/etc/miniupnpd.conf" |
#define DEFAULT_CONFIG "/etc/miniupnpd.conf" |
Line 81 static struct nfq_handle *nfqHandle;
|
Line 85 static struct nfq_handle *nfqHandle;
|
static struct sockaddr_in ssdp; |
static struct sockaddr_in ssdp; |
|
|
/* prototypes */ |
/* prototypes */ |
void ProcessSSDPData(int s, char *bufr, struct sockaddr_in sendername, int n, unsigned short port); |
|
static int nfqueue_cb( struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) ; |
static int nfqueue_cb( struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) ; |
int identify_ip_protocol (char *payload); |
int identify_ip_protocol (char *payload); |
int get_udp_dst_port (char *payload); |
int get_udp_dst_port (char *payload); |
#endif |
#endif |
|
|
| /* variables used by signals */ |
static int sudp = -1; | |
| |
/* MAX_LAN_ADDR : maximum number of interfaces | |
* to listen to SSDP traffic */ | |
/*#define MAX_LAN_ADDR (4)*/ | |
| |
static volatile int quitting = 0; |
static volatile int quitting = 0; |
static volatile int should_send_public_address_change_notif = 0; | volatile int should_send_public_address_change_notif = 0; |
|
|
/* OpenAndConfHTTPSocket() : |
/* OpenAndConfHTTPSocket() : |
* setup the socket used to handle incoming HTTP connections. */ |
* setup the socket used to handle incoming HTTP connections. */ |
Line 104 OpenAndConfHTTPSocket(unsigned short port)
|
Line 101 OpenAndConfHTTPSocket(unsigned short port)
|
{ |
{ |
int s; |
int s; |
int i = 1; |
int i = 1; |
|
#ifdef ENABLE_IPV6 |
|
struct sockaddr_in6 listenname; |
|
#else |
struct sockaddr_in listenname; |
struct sockaddr_in listenname; |
|
#endif |
|
socklen_t listenname_len; |
|
|
if( (s = socket(PF_INET, SOCK_STREAM, 0)) < 0) | if( (s = socket( |
| #ifdef ENABLE_IPV6 |
| PF_INET6, |
| #else |
| PF_INET, |
| #endif |
| SOCK_STREAM, 0)) < 0) |
{ |
{ |
syslog(LOG_ERR, "socket(http): %m"); |
syslog(LOG_ERR, "socket(http): %m"); |
return -1; |
return -1; |
Line 116 OpenAndConfHTTPSocket(unsigned short port)
|
Line 124 OpenAndConfHTTPSocket(unsigned short port)
|
{ |
{ |
syslog(LOG_WARNING, "setsockopt(http, SO_REUSEADDR): %m"); |
syslog(LOG_WARNING, "setsockopt(http, SO_REUSEADDR): %m"); |
} |
} |
|
#if 0 |
|
/* enable this to force IPV6 only for IPV6 socket. |
|
* see http://www.ietf.org/rfc/rfc3493.txt section 5.3 */ |
|
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i)) < 0) |
|
{ |
|
syslog(LOG_WARNING, "setsockopt(http, IPV6_V6ONLY): %m"); |
|
} |
|
#endif |
|
|
memset(&listenname, 0, sizeof(struct sockaddr_in)); | #ifdef ENABLE_IPV6 |
| memset(&listenname, 0, sizeof(struct sockaddr_in6)); |
| listenname.sin6_family = AF_INET6; |
| listenname.sin6_port = htons(port); |
| listenname.sin6_addr = in6addr_any; |
| listenname_len = sizeof(struct sockaddr_in6); |
| #else |
listenname.sin_family = AF_INET; |
listenname.sin_family = AF_INET; |
listenname.sin_port = htons(port); |
listenname.sin_port = htons(port); |
listenname.sin_addr.s_addr = htonl(INADDR_ANY); |
listenname.sin_addr.s_addr = htonl(INADDR_ANY); |
|
listenname_len = sizeof(struct sockaddr_in); |
|
#endif |
|
|
if(bind(s, (struct sockaddr *)&listenname, sizeof(struct sockaddr_in)) < 0) | if(bind(s, (struct sockaddr *)&listenname, listenname_len) < 0) |
{ |
{ |
syslog(LOG_ERR, "bind(http): %m"); |
syslog(LOG_ERR, "bind(http): %m"); |
close(s); |
close(s); |
return -1; |
return -1; |
} |
} |
|
|
if(listen(s, 6) < 0) | if(listen(s, 5) < 0) |
{ |
{ |
syslog(LOG_ERR, "listen(http): %m"); |
syslog(LOG_ERR, "listen(http): %m"); |
close(s); |
close(s); |
Line 255 static int nfqueue_cb(
|
Line 279 static int nfqueue_cb(
|
sendername.sin_addr.s_addr = iph->ip_src.s_addr; |
sendername.sin_addr.s_addr = iph->ip_src.s_addr; |
|
|
/* printf("pkt found %s\n",dd);*/ |
/* printf("pkt found %s\n",dd);*/ |
ProcessSSDPData (sudp, dd, sendername, size - x, (unsigned short) 5555); | ProcessSSDPData (sudp, dd, size - x, |
| &sendername, (unsigned short) 5555); |
} |
} |
} |
} |
} |
} |
Line 472 set_startup_time(int sysuptime)
|
Line 497 set_startup_time(int sysuptime)
|
struct runtime_vars { |
struct runtime_vars { |
/* LAN IP addresses for SSDP traffic and HTTP */ |
/* LAN IP addresses for SSDP traffic and HTTP */ |
/* moved to global vars */ |
/* moved to global vars */ |
/*int n_lan_addr;*/ |
|
/*struct lan_addr_s lan_addr[MAX_LAN_ADDR];*/ |
|
int port; /* HTTP Port */ |
int port; /* HTTP Port */ |
int notify_interval; /* seconds between SSDP announces */ |
int notify_interval; /* seconds between SSDP announces */ |
/* unused rules cleaning related variables : */ |
/* unused rules cleaning related variables : */ |
Line 563 init(int argc, char * * argv, struct runtime_vars * v)
|
Line 586 init(int argc, char * * argv, struct runtime_vars * v)
|
/*const char * logfilename = 0;*/ |
/*const char * logfilename = 0;*/ |
const char * presurl = 0; |
const char * presurl = 0; |
const char * optionsfile = DEFAULT_CONFIG; |
const char * optionsfile = DEFAULT_CONFIG; |
|
struct lan_addr_s * lan_addr; |
|
struct lan_addr_s * lan_addr2; |
|
|
/* only print usage if -h is used */ |
/* only print usage if -h is used */ |
for(i=1; i<argc; i++) |
for(i=1; i<argc; i++) |
Line 584 init(int argc, char * * argv, struct runtime_vars * v)
|
Line 609 init(int argc, char * * argv, struct runtime_vars * v)
|
/* set initial values */ |
/* set initial values */ |
SETFLAG(ENABLEUPNPMASK); |
SETFLAG(ENABLEUPNPMASK); |
|
|
/*v->n_lan_addr = 0;*/ | LIST_INIT(&lan_addrs); |
v->port = -1; |
v->port = -1; |
v->notify_interval = 30; /* seconds between SSDP announces */ |
v->notify_interval = 30; /* seconds between SSDP announces */ |
v->clean_ruleset_threshold = 20; |
v->clean_ruleset_threshold = 20; |
Line 611 init(int argc, char * * argv, struct runtime_vars * v)
|
Line 636 init(int argc, char * * argv, struct runtime_vars * v)
|
use_ext_ip_addr = ary_options[i].value; |
use_ext_ip_addr = ary_options[i].value; |
break; |
break; |
case UPNPLISTENING_IP: |
case UPNPLISTENING_IP: |
if(n_lan_addr < MAX_LAN_ADDR)/* if(v->n_lan_addr < MAX_LAN_ADDR)*/ | lan_addr = (struct lan_addr_s *) malloc(sizeof(struct lan_addr_s)); |
| if (lan_addr == NULL) |
{ |
{ |
/*if(parselanaddr(&v->lan_addr[v->n_lan_addr],*/ | fprintf(stderr, "malloc(sizeof(struct lan_addr_s)): %m"); |
if(parselanaddr(&lan_addr[n_lan_addr], | break; |
ary_options[i].value) == 0) | |
n_lan_addr++; /*v->n_lan_addr++; */ | |
} |
} |
else | if(parselanaddr(lan_addr, ary_options[i].value) != 0) |
{ |
{ |
fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n", | fprintf(stderr, "can't parse \"%s\" as valid lan address\n", ary_options[i].value); |
MAX_LAN_ADDR, ary_options[i].value); | free(lan_addr); |
| break; |
} |
} |
|
LIST_INSERT_HEAD(&lan_addrs, lan_addr, list); |
break; |
break; |
case UPNPPORT: |
case UPNPPORT: |
v->port = atoi(ary_options[i].value); |
v->port = atoi(ary_options[i].value); |
Line 856 init(int argc, char * * argv, struct runtime_vars * v)
|
Line 882 init(int argc, char * * argv, struct runtime_vars * v)
|
case 'a': |
case 'a': |
if(i+1 < argc) |
if(i+1 < argc) |
{ |
{ |
int address_already_there = 0; |
|
int j; |
|
i++; |
i++; |
for(j=0; j<n_lan_addr; j++) | lan_addr = (struct lan_addr_s *) malloc(sizeof(struct lan_addr_s)); |
| if (lan_addr == NULL) |
{ |
{ |
struct lan_addr_s tmpaddr; | fprintf(stderr, "malloc(sizeof(struct lan_addr_s)): %m"); |
parselanaddr(&tmpaddr, argv[i]); | |
if(0 == strcmp(lan_addr[j].str, tmpaddr.str)) | |
address_already_there = 1; | |
} | |
if(address_already_there) | |
break; |
break; |
if(n_lan_addr < MAX_LAN_ADDR) | } |
| if(parselanaddr(lan_addr, argv[i]) != 0) |
{ |
{ |
if(parselanaddr(&lan_addr[n_lan_addr], argv[i]) == 0) | fprintf(stderr, "can't parse \"%s\" as valid lan address\n", argv[i]); |
n_lan_addr++; | free(lan_addr); |
| break; |
} |
} |
else | /* check if we already have this address */ |
| for(lan_addr2 = lan_addrs.lh_first; lan_addr2 != NULL; lan_addr2 = lan_addr2->list.le_next) |
{ |
{ |
fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n", | if (0 == strncmp(lan_addr2->str, lan_addr->str, 15)) |
MAX_LAN_ADDR, argv[i]); | break; |
} |
} |
|
if (lan_addr2 == NULL) |
|
LIST_INSERT_HEAD(&lan_addrs, lan_addr, list); |
} |
} |
else |
else |
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]); |
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]); |
Line 889 init(int argc, char * * argv, struct runtime_vars * v)
|
Line 914 init(int argc, char * * argv, struct runtime_vars * v)
|
fprintf(stderr, "Unknown option: %s\n", argv[i]); |
fprintf(stderr, "Unknown option: %s\n", argv[i]); |
} |
} |
} |
} |
if(!ext_if_name || (n_lan_addr==0)) | if(!ext_if_name || !lan_addrs.lh_first) |
{ |
{ |
/* bad configuration */ |
/* bad configuration */ |
goto print_usage; |
goto print_usage; |
Line 942 init(int argc, char * * argv, struct runtime_vars * v)
|
Line 967 init(int argc, char * * argv, struct runtime_vars * v)
|
else |
else |
{ |
{ |
snprintf(presentationurl, PRESENTATIONURL_MAX_LEN, |
snprintf(presentationurl, PRESENTATIONURL_MAX_LEN, |
"http://%s/", lan_addr[0].str); | "http://%s/", lan_addrs.lh_first->str); |
/*"http://%s:%d/", lan_addr[0].str, 80);*/ | /*"http://%s:%d/", lan_addrs.lh_first->str, 80);*/ |
} |
} |
|
|
/* set signal handler */ |
/* set signal handler */ |
Line 1037 int
|
Line 1062 int
|
main(int argc, char * * argv) |
main(int argc, char * * argv) |
{ |
{ |
int i; |
int i; |
int shttpl = -1; | int shttpl = -1; /* socket for HTTP */ |
| int sudp = -1; /* IP v4 socket for receiving SSDP */ |
| #ifdef ENABLE_IPV6 |
| int sudpv6 = -1; /* IP v6 socket for receiving SSDP */ |
| #endif |
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
int snatpmp[MAX_LAN_ADDR]; | int * snatpmp; |
| #endif |
#ifdef ENABLE_NFQUEUE |
#ifdef ENABLE_NFQUEUE |
int nfqh = -1; |
int nfqh = -1; |
#endif |
#endif |
|
#ifdef USE_IFACEWATCHER |
|
int sifacewatcher = -1; |
#endif |
#endif |
int snotify[MAX_LAN_ADDR]; | |
| int * snotify; |
| int addr_count; |
LIST_HEAD(httplisthead, upnphttp) upnphttphead; |
LIST_HEAD(httplisthead, upnphttp) upnphttphead; |
struct upnphttp * e = 0; |
struct upnphttp * e = 0; |
struct upnphttp * next; |
struct upnphttp * next; |
Line 1064 main(int argc, char * * argv)
|
Line 1098 main(int argc, char * * argv)
|
/* variables used for the unused-rule cleanup process */ |
/* variables used for the unused-rule cleanup process */ |
struct rule_state * rule_list = 0; |
struct rule_state * rule_list = 0; |
struct timeval checktime = {0, 0}; |
struct timeval checktime = {0, 0}; |
|
struct lan_addr_s * lan_addr; |
syslog(LOG_INFO, "SNet version started"); |
syslog(LOG_INFO, "SNet version started"); |
|
|
| if(init(argc, argv, &v) != 0) |
| return 1; |
| /* count lan addrs */ |
| addr_count = 0; |
| for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next) |
| addr_count++; |
| snotify = (int*) malloc(addr_count * sizeof(int)); |
memset(snotify, 0, sizeof(snotify)); |
memset(snotify, 0, sizeof(snotify)); |
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
for(i = 0; i < MAX_LAN_ADDR; i++) | snatpmp = (int*) malloc(addr_count * sizeof(int)); |
| for(i = 0; i < addr_count; i++) |
snatpmp[i] = -1; |
snatpmp[i] = -1; |
#endif |
#endif |
if(init(argc, argv, &v) != 0) |
|
return 1; |
|
|
|
LIST_INIT(&upnphttphead); |
LIST_INIT(&upnphttphead); |
#ifdef USE_MINIUPNPDCTL |
#ifdef USE_MINIUPNPDCTL |
Line 1109 main(int argc, char * * argv)
|
Line 1149 main(int argc, char * * argv)
|
v.port = ntohs(sockinfo.sin_port); |
v.port = ntohs(sockinfo.sin_port); |
} |
} |
syslog(LOG_NOTICE, "HTTP listening on port %d", v.port); |
syslog(LOG_NOTICE, "HTTP listening on port %d", v.port); |
|
#ifdef ENABLE_IPV6 |
|
if(find_ipv6_addr(NULL, ipv6_addr_for_http_with_brackets, sizeof(ipv6_addr_for_http_with_brackets)) > 0) { |
|
syslog(LOG_NOTICE, "HTTP IPv6 address given to control points : %s", |
|
ipv6_addr_for_http_with_brackets); |
|
} else { |
|
memcpy(ipv6_addr_for_http_with_brackets, "[::1]", 6); |
|
syslog(LOG_WARNING, "no HTTP IPv6 address"); |
|
} |
|
#endif |
|
|
/* open socket for SSDP connections */ |
/* open socket for SSDP connections */ |
sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr); | sudp = OpenAndConfSSDPReceiveSocket(0); |
if(sudp < 0) |
if(sudp < 0) |
{ |
{ |
syslog(LOG_INFO, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd"); |
syslog(LOG_INFO, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd"); |
if(SubmitServicesToMiniSSDPD(lan_addr[0].str, v.port) < 0) { | if(SubmitServicesToMiniSSDPD(lan_addrs.lh_first->str, v.port) < 0) { |
syslog(LOG_ERR, "Failed to connect to MiniSSDPd. EXITING"); |
syslog(LOG_ERR, "Failed to connect to MiniSSDPd. EXITING"); |
return 1; |
return 1; |
} |
} |
} |
} |
|
#ifdef ENABLE_IPV6 |
|
sudpv6 = OpenAndConfSSDPReceiveSocket(1); |
|
if(sudpv6 < 0) |
|
{ |
|
syslog(LOG_INFO, "Failed to open socket for receiving SSDP (IP v6)."); |
|
} |
|
#endif |
|
|
/* open socket for sending notifications */ |
/* open socket for sending notifications */ |
if(OpenAndConfSSDPNotifySockets(snotify) < 0) |
if(OpenAndConfSSDPNotifySockets(snotify) < 0) |
Line 1128 main(int argc, char * * argv)
|
Line 1184 main(int argc, char * * argv)
|
"messages. EXITING"); |
"messages. EXITING"); |
return 1; |
return 1; |
} |
} |
|
|
|
#ifdef USE_IFACEWATCHER |
|
/* open socket for kernel notifications about new network interfaces */ |
|
if (sudp >= 0) |
|
{ |
|
sifacewatcher = OpenAndConfInterfaceWatchSocket(); |
|
if (sifacewatcher < 0) |
|
{ |
|
syslog(LOG_ERR, "Failed to open socket for receiving network interface notifications"); |
|
} |
|
} |
|
#endif |
} |
} |
|
|
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
Line 1141 main(int argc, char * * argv)
|
Line 1209 main(int argc, char * * argv)
|
syslog(LOG_NOTICE, "Listening for NAT-PMP traffic on port %u", |
syslog(LOG_NOTICE, "Listening for NAT-PMP traffic on port %u", |
NATPMP_PORT); |
NATPMP_PORT); |
} |
} |
|
#if 0 |
ScanNATPMPforExpiration(); |
ScanNATPMPforExpiration(); |
|
#endif |
} |
} |
#endif |
#endif |
|
|
Line 1169 main(int argc, char * * argv)
|
Line 1239 main(int argc, char * * argv)
|
{ |
{ |
set_startup_time(GETFLAG(SYSUPTIMEMASK)); |
set_startup_time(GETFLAG(SYSUPTIMEMASK)); |
} |
} |
|
/* send public address change notifications if needed */ |
|
if(should_send_public_address_change_notif) |
|
{ |
|
syslog(LOG_DEBUG, "should send external iface address change notification(s)"); |
|
#ifdef ENABLE_NATPMP |
|
if(GETFLAG(ENABLENATPMPMASK)) |
|
SendNATPMPPublicAddressChangeNotification(snatpmp, addr_count); |
|
#endif |
|
#ifdef ENABLE_EVENTS |
|
if(GETFLAG(ENABLEUPNPMASK)) |
|
{ |
|
upnp_event_var_change_notify(EWanIPC); |
|
} |
|
#endif |
|
should_send_public_address_change_notif = 0; |
|
} |
/* Check if we need to send SSDP NOTIFY messages and do it if |
/* Check if we need to send SSDP NOTIFY messages and do it if |
* needed */ |
* needed */ |
if(gettimeofday(&timeofday, 0) < 0) |
if(gettimeofday(&timeofday, 0) < 0) |
Line 1221 main(int argc, char * * argv)
|
Line 1307 main(int argc, char * * argv)
|
} |
} |
memcpy(&checktime, &timeofday, sizeof(struct timeval)); |
memcpy(&checktime, &timeofday, sizeof(struct timeval)); |
} |
} |
|
/* Remove expired port mappings, based on UPnP IGD LeaseDuration |
|
* or NAT-PMP lifetime) */ |
|
if(nextruletoclean_timestamp |
|
&& (timeofday.tv_sec >= nextruletoclean_timestamp)) |
|
{ |
|
syslog(LOG_DEBUG, "cleaning expired Port Mappings"); |
|
get_upnp_rules_state_list(0); |
|
} |
|
if(nextruletoclean_timestamp |
|
&& timeout.tv_sec >= (nextruletoclean_timestamp - timeofday.tv_sec)) |
|
{ |
|
timeout.tv_sec = nextruletoclean_timestamp - timeofday.tv_sec; |
|
timeout.tv_usec = 0; |
|
syslog(LOG_DEBUG, "setting timeout to %u sec", |
|
(unsigned)timeout.tv_sec); |
|
} |
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
|
#if 0 |
/* Remove expired NAT-PMP mappings */ |
/* Remove expired NAT-PMP mappings */ |
while( nextnatpmptoclean_timestamp && (timeofday.tv_sec >= nextnatpmptoclean_timestamp + startup_time)) | while(nextnatpmptoclean_timestamp |
| && (timeofday.tv_sec >= nextnatpmptoclean_timestamp + startup_time)) |
{ |
{ |
/*syslog(LOG_DEBUG, "cleaning expired NAT-PMP mappings");*/ |
/*syslog(LOG_DEBUG, "cleaning expired NAT-PMP mappings");*/ |
if(CleanExpiredNATPMP() < 0) { |
if(CleanExpiredNATPMP() < 0) { |
Line 1231 main(int argc, char * * argv)
|
Line 1335 main(int argc, char * * argv)
|
break; |
break; |
} |
} |
} |
} |
if(nextnatpmptoclean_timestamp && timeout.tv_sec >= (nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec)) | if(nextnatpmptoclean_timestamp |
| && timeout.tv_sec >= (nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec)) |
{ |
{ |
/*syslog(LOG_DEBUG, "setting timeout to %d sec", nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec);*/ | /*syslog(LOG_DEBUG, "setting timeout to %d sec", |
#ifdef ENABLE_NFQUEUE | nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec);*/ |
if (nfqh >= 0) | |
{ | |
FD_SET(nfqh, &readset); | |
max_fd = MAX( max_fd, nfqh); | |
} | |
#endif | |
| |
timeout.tv_sec = nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec; |
timeout.tv_sec = nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec; |
timeout.tv_usec = 0; |
timeout.tv_usec = 0; |
} |
} |
#endif |
#endif |
|
#endif |
|
|
/* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */ |
/* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */ |
FD_ZERO(&readset); |
FD_ZERO(&readset); |
Line 1254 main(int argc, char * * argv)
|
Line 1353 main(int argc, char * * argv)
|
{ |
{ |
FD_SET(sudp, &readset); |
FD_SET(sudp, &readset); |
max_fd = MAX( max_fd, sudp); |
max_fd = MAX( max_fd, sudp); |
|
#ifdef USE_IFACEWATCHER |
|
if (sifacewatcher >= 0) |
|
{ |
|
FD_SET(sifacewatcher, &readset); |
|
max_fd = MAX(max_fd, sifacewatcher); |
|
} |
|
#endif |
} |
} |
|
|
if (shttpl >= 0) |
if (shttpl >= 0) |
{ |
{ |
FD_SET(shttpl, &readset); |
FD_SET(shttpl, &readset); |
max_fd = MAX( max_fd, shttpl); |
max_fd = MAX( max_fd, shttpl); |
} |
} |
|
#ifdef ENABLE_IPV6 |
|
if (sudpv6 >= 0) |
|
{ |
|
FD_SET(sudpv6, &readset); |
|
max_fd = MAX( max_fd, sudpv6); |
|
} |
|
#endif |
|
|
|
#ifdef ENABLE_NFQUEUE |
|
if (nfqh >= 0) |
|
{ |
|
FD_SET(nfqh, &readset); |
|
max_fd = MAX( max_fd, nfqh); |
|
} |
|
#endif |
|
|
i = 0; /* active HTTP connections count */ |
i = 0; /* active HTTP connections count */ |
for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) |
for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) |
{ |
{ |
Line 1280 main(int argc, char * * argv)
|
Line 1400 main(int argc, char * * argv)
|
} |
} |
#endif |
#endif |
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
for(i=0; i<n_lan_addr; i++) { | for(i=0; i<addr_count; i++) { |
if(snatpmp[i] >= 0) { |
if(snatpmp[i] >= 0) { |
FD_SET(snatpmp[i], &readset); |
FD_SET(snatpmp[i], &readset); |
max_fd = MAX( max_fd, snatpmp[i]); |
max_fd = MAX( max_fd, snatpmp[i]); |
Line 1377 main(int argc, char * * argv)
|
Line 1497 main(int argc, char * * argv)
|
#endif |
#endif |
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
/* process NAT-PMP packets */ |
/* process NAT-PMP packets */ |
for(i=0; i<n_lan_addr; i++) | for(i=0; i<addr_count; i++) |
{ |
{ |
if((snatpmp[i] >= 0) && FD_ISSET(snatpmp[i], &readset)) |
if((snatpmp[i] >= 0) && FD_ISSET(snatpmp[i], &readset)) |
{ |
{ |
Line 1391 main(int argc, char * * argv)
|
Line 1511 main(int argc, char * * argv)
|
/*syslog(LOG_INFO, "Received UDP Packet");*/ |
/*syslog(LOG_INFO, "Received UDP Packet");*/ |
ProcessSSDPRequest(sudp, (unsigned short)v.port); |
ProcessSSDPRequest(sudp, (unsigned short)v.port); |
} |
} |
|
#ifdef ENABLE_IPV6 |
|
if(sudpv6 >= 0 && FD_ISSET(sudpv6, &readset)) |
|
{ |
|
syslog(LOG_INFO, "Received UDP Packet (IPv6)"); |
|
ProcessSSDPRequest(sudpv6, (unsigned short)v.port); |
|
} |
|
#endif |
|
#ifdef USE_IFACEWATCHER |
|
/* process kernel notifications */ |
|
if (sifacewatcher >= 0 && FD_ISSET(sifacewatcher, &readset)) |
|
ProcessInterfaceWatchNotify(sifacewatcher); |
|
#endif |
|
|
/* process active HTTP connections */ |
/* process active HTTP connections */ |
/* LIST_FOREACH macro is not available under linux */ |
/* LIST_FOREACH macro is not available under linux */ |
for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) |
for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) |
Line 1406 main(int argc, char * * argv)
|
Line 1539 main(int argc, char * * argv)
|
{ |
{ |
int shttp; |
int shttp; |
socklen_t clientnamelen; |
socklen_t clientnamelen; |
|
#ifdef ENABLE_IPV6 |
|
struct sockaddr_storage clientname; |
|
clientnamelen = sizeof(struct sockaddr_storage); |
|
#else |
struct sockaddr_in clientname; |
struct sockaddr_in clientname; |
clientnamelen = sizeof(struct sockaddr_in); |
clientnamelen = sizeof(struct sockaddr_in); |
|
#endif |
shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen); |
shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen); |
if(shttp<0) |
if(shttp<0) |
{ |
{ |
Line 1416 main(int argc, char * * argv)
|
Line 1554 main(int argc, char * * argv)
|
else |
else |
{ |
{ |
struct upnphttp * tmp = 0; |
struct upnphttp * tmp = 0; |
syslog(LOG_INFO, "HTTP connection from %s:%d", | char addr_str[64]; |
inet_ntoa(clientname.sin_addr), | |
ntohs(clientname.sin_port) ); | sockaddr_to_string((struct sockaddr *)&clientname, addr_str, sizeof(addr_str)); |
| syslog(LOG_INFO, "HTTP connection from %s", addr_str); |
/*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) { |
/*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) { |
syslog(LOG_ERR, "fcntl F_SETFL, O_NONBLOCK"); |
syslog(LOG_ERR, "fcntl F_SETFL, O_NONBLOCK"); |
}*/ |
}*/ |
#ifdef ENABLE_NFQUEUE |
|
/* process NFQ packets */ |
|
if(nfqh >= 0 && FD_ISSET(nfqh, &readset)) |
|
{ |
|
/* syslog(LOG_INFO, "Received NFQUEUE Packet");*/ |
|
ProcessNFQUEUE(nfqh); |
|
} |
|
#endif |
|
/* Create a new upnphttp object and add it to |
/* Create a new upnphttp object and add it to |
* the active upnphttp object list */ |
* the active upnphttp object list */ |
tmp = New_upnphttp(shttp); |
tmp = New_upnphttp(shttp); |
if(tmp) |
if(tmp) |
{ |
{ |
|
#ifdef ENABLE_IPV6 |
|
if(clientname.ss_family == AF_INET) |
|
{ |
|
tmp->clientaddr = ((struct sockaddr_in *)&clientname)->sin_addr; |
|
} |
|
else if(clientname.ss_family == AF_INET6) |
|
{ |
|
struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&clientname; |
|
if(IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr)) |
|
{ |
|
memcpy(&tmp->clientaddr, |
|
&addr->sin6_addr.s6_addr[12], |
|
4); |
|
} |
|
else |
|
{ |
|
tmp->ipv6 = 1; |
|
memcpy(&tmp->clientaddr_v6, |
|
&addr->sin6_addr, |
|
sizeof(struct in6_addr)); |
|
} |
|
} |
|
#else |
tmp->clientaddr = clientname.sin_addr; |
tmp->clientaddr = clientname.sin_addr; |
|
#endif |
LIST_INSERT_HEAD(&upnphttphead, tmp, entries); |
LIST_INSERT_HEAD(&upnphttphead, tmp, entries); |
} |
} |
else |
else |
Line 1445 main(int argc, char * * argv)
|
Line 1600 main(int argc, char * * argv)
|
} |
} |
} |
} |
} |
} |
|
#ifdef ENABLE_NFQUEUE |
|
/* process NFQ packets */ |
|
if(nfqh >= 0 && FD_ISSET(nfqh, &readset)) |
|
{ |
|
/* syslog(LOG_INFO, "Received NFQUEUE Packet");*/ |
|
ProcessNFQUEUE(nfqh); |
|
} |
|
#endif |
/* delete finished HTTP connections */ |
/* delete finished HTTP connections */ |
for(e = upnphttphead.lh_first; e != NULL; ) |
for(e = upnphttphead.lh_first; e != NULL; ) |
{ |
{ |
Line 1457 main(int argc, char * * argv)
|
Line 1620 main(int argc, char * * argv)
|
e = next; |
e = next; |
} |
} |
|
|
/* send public address change notifications */ |
|
if(should_send_public_address_change_notif) |
|
{ |
|
#ifdef ENABLE_NATPMP |
|
if(GETFLAG(ENABLENATPMPMASK)) |
|
SendNATPMPPublicAddressChangeNotification(snatpmp/*snotify*/, n_lan_addr); |
|
#endif |
|
#ifdef ENABLE_EVENTS |
|
if(GETFLAG(ENABLEUPNPMASK)) |
|
{ |
|
upnp_event_var_change_notify(EWanIPC); |
|
} |
|
#endif |
|
should_send_public_address_change_notif = 0; |
|
} |
|
} /* end of main loop */ |
} /* end of main loop */ |
|
|
shutdown: |
shutdown: |
Line 1485 shutdown:
|
Line 1633 shutdown:
|
|
|
if (sudp >= 0) close(sudp); |
if (sudp >= 0) close(sudp); |
if (shttpl >= 0) close(shttpl); |
if (shttpl >= 0) close(shttpl); |
|
#ifdef ENABLE_IPV6 |
|
if (sudpv6 >= 0) close(sudpv6); |
|
//if (shttplv6 >= 0) close(shttplv6); |
|
#endif |
|
#ifdef USE_IFACEWATCHER |
|
if(sifacewatcher >= 0) close(sifacewatcher); |
|
#endif |
#ifdef ENABLE_NATPMP |
#ifdef ENABLE_NATPMP |
for(i=0; i<n_lan_addr; i++) { | for(i=0; i<addr_count; i++) { |
if(snatpmp[i]>=0) |
if(snatpmp[i]>=0) |
{ |
{ |
close(snatpmp[i]); |
close(snatpmp[i]); |
Line 1509 shutdown:
|
Line 1664 shutdown:
|
/*if(SendSSDPGoodbye(snotify, v.n_lan_addr) < 0)*/ |
/*if(SendSSDPGoodbye(snotify, v.n_lan_addr) < 0)*/ |
if (GETFLAG(ENABLEUPNPMASK)) |
if (GETFLAG(ENABLEUPNPMASK)) |
{ |
{ |
if(SendSSDPGoodbye(snotify, n_lan_addr) < 0) | if(SendSSDPGoodbye(snotify, addr_count) < 0) |
{ |
{ |
syslog(LOG_ERR, "Failed to broadcast good-bye notifications"); |
syslog(LOG_ERR, "Failed to broadcast good-bye notifications"); |
} |
} |
for(i=0; i<n_lan_addr; i++)/* for(i=0; i<v.n_lan_addr; i++)*/ | for(i=0; i<addr_count; i++) |
close(snotify[i]); |
close(snotify[i]); |
} |
} |
|
|
Line 1522 shutdown:
|
Line 1677 shutdown:
|
syslog(LOG_ERR, "Failed to remove pidfile %s: %m", pidfilename); |
syslog(LOG_ERR, "Failed to remove pidfile %s: %m", pidfilename); |
} |
} |
|
|
|
/* delete lists */ |
|
while(lan_addrs.lh_first != NULL) |
|
{ |
|
lan_addr = lan_addrs.lh_first; |
|
LIST_REMOVE(lan_addrs.lh_first, list); |
|
free(lan_addr); |
|
} |
|
|
|
#ifdef ENABLE_NATPMP |
|
free(snatpmp); |
|
#endif |
|
free(snotify); |
closelog(); |
closelog(); |
freeoptions(); |
freeoptions(); |
|
|