2 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * Copyright (c) 2006, Thomas Bernard
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/ioctl.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
37 #include <arpa/inet.h>
38 #include <netinet/in.h>
42 #include <sys/sockio.h>
45 #include "getifaddr.h"
49 getifaddr(const char * ifname
, char * buf
, int len
)
51 /* SIOCGIFADDR struct ifreq * */
55 struct sockaddr_in
* addr
;
60 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
63 DPRINTF(E_ERROR
, L_GENERAL
, "socket(PF_INET, SOCK_DGRAM): %s\n", strerror(errno
));
66 strncpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
67 if(ioctl(s
, SIOCGIFADDR
, &ifr
, &ifrlen
) < 0)
69 DPRINTF(E_ERROR
, L_GENERAL
, "ioctl(s, SIOCGIFADDR, ...): %s\n", strerror(errno
));
73 addr
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
74 if(!inet_ntop(AF_INET
, &addr
->sin_addr
, buf
, len
))
76 DPRINTF(E_ERROR
, L_GENERAL
, "inet_ntop(): %s\n", strerror(errno
));
80 if(ioctl(s
, SIOCGIFNETMASK
, &ifr
, &ifrlen
) == 0)
82 addr
= (struct sockaddr_in
*)&ifr
.ifr_netmask
;
83 mask
= ntohl(addr
->sin_addr
.s_addr
);
84 for (i
= 0; i
< 32; i
++)
93 snprintf(buf
+i
, len
-i
, "/%u", mask
);
97 DPRINTF(E_ERROR
, L_GENERAL
, "ioctl(s, SIOCGIFNETMASK, ...): %s\n", strerror(errno
));
103 getsysaddr(char * buf
, int len
)
106 int s
= socket(PF_INET
, SOCK_STREAM
, 0);
107 struct sockaddr_in addr
;
112 for (i
=1; i
> 0; i
++)
115 if( ioctl(s
, SIOCGIFNAME
, &ifr
) < 0 )
117 if(ioctl(s
, SIOCGIFADDR
, &ifr
, sizeof(struct ifreq
)) < 0)
119 memcpy(&addr
, &ifr
.ifr_addr
, sizeof(addr
));
120 if(strncmp(inet_ntoa(addr
.sin_addr
), "127.", 4) == 0)
122 if(ioctl(s
, SIOCGIFNETMASK
, &ifr
, sizeof(struct ifreq
)) < 0)
124 if(!inet_ntop(AF_INET
, &addr
.sin_addr
, buf
, len
))
126 DPRINTF(E_ERROR
, L_GENERAL
, "inet_ntop(): %s\n", strerror(errno
));
132 memcpy(&addr
, &ifr
.ifr_netmask
, sizeof(addr
));
133 mask
= ntohl(addr
.sin_addr
.s_addr
);
134 for (i
= 0; i
< 32; i
++)
143 snprintf(buf
+i
, len
-i
, "/%u", mask
);
153 getsyshwaddr(char * buf
, int len
)
155 struct if_nameindex
*ifaces
, *if_idx
;
156 unsigned char mac
[6];
161 memset(&mac
, '\0', sizeof(mac
));
162 /* Get the spatially unique node identifier */
163 fd
= socket(AF_INET
, SOCK_DGRAM
, 0);
167 ifaces
= if_nameindex();
171 for(if_idx
= ifaces
; if_idx
->if_index
; if_idx
++)
173 strncpy(ifr
.ifr_name
, if_idx
->if_name
, IFNAMSIZ
);
174 if(ioctl(fd
, SIOCGIFFLAGS
, &ifr
) < 0)
176 if(ifr
.ifr_ifru
.ifru_flags
& IFF_LOOPBACK
)
178 if( ioctl(fd
, SIOCGIFHWADDR
, &ifr
) < 0 )
180 if( MACADDR_IS_ZERO(ifr
.ifr_hwaddr
.sa_data
) )
185 if_freenameindex(ifaces
);
192 memmove(mac
, ifr
.ifr_hwaddr
.sa_data
, 6);
193 sprintf(buf
, "%02x%02x%02x%02x%02x%02x",
194 mac
[0]&0xFF, mac
[1]&0xFF, mac
[2]&0xFF,
195 mac
[3]&0xFF, mac
[4]&0xFF, mac
[5]&0xFF);
199 memmove(buf
, ifr
.ifr_hwaddr
.sa_data
, 6);
206 get_remote_mac(struct in_addr ip_addr
, unsigned char * mac
)
208 struct in_addr arp_ent
;
211 int matches
, hwtype
, flags
;
212 memset(mac
, 0xFF, 6);
214 arp
= fopen("/proc/net/arp", "r");
219 matches
= fscanf(arp
, "%15s 0x%8X 0x%8X %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
220 remote_ip
, &hwtype
, &flags
,
221 &mac
[0], &mac
[1], &mac
[2], &mac
[3], &mac
[4], &mac
[5]);
224 inet_pton(AF_INET
, remote_ip
, &arp_ent
);
225 if( ip_addr
.s_addr
== arp_ent
.s_addr
)
233 memset(mac
, 0xFF, 6);