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);