1 /* $Id: upnputils.c,v 1.6 2013/02/06 10:50:04 nanard Exp $ */
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2013 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
20 #include <net/if_dl.h>
23 #include "upnputils.h"
24 #include "upnpglobalvars.h"
30 sockaddr_to_string(const struct sockaddr
* addr
, char * str
, size_t size
)
33 unsigned short port
= 0;
36 switch(addr
->sa_family
)
39 inet_ntop(addr
->sa_family
,
40 &((struct sockaddr_in6
*)addr
)->sin6_addr
,
41 buffer
, sizeof(buffer
));
42 port
= ntohs(((struct sockaddr_in6
*)addr
)->sin6_port
);
43 n
= snprintf(str
, size
, "[%s]:%hu", buffer
, port
);
46 inet_ntop(addr
->sa_family
,
47 &((struct sockaddr_in
*)addr
)->sin_addr
,
48 buffer
, sizeof(buffer
));
49 port
= ntohs(((struct sockaddr_in
*)addr
)->sin_port
);
50 n
= snprintf(str
, size
, "%s:%hu", buffer
, port
);
54 /* solaris does not seem to have link_ntoa */
55 /* #define link_ntoa _link_ntoa */
56 #define link_ntoa(x) "dummy-link_ntoa"
60 struct sockaddr_dl
* sdl
= (struct sockaddr_dl
*)addr
;
61 n
= snprintf(str
, size
, "index=%hu type=%d %s",
62 sdl
->sdl_index
, sdl
->sdl_type
,
68 n
= snprintf(str
, size
, "unknown address family %d", addr
->sa_family
);
70 n
= snprintf(str
, size
, "unknown address family %d "
71 "%02x %02x %02x %02x %02x %02x %02x %02x",
73 addr
->sa_data
[0], addr
->sa_data
[1], (unsigned)addr
->sa_data
[2], addr
->sa_data
[3],
74 addr
->sa_data
[4], addr
->sa_data
[5], (unsigned)addr
->sa_data
[6], addr
->sa_data
[7]);
82 set_non_blocking(int fd
)
84 int flags
= fcntl(fd
, F_GETFL
);
87 if(fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
) < 0)
93 get_lan_for_peer(const struct sockaddr
* peer
)
95 struct lan_addr_s
* lan_addr
= NULL
;
98 if(peer
->sa_family
== AF_INET6
)
100 struct sockaddr_in6
* peer6
= (struct sockaddr_in6
*)peer
;
101 if(IN6_IS_ADDR_V4MAPPED(&peer6
->sin6_addr
))
103 struct in_addr peer_addr
;
104 memcpy(&peer_addr
, &peer6
->sin6_addr
.s6_addr
[12], 4);
105 for(lan_addr
= lan_addrs
.lh_first
;
107 lan_addr
= lan_addr
->list
.le_next
)
109 if( (peer_addr
.s_addr
& lan_addr
->mask
.s_addr
)
110 == (lan_addr
->addr
.s_addr
& lan_addr
->mask
.s_addr
))
117 if(get_src_for_route_to(peer
, NULL
, NULL
, &index
) < 0)
119 syslog(LOG_DEBUG
, "%s looking for LAN interface index=%d",
120 "get_lan_for_peer()", index
);
121 for(lan_addr
= lan_addrs
.lh_first
;
123 lan_addr
= lan_addr
->list
.le_next
)
126 "ifname=%s index=%u str=%s addr=%08x mask=%08x",
127 lan_addr
->ifname
, lan_addr
->index
,
129 ntohl(lan_addr
->addr
.s_addr
),
130 ntohl(lan_addr
->mask
.s_addr
));
131 if(index
== (int)lan_addr
->index
)
136 else if(peer
->sa_family
== AF_INET
)
139 for(lan_addr
= lan_addrs
.lh_first
;
141 lan_addr
= lan_addr
->list
.le_next
)
143 if( (((const struct sockaddr_in
*)peer
)->sin_addr
.s_addr
& lan_addr
->mask
.s_addr
)
144 == (lan_addr
->addr
.s_addr
& lan_addr
->mask
.s_addr
))
152 syslog(LOG_DEBUG
, "%s: found in LAN %s %s",
153 "get_lan_for_peer()", lan_addr
->ifname
, lan_addr
->str
);
155 syslog(LOG_DEBUG
, "%s: not found !", "get_lan_for_peer()");