int wl_ioctl(char *name, int cmd, void *buf, int len) { struct ifreq ifr; wl_ioctl_t ioc; int ret = 0; int s; char nv_name[IFNAMSIZ], bwl_name[IFNAMSIZ]; int unit; if (osifname_to_nvifname(name, nv_name, sizeof(nv_name)) != 0) return -1; /* NVRAM I/F names for wireless devices are always wlX or wlX.Y */ if (strncmp(nv_name, "wl", 2)) return -1; if (get_ifname_unit(nv_name, &unit, NULL) != 0) return -1; snprintf(bwl_name, IFNAMSIZ, "bwl%d", unit); /* open socket to kernel */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return errno; } /* do it */ ioc.cmd = cmd; ioc.buf = buf; ioc.len = len; /* initializing the remaining fields */ ioc.set = FALSE; ioc.used = 0; ioc.needed = 0; /* strncpy(ifr.ifr_name, name, IFNAMSIZ); */ strncpy(ifr.ifr_name, bwl_name, IFNAMSIZ); ifr.ifr_data = (caddr_t) &ioc; if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0) { /* cprintf("%s: cmd=%d\n", __func__, cmd); */ if (cmd != WLC_GET_MAGIC) perror(ifr.ifr_name); } /* cleanup */ close(s); /* printf("%s(%d) ret %d\n", __func__, cmd, ret); */ return ret; }
int foreach_wif(int include_vifs, void *param, int (*func)(int idx, int unit, int subunit, void *param)) { char ifnames[256]; char name[64], ifname[64], *next = NULL; int unit = -1, subunit = -1; int i; int ret = 0; snprintf(ifnames, sizeof(ifnames), "%s %s %s %s %s %s %s %s %s %s", nvram_safe_get("lan_ifnames"), nvram_safe_get("lan1_ifnames"), nvram_safe_get("lan2_ifnames"), nvram_safe_get("lan3_ifnames"), nvram_safe_get("wan_ifnames"), nvram_safe_get("wl_ifname"), nvram_safe_get("wl0_ifname"), nvram_safe_get("wl0_vifs"), nvram_safe_get("wl1_ifname"), nvram_safe_get("wl1_vifs")); remove_dups(ifnames, sizeof(ifnames)); sort_list(ifnames, sizeof(ifnames)); i = 0; foreach(name, ifnames, next) { if (nvifname_to_osifname(name, ifname, sizeof(ifname)) != 0) continue; if (wl_probe(ifname) || wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit))) continue; // Convert eth name to wl name if (osifname_to_nvifname(name, ifname, sizeof(ifname)) != 0) continue; // Slave intefaces have a '.' in the name if (strchr(ifname, '.') && !include_vifs) continue; if (get_ifname_unit(ifname, &unit, &subunit) < 0) continue; ret |= func(i++, unit, subunit, param); } return ret; }
/* * Translate virtual interface mac to spoof mac * Rule: * 00:aa:bb:cc:dd:ee 00:00:00:x:y:z * wl0 ------------ [wlx/wlx.y/wdsx.y]0.1 ------ x=1/2/3, y=0, z=1 * +----------- [wlx/wlx.y/wdsx.y]0.2 ------ x=1/2/3, y=0, z=2 * wl1 ------------ [wlx/wlx.y/wdsx.y]1.1 ------ x=1/2/3, y=1, z=1 * +----------- [wlx/wlx.y/wdsx.y]1.2 ------ x=1/2/3, y=1, z=2 * * URE ON : wds/mbss not support and wlx.y have same mac as wlx * URE OFF : wlx.y have unique mac and wdsx.y have same mac as wlx * */ int get_spoof_mac(const char *osifname, char *mac, int maclen) { char nvifname[16]; int i, unit, subunit; wlif_name_desc_t *wlif_name; if (osifname == NULL || mac == NULL || maclen < ETHER_ADDR_LEN) return -1; if (osifname_to_nvifname(osifname, nvifname, sizeof(nvifname)) < 0) return -1; /* translate to spoof mac */ if (!get_ifname_unit(nvifname, &unit, &subunit)) { memset(mac, 0, maclen); for (i = 0; i < ARRAYSIZE(wlif_name_array); i++) { wlif_name = &wlif_name_array[i]; if (!strncmp(osifname, wlif_name->name, strlen(wlif_name->name))) { if (subunit >= 0 && wlif_name->subunit) break; else if (subunit < 0 && !wlif_name->subunit) { subunit = 0; /* reset to zero */ break; } } } /* not found */ if (i == ARRAYSIZE(wlif_name_array)) return -1; /* translate it */ mac[3] = i+1; mac[4] = unit; mac[5] = subunit; return 0; } return -1; }