Merge remote branch 'remotes/origin/Teaman-IPTraffic' into Teaman-ND
[tomato.git] / release / src / router / minidlna / getifaddr.c
blob44b002ba3fa62b7134431846fb5e9e46852151c4
1 /* $Id: getifaddr.c,v 1.12 2010/11/11 23:48:13 jmaggard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
5 * Copyright (c) 2006, Thomas Bernard
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <sys/ioctl.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <net/if.h>
38 #include <arpa/inet.h>
39 #include <netinet/in.h>
40 #include <netdb.h>
41 #include <errno.h>
42 #if defined(sun)
43 #include <sys/sockio.h>
44 #endif
46 #include "getifaddr.h"
47 #include "log.h"
49 int
50 getifaddr(const char * ifname, char * buf, int len)
52 /* SIOCGIFADDR struct ifreq * */
53 int s;
54 struct ifreq ifr;
55 int ifrlen;
56 struct sockaddr_in * addr;
57 ifrlen = sizeof(ifr);
58 s = socket(PF_INET, SOCK_DGRAM, 0);
59 if(s < 0)
61 DPRINTF(E_ERROR, L_GENERAL, "socket(PF_INET, SOCK_DGRAM): %s\n", strerror(errno));
62 return -1;
64 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
65 if(ioctl(s, SIOCGIFADDR, &ifr, &ifrlen) < 0)
67 DPRINTF(E_ERROR, L_GENERAL, "ioctl(s, SIOCGIFADDR, ...): %s\n", strerror(errno));
68 close(s);
69 return -1;
71 addr = (struct sockaddr_in *)&ifr.ifr_addr;
72 if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len))
74 DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno));
75 close(s);
76 return -1;
78 close(s);
79 return 0;
82 int
83 getsysaddr(char * buf, int len)
85 int i;
86 int s = socket(PF_INET, SOCK_STREAM, 0);
87 struct sockaddr_in addr;
88 struct ifreq ifr;
89 int ret = -1;
91 for (i=1; i > 0; i++)
93 ifr.ifr_ifindex = i;
94 if( ioctl(s, SIOCGIFNAME, &ifr) < 0 )
95 break;
96 if(ioctl(s, SIOCGIFADDR, &ifr, sizeof(struct ifreq)) < 0)
97 continue;
98 memcpy(&addr, &ifr.ifr_addr, sizeof(addr));
99 if(strncmp(inet_ntoa(addr.sin_addr), "127.", 4) == 0)
100 continue;
101 if(!inet_ntop(AF_INET, &addr.sin_addr, buf, len))
103 DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno));
104 close(s);
105 break;
107 ret = 0;
108 break;
110 close(s);
112 return(ret);
116 getsyshwaddr(char * buf, int len)
118 struct if_nameindex *ifaces, *if_idx;
119 unsigned char mac[6];
120 struct ifreq ifr;
121 int fd;
122 int ret = -1;
124 memset(&mac, '\0', sizeof(mac));
125 /* Get the spatially unique node identifier */
126 fd = socket(AF_INET, SOCK_DGRAM, 0);
127 if( fd < 0 )
128 return(ret);
130 ifaces = if_nameindex();
131 if(!ifaces)
132 return(ret);
134 for(if_idx = ifaces; if_idx->if_index; if_idx++)
136 strncpy(ifr.ifr_name, if_idx->if_name, IFNAMSIZ);
137 if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0)
138 continue;
139 if(ifr.ifr_ifru.ifru_flags & IFF_LOOPBACK)
140 continue;
141 if( ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 )
142 continue;
143 if( MACADDR_IS_ZERO(ifr.ifr_hwaddr.sa_data) )
144 continue;
145 ret = 0;
146 break;
148 if_freenameindex(ifaces);
149 close(fd);
151 if(ret == 0)
153 if(len > 12)
155 memmove(mac, ifr.ifr_hwaddr.sa_data, 6);
156 sprintf(buf, "%02x%02x%02x%02x%02x%02x",
157 mac[0]&0xFF, mac[1]&0xFF, mac[2]&0xFF,
158 mac[3]&0xFF, mac[4]&0xFF, mac[5]&0xFF);
160 else if(len == 6)
162 memmove(buf, ifr.ifr_hwaddr.sa_data, 6);
165 return ret;
169 get_remote_mac(struct in_addr ip_addr, unsigned char * mac)
171 struct in_addr arp_ent;
172 FILE * arp;
173 char remote_ip[16];
174 int matches, hwtype, flags;
175 memset(mac, 0xFF, 6);
177 arp = fopen("/proc/net/arp", "r");
178 if( !arp )
179 return 1;
180 while( !feof(arp) )
182 matches = fscanf(arp, "%s 0x%X 0x%X %hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
183 remote_ip, &hwtype, &flags,
184 &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
185 if( matches != 9 )
186 continue;
187 inet_pton(AF_INET, remote_ip, &arp_ent);
188 if( ip_addr.s_addr == arp_ent.s_addr )
189 break;
190 mac[0] = 0xFF;
192 fclose(arp);
194 if( mac[0] == 0xFF )
196 memset(mac, 0xFF, 6);
197 return 1;
200 return 0;