2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
14 * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
15 * Copyright (C) 2008 Steven Barth <steven@midlink.org>
19 #include <net/if_arp.h>
24 #include <linux/sockios.h>
25 #include <sys/ioctl.h>
27 #include <sys/types.h>
37 int sock_ifconfig = 0;
42 sock_ifconfig = socket(AF_INET, SOCK_DGRAM, 0);
46 void ifc_shutdown(void)
54 static int isdev(const struct dirent *entry)
56 if(*entry->d_name == '.')
61 static void ifc_addif(lua_State *L, char *ifname)
63 char *ip = malloc(32);
65 lua_pushstring(L, ifname);
67 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
69 if(!ioctl(sock_ifconfig, SIOCGIFADDR, &ifr))
71 ipv42char(&ifr.ifr_addr.sa_data[2], ip);
72 add_table_entry(L, "ip", ip);
75 if(!ioctl(sock_ifconfig, SIOCGIFNETMASK, &ifr))
77 ipv42char(&ifr.ifr_netmask.sa_data[2], ip);
78 add_table_entry(L, "netmask", ip);
81 if(!ioctl(sock_ifconfig, SIOCGIFBRDADDR, &ifr))
83 ipv42char(&ifr.ifr_broadaddr.sa_data[2], ip);
84 add_table_entry(L, "broadaddr", ip);
87 if(!ioctl(sock_ifconfig, SIOCGIFHWADDR, &ifr))
89 mac2char(ifr.ifr_hwaddr.sa_data, ip);
90 add_table_entry(L, "mac", ip);
93 if(!ioctl(sock_ifconfig, SIOCGIFFLAGS, &ifr))
95 if(ifr.ifr_flags & IFF_UP)
96 add_table_entry(L, "up", "1");
98 add_table_entry(L, "up", "0");
101 ioctl(sock_ifconfig, SIOCGIFMTU, &ifr);
102 lua_pushstring(L, "mtu");
103 lua_pushinteger(L, ifr.ifr_mtu);
109 #define SYSFS_CLASS_NET "/sys/class/net/"
110 int ifc_getall(lua_State *L)
113 struct dirent **namelist;
118 count = scandir(SYSFS_CLASS_NET, &namelist, isdev, alphasort);
124 for (i = 0; i < count; i++)
126 ifc_addif(L, namelist[i]->d_name);
131 ifc.ifc_len = sizeof(struct ifreq) * numreqs;
132 ifc.ifc_buf = malloc(ifc.ifc_len);
133 if(ioctl(sock_ifconfig, SIOCGIFCONF, &ifc) < 0)
136 for(i = 0; i < ifc.ifc_len; i += sizeof(struct ifreq))
138 if(strchr(ifr->ifr_name, ':'))
139 ifc_addif(L, ifr->ifr_name);
147 static inline int _ifc_setip(lua_State *L, int i)
151 if(lua_gettop(L) != 2)
153 lua_pushstring(L, "invalid arg list");
157 ifname = (char *)lua_tostring (L, 1);
158 ip = (char *)lua_tostring (L, 2);
159 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
160 ifr.ifr_addr.sa_family = AF_INET;
161 if(char2ipv4(ip, &ifr.ifr_addr.sa_data[2]))
163 lua_pushstring(L, "invalid ip");
167 if(!ioctl(sock_ifconfig, i, &ifr))
168 lua_pushboolean(L, 1);
170 lua_pushboolean(L, 0);
174 int ifc_setip(lua_State *L)
176 return _ifc_setip(L, SIOCSIFADDR);
179 int ifc_setnetmask(lua_State *L)
181 return _ifc_setip(L, SIOCGIFNETMASK);
184 int ifc_setbroadcast(lua_State *L)
186 return _ifc_setip(L, SIOCSIFBRDADDR);
189 int ifc_setmtu(lua_State *L)
194 if(lua_gettop(L) != 2)
196 lua_pushstring(L, "invalid arg list");
200 ifname = (char *)lua_tostring (L, 1);
201 mtu = (int)lua_tointeger (L, 2);
202 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
204 if(!ioctl(sock_ifconfig, SIOCSIFMTU, &ifr))
205 lua_pushboolean(L, 1);
207 lua_pushboolean(L, 0);
211 static int _ifc_up(lua_State *L, int up)
215 if(lua_gettop(L) != 1)
217 lua_pushstring(L, "invalid arg list");
222 ifname = (char *)lua_tostring (L, 1);
223 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
225 if(ioctl(sock_ifconfig, SIOCGIFFLAGS, &ifr) < 0)
227 lua_pushboolean(L, 0);
231 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
233 ifr.ifr_flags &= ~IFF_UP;
234 if(!ioctl(sock_ifconfig, SIOCSIFFLAGS, &ifr))
235 lua_pushboolean(L, 1);
237 lua_pushboolean(L, 0);
241 int ifc_up(lua_State *L)
243 return _ifc_up(L, 1);
246 int ifc_down(lua_State *L)
248 return _ifc_up(L, 0);