00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "utils/includes.h"
00016 #include <sys/ioctl.h>
00017 #include <net/if.h>
00018 #include <net/if_arp.h>
00019
00020 #include "utils/common.h"
00021 #include "linux_ioctl.h"
00022
00023
00024 int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
00025 {
00026 struct ifreq ifr;
00027
00028 if (sock < 0)
00029 return -1;
00030
00031 os_memset(&ifr, 0, sizeof(ifr));
00032 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
00033
00034 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
00035 wpa_printf(MSG_ERROR, "Could not read interface %s flags: %s",
00036 ifname, strerror(errno));
00037 return -1;
00038 }
00039
00040 if (dev_up) {
00041 if (ifr.ifr_flags & IFF_UP)
00042 return 0;
00043 ifr.ifr_flags |= IFF_UP;
00044 } else {
00045 if (!(ifr.ifr_flags & IFF_UP))
00046 return 0;
00047 ifr.ifr_flags &= ~IFF_UP;
00048 }
00049
00050 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
00051 wpa_printf(MSG_ERROR, "Could not set interface %s flags: %s",
00052 ifname, strerror(errno));
00053 return -1;
00054 }
00055
00056 return 0;
00057 }
00058
00059
00060 int linux_get_ifhwaddr(int sock, const char *ifname, u8 *addr)
00061 {
00062 struct ifreq ifr;
00063
00064 os_memset(&ifr, 0, sizeof(ifr));
00065 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
00066 if (ioctl(sock, SIOCGIFHWADDR, &ifr)) {
00067 wpa_printf(MSG_ERROR, "Could not get interface %s hwaddr: %s",
00068 ifname, strerror(errno));
00069 return -1;
00070 }
00071
00072 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
00073 wpa_printf(MSG_ERROR, "%s: Invalid HW-addr family 0x%04x",
00074 ifname, ifr.ifr_hwaddr.sa_family);
00075 return -1;
00076 }
00077 os_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
00078
00079 return 0;
00080 }
00081
00082
00083 int linux_set_ifhwaddr(int sock, const char *ifname, const u8 *addr)
00084 {
00085 struct ifreq ifr;
00086
00087 os_memset(&ifr, 0, sizeof(ifr));
00088 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
00089 os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN);
00090 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
00091
00092 if (ioctl(sock, SIOCSIFHWADDR, &ifr)) {
00093 wpa_printf(MSG_DEBUG, "Could not set interface %s hwaddr: %s",
00094 ifname, strerror(errno));
00095 return -1;
00096 }
00097
00098 return 0;
00099 }
00100
00101
00102 #ifndef SIOCBRADDBR
00103 #define SIOCBRADDBR 0x89a0
00104 #endif
00105 #ifndef SIOCBRDELBR
00106 #define SIOCBRDELBR 0x89a1
00107 #endif
00108 #ifndef SIOCBRADDIF
00109 #define SIOCBRADDIF 0x89a2
00110 #endif
00111 #ifndef SIOCBRDELIF
00112 #define SIOCBRDELIF 0x89a3
00113 #endif
00114
00115
00116 int linux_br_add(int sock, const char *brname)
00117 {
00118 if (ioctl(sock, SIOCBRADDBR, brname) < 0) {
00119 wpa_printf(MSG_DEBUG, "Could not add bridge %s: %s",
00120 brname, strerror(errno));
00121 return -1;
00122 }
00123
00124 return 0;
00125 }
00126
00127
00128 int linux_br_del(int sock, const char *brname)
00129 {
00130 if (ioctl(sock, SIOCBRDELBR, brname) < 0) {
00131 wpa_printf(MSG_DEBUG, "Could not remove bridge %s: %s",
00132 brname, strerror(errno));
00133 return -1;
00134 }
00135
00136 return 0;
00137 }
00138
00139
00140 int linux_br_add_if(int sock, const char *brname, const char *ifname)
00141 {
00142 struct ifreq ifr;
00143 int ifindex;
00144
00145 ifindex = if_nametoindex(ifname);
00146 if (ifindex == 0)
00147 return -1;
00148
00149 os_memset(&ifr, 0, sizeof(ifr));
00150 os_strlcpy(ifr.ifr_name, brname, IFNAMSIZ);
00151 ifr.ifr_ifindex = ifindex;
00152 if (ioctl(sock, SIOCBRADDIF, &ifr) < 0) {
00153 wpa_printf(MSG_DEBUG, "Could not add interface %s into bridge "
00154 "%s: %s", ifname, brname, strerror(errno));
00155 return -1;
00156 }
00157
00158 return 0;
00159 }
00160
00161
00162 int linux_br_del_if(int sock, const char *brname, const char *ifname)
00163 {
00164 struct ifreq ifr;
00165 int ifindex;
00166
00167 ifindex = if_nametoindex(ifname);
00168 if (ifindex == 0)
00169 return -1;
00170
00171 os_memset(&ifr, 0, sizeof(ifr));
00172 os_strlcpy(ifr.ifr_name, brname, IFNAMSIZ);
00173 ifr.ifr_ifindex = ifindex;
00174 if (ioctl(sock, SIOCBRDELIF, &ifr) < 0) {
00175 wpa_printf(MSG_DEBUG, "Could not remove interface %s from "
00176 "bridge %s: %s", ifname, brname, strerror(errno));
00177 return -1;
00178 }
00179
00180 return 0;
00181 }
00182
00183
00184 int linux_br_get(char *brname, const char *ifname)
00185 {
00186 char path[128], brlink[128], *pos;
00187 os_snprintf(path, sizeof(path), "/sys/class/net/%s/brport/bridge",
00188 ifname);
00189 os_memset(brlink, 0, sizeof(brlink));
00190 if (readlink(path, brlink, sizeof(brlink) - 1) < 0)
00191 return -1;
00192 pos = os_strrchr(brlink, '/');
00193 if (pos == NULL)
00194 return -1;
00195 pos++;
00196 os_strlcpy(brname, pos, IFNAMSIZ);
00197 return 0;
00198 }