static void setmedia(const char *val, int d, int s, const struct afswtch *afp) { struct ifmediareq *ifmr; int subtype; ifmr = ifmedia_getstate(s); /* * We are primarily concerned with the top-level type. * However, "current" may be only IFM_NONE, so we just look * for the top-level type in the first "supported type" * entry. * * (I'm assuming that all supported media types for a given * interface will be the same top-level type..) */ subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_media = (ifmr->ifm_current & ~(IFM_NMASK|IFM_TMASK)) | IFM_TYPE(ifmr->ifm_ulist[0]) | subtype; if ((ifr.ifr_media & IFM_TMASK) == 0) { ifr.ifr_media &= ~(IFM_GMASK | IFM_OMASK); } ifmr->ifm_current = ifr.ifr_media; callback_register(setifmediacallback, (void *)ifmr); }
/* * Set media options. */ int qe_ifmedia_upd(struct ifnet *ifp) { struct qe_softc *sc = ifp->if_softc; struct ifmedia *ifm = &sc->sc_ifmedia; bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t mr = sc->sc_mr; int newmedia = ifm->ifm_media; uint8_t plscc, phycc; #if defined(SUN4U) || defined(__GNUC__) (void)&t; #endif if (IFM_TYPE(newmedia) != IFM_ETHER) return (EINVAL); plscc = bus_space_read_1(t, mr, QE_MRI_PLSCC) & ~QE_MR_PLSCC_PORTMASK; phycc = bus_space_read_1(t, mr, QE_MRI_PHYCC) & ~QE_MR_PHYCC_ASEL; if (IFM_SUBTYPE(newmedia) == IFM_AUTO) phycc |= QE_MR_PHYCC_ASEL; else if (IFM_SUBTYPE(newmedia) == IFM_10_T) plscc |= QE_MR_PLSCC_TP; else if (IFM_SUBTYPE(newmedia) == IFM_10_5) plscc |= QE_MR_PLSCC_AUI; bus_space_write_1(t, mr, QE_MRI_PLSCC, plscc); bus_space_write_1(t, mr, QE_MRI_PHYCC, phycc); return (0); }
int lemediachange(struct lance_softc *sc) { struct ifmedia *ifm = &sc->sc_media; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); /* * Switch to the selected media. If autoselect is * set, we don't really have to do anything. We'll * switch to the other media when we detect loss of * carrier. */ switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_10_T: lesetutp(sc); break; case IFM_10_5: lesetaui(sc); break; case IFM_AUTO: break; default: return (EINVAL); } return (0); }
int init_current_media(int s, char *ifname) { int media_current; struct ifmediareq ifmr; (void) memset(&ifmr, 0, sizeof(ifmr)); (void) strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); if (ioctl(s, SIOCGIFMEDIA, (caddr_t) & ifmr) < 0) { /* * If we get E2BIG, the kernel is telling us * that there are more, so we can ignore it. */ if (errno != E2BIG) return(-1); } media_current = ifmr.ifm_current; /* Sanity. */ if (IFM_TYPE(media_current) == 0) { printf("%% init_current_media: %s: no link type?\n", ifname); return(-1); } return(media_current); }
int rtems_ifmedia2str (int media, char *buf, int bufsz) { const char *mdesc; const char *dupdesc = 0; /* only ethernet supported, so far */ if (IFM_ETHER != IFM_TYPE (media)) return -1; if (!(mdesc = find_desc (IFM_SUBTYPE (media), shared_media_strings))) mdesc = find_desc (IFM_SUBTYPE (media), ethern_media_strings); if (!mdesc) return -1; if (IFM_NONE != IFM_SUBTYPE (media)) dupdesc = IFM_FDX & media ? " full-duplex" : " half-duplex"; return WHATPRINT (buf, bufsz, "Ethernet [phy instance: %" PRId32 "]: (link %s, autoneg %s) -- media: %s%s", (int32_t) IFM_INST (media), IFM_LINK_OK & media ? "ok" : "down", IFM_ANEG_DIS & media ? "off" : "on", mdesc, dupdesc ? dupdesc : ""); }
static int tr_pcmcia_mediachange(struct tr_softc *sc) { int setspeed = 0; if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_TOKEN) return EINVAL; switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) { case IFM_TOK_STP16: case IFM_TOK_UTP16: if ((sc->sc_init_status & RSP_16) == 0) setspeed = 1; break; case IFM_TOK_STP4: case IFM_TOK_UTP4: if ((sc->sc_init_status & RSP_16) != 0) setspeed = 1; break; } if (setspeed != 0) { tr_stop(sc); if (sc->sc_enabled) tr_pcmcia_disable(sc); sc->sc_init_status ^= RSP_16; /* XXX 100 Mbit/s */ if (sc->sc_enabled) tr_pcmcia_enable(sc); } /* * XXX Handle Early Token Release !!!! */ return 0; }
static bool s_wireless_nic (const char* name) { int sock = 0; bool result = FALSE; if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return FALSE; #if defined (SIOCGIFMEDIA) struct ifmediareq ifmr; memset (&ifmr, 0, sizeof (struct ifmediareq)); strncpy(ifmr.ifm_name, name, sizeof (ifmr.ifm_name)); int res = ioctl (sock, SIOCGIFMEDIA, (caddr_t) &ifmr); if (res != -1) result = (IFM_TYPE (ifmr.ifm_current) == IFM_IEEE80211); #elif defined (SIOCGIWNAME) struct iwreq wrq; memset (&wrq, 0, sizeof (struct iwreq)); strncpy (wrq.ifr_name, name, sizeof (wrq.ifr_name)); int res = ioctl (sock, SIOCGIWNAME, (caddr_t) &wrq); if (res != -1) result = TRUE; #endif close (sock); return result; }
static void set_port_media(struct cfg *cfg, char *argv[]) { etherswitch_port_t p; int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; int subtype; bzero(&p, sizeof(p)); p.es_port = cfg->unit; p.es_ifmr.ifm_ulist = ifm_ulist; p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); subtype = get_media_subtype(IFM_TYPE(ifm_ulist[0]), argv[1]); p.es_ifr.ifr_media = (p.es_ifmr.ifm_current & IFM_IMASK) | IFM_TYPE(ifm_ulist[0]) | subtype; if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); }
static struct ifmedia_description *get_toptype_desc(int ifmw) { struct ifmedia_description *desc; for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) if (IFM_TYPE(ifmw) == desc->ifmt_word) break; return desc; }
static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw) { struct ifmedia_description *desc; struct ifmedia_type_to_subtype *ttos; for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes; desc->ifmt_string != NULL; desc++, ttos++) if (IFM_TYPE(ifmw) == desc->ifmt_word) break; return ttos; }
bool NetworkInterface::isWireless() { struct ifmediareq ifm; memset(&ifm, 0, sizeof(struct ifmediareq)); strncpy(ifm.ifm_name, name.toLocal8Bit(), IFNAMSIZ); int s = socket(AF_INET, SOCK_DGRAM, 0); ioctl(s, SIOCGIFMEDIA, &ifm); return IFM_TYPE(ifm.ifm_active) == IFM_IEEE80211; }
const char * get_media_type_string(uint64_t mword) { const struct ifmedia_description *desc; for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) { if (IFM_TYPE(mword) == desc->ifmt_word) return (desc->ifmt_string); } return ("<unknown type>"); }
/********************************************************************* * * Media Ioctl callback * * This routine is called when the user changes speed/duplex using * media/mediopt option with ifconfig. * **********************************************************************/ int ixl_if_media_change(if_ctx_t ctx) { struct ifmedia *ifm = iflib_get_media(ctx); INIT_DEBUGOUT("ixl_media_change: begin"); if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); if_printf(iflib_get_ifp(ctx), "Media change is currently not supported.\n"); return (ENODEV); }
int intmediaopt(char *ifname, int ifs, int argc, char **argv) { int set, media_current, mediaopt; if (NO_ARG(argv[0])) { set = 0; argc--; argv++; } else set = 1; argv++; argc--; if ((set && (argc != 1)) || (!set && (argc > 1))) { printf("%% mediaopt <option>\n"); printf("%% no mediaopt [option]\n"); return(0); } media_current = init_current_media(ifs, ifname); if (media_current == -1) { if (errno == EINVAL) printf("%% This device does not support " "media commands.\n"); else printf("%% Failed to initialize media: %s\n", strerror(errno)); return(0); } if (argc == 1) mediaopt = get_media_options(IFM_TYPE(media_current), argv[0]); else mediaopt = IFM_OPTIONS(media_current); if (mediaopt == -1) return(0); if (set) media_current |= mediaopt; else media_current &= ~mediaopt; process_media_commands(ifs, ifname, media_current); return(0); }
static int sln_media_upd(struct ifnet *ifp) { struct sln_softc *sc = ifp->if_softc; struct ifmedia *ifm = &sc->ifmedia; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return EINVAL; if (ifp->if_flags & IFF_UP) sln_init(sc); return 0; }
void media_supported(int s, char *ifname, char *hdr_delim, char *body_delim) { u_int64_t *media_list; int i, type, printed_type; struct ifmediareq ifmr; memset(&ifmr, 0, sizeof(ifmr)); strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { if (errno != ENOTTY) printf("%% media_supported: 1/SIOCGIFMEDIA: %s\n", strerror(errno)); return; } media_list = calloc(ifmr.ifm_count, sizeof(*media_list)); if (media_list == NULL) { printf("%% media_status: calloc: %s\n", strerror(errno)); return; } ifmr.ifm_ulist = media_list; if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { printf("%% media_supported: 2/SIOCGIFMEDIA: %s\n", strerror(errno)); return; } for (type = IFM_NMIN; type <= IFM_NMAX; type += IFM_NMIN) { for (i = 0, printed_type = 0; i < ifmr.ifm_count; i++) { if (IFM_TYPE(media_list[i]) == type) { if (printed_type == 0) { printf("%sSupported media types on %s:\n", hdr_delim, ifname); printed_type = 1; } printf("%s", body_delim); print_media_word(media_list[i], 0, 1); printf("\n"); } } } free(media_list); return; }
static void setmediamode(const char *val, int d, int s, const struct afswtch *afp) { struct ifmediareq *ifmr; int mode; ifmr = ifmedia_getstate(s); mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode; ifmr->ifm_current = ifr.ifr_media; callback_register(setifmediacallback, (void *)ifmr); }
static Boolean isVPNInterfaceWifi (struct service *serv) { u_int32_t media; char *interface_buf = getVPNInterfaceBuf(serv); if (interface_buf && interface_buf[0]) { media = get_if_media(interface_buf); } else { media = 0; } if (IFM_TYPE(media) == IFM_IEEE80211) { return true; } return false; }
int connection_active(char *if_name, int if_type) { /* * Returns 1 if the network status on the interface is active. * if_type: 0 for ethernet, 1 for ieee80211 */ struct ifmediareq ifmr; const struct ifmedia_status_description *ifms; static const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST; static const struct ifmedia_status_description ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS; int bit = 0, s = -1, res; s = open_socket(AF_INET); if (s < 0) { printf("error opening socket: %s\n", strerror(errno)); } memset(&ifmr, 0, sizeof(ifmr)); strlcpy(ifmr.ifm_name, if_name, sizeof(ifmr.ifm_name)); res = ioctl(s, SIOCGIFMEDIA, (caddr_t) & ifmr); close(s); if (res) { printf("res: %d (%s)\n", res, strerror(errno)); return 0; } if (if_type) { /* ieee80211 check */ if (IFM_ACTIVE) { printf("connection_active: ieee80211 network is active\n"); return 1; } printf("connection_active: ieee80211 failed check\n"); return 0; } else { /* ethernet check */ for (ifms = ifm_status_descriptions; ifms->ifms_valid != 0; ifms++) { if (ifms->ifms_type == IFM_TYPE(ifmr.ifm_current)) if (strcmp(IFM_STATUS_DESC(ifms, ifmr.ifm_status), "active") == 0) { printf("connection_active: ethernet network is active\n"); return 1; } else { printf("connection_active: ethernet failed check\n"); return 0; } } } }
/* * FreeBSD allows for Virtual Access Points * We need to check if the interface is a Virtual Interface Master * and if so, don't use it. * This check is made by virtue of being a IEEE80211 device but * returning the SSID gives an error. */ int if_vimaster(const char *ifname) { struct ifmediareq ifmr; memset(&ifmr, 0, sizeof(ifmr)); strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); if (ioctl(socket_afnet, SIOCGIFMEDIA, &ifmr) == -1) return -1; if (ifmr.ifm_status & IFM_AVALID && IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) { if (getifssid(ifname, NULL) == -1) return 1; } return 0; }
static int le_pci_mediachange(struct lance_softc *sc) { struct ifmedia *ifm = &sc->sc_media; uint16_t reg; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); if (IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) le_pci_wrbcr(sc, LE_BCR49, (le_pci_rdbcr(sc, LE_BCR49) & ~LE_B49_PHYSEL) | 0x1); else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) le_pci_wrbcr(sc, LE_BCR2, le_pci_rdbcr(sc, LE_BCR2) | LE_B2_ASEL); else { le_pci_wrbcr(sc, LE_BCR2, le_pci_rdbcr(sc, LE_BCR2) & ~LE_B2_ASEL); reg = le_pci_rdcsr(sc, LE_CSR15); reg &= ~LE_C15_PORTSEL(LE_PORTSEL_MASK); if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) reg |= LE_C15_PORTSEL(LE_PORTSEL_10T); else reg |= LE_C15_PORTSEL(LE_PORTSEL_AUI); le_pci_wrcsr(sc, LE_CSR15, reg); } reg = le_pci_rdbcr(sc, LE_BCR9); if (IFM_OPTIONS(ifm->ifm_media) & IFM_FDX) { reg |= LE_B9_FDEN; /* * Allow FDX on AUI only if explicitly chosen, * not in autoselect mode. */ if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_5) reg |= LE_B9_AUIFD; else reg &= ~LE_B9_AUIFD; } else reg &= ~LE_B9_FDEN; le_pci_wrbcr(sc, LE_BCR9, reg); return (0); }
static void domediaopt(const char *val, int clear, int s) { struct ifmediareq *ifmr; int options; ifmr = ifmedia_getstate(s); options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_media = ifmr->ifm_current; if (clear) ifr.ifr_media &= ~options; else ifr.ifr_media |= options; ifmr->ifm_current = ifr.ifr_media; callback_register(setifmediacallback, (void *)ifmr); }
/* * FreeBSD allows for Virtual Access Points * We need to check if the interface is a Virtual Interface Master * and if so, don't use it. * This check is made by virtue of being a IEEE80211 device but * returning the SSID gives an error. */ int if_vimaster(const char *ifname) { int s, r; struct ifmediareq ifmr; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return -1; memset(&ifmr, 0, sizeof(ifmr)); strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); r = ioctl(s, SIOCGIFMEDIA, &ifmr); close(s); if (r == -1) return -1; if (ifmr.ifm_status & IFM_AVALID && IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) { if (if_getssid1(ifname, NULL) == -1) return 1; } return 0; }
QString NetworkInterface::mediaStatusAsString() { struct ifmediareq ifm; memset(&ifm, 0, sizeof(struct ifmediareq)); strncpy(ifm.ifm_name, name.toLocal8Bit(), IFNAMSIZ); int s = socket(AF_INET, SOCK_DGRAM, 0); ioctl(s, SIOCGIFMEDIA, &ifm); QString status; switch (IFM_TYPE(ifm.ifm_active)) { case IFM_IEEE80211: if (ifm.ifm_status & IFM_ACTIVE) status = "associated"; else status = "no carrier"; break; default: if (ifm.ifm_status & IFM_ACTIVE) status = "active"; else status = "no carrier"; } return status; }
int mc_mediachange(struct mc_softc *sc) { struct ifmedia *ifm = &sc->sc_media; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return EINVAL; switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_10_T: mc_select_utp(sc); break; case IFM_10_5: mc_select_aui(sc); break; default: return EINVAL; } return 0; }
static void set_port_mediaopt(struct cfg *cfg, char *argv[]) { etherswitch_port_t p; int ifm_ulist[IFMEDIAREQ_NULISTENTRIES]; int options; bzero(&p, sizeof(p)); p.es_port = cfg->unit; p.es_ifmr.ifm_ulist = ifm_ulist; p.es_ifmr.ifm_count = IFMEDIAREQ_NULISTENTRIES; if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); options = get_media_options(IFM_TYPE(ifm_ulist[0]), argv[1]); if (options == -1) errx(EX_USAGE, "invalid media options \"%s\"", argv[1]); if (options & IFM_HDX) { p.es_ifr.ifr_media &= ~IFM_FDX; options &= ~IFM_HDX; } p.es_ifr.ifr_media |= options; if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); }
void configure_interface(int socket, const char* name, char* const* args, int32 argCount) { ifreq request; if (!prepare_request(request, name)) return; uint32 index = 0; if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) >= 0) index = request.ifr_index; bool hasAddress = false, hasMask = false, hasPeer = false; bool hasBroadcast = false, doAutoConfig = false; struct sockaddr address, mask, peer, broadcast; int mtu = -1, metric = -1, media = -1; int addFlags = 0, currentFlags = 0, removeFlags = 0; // try to parse address family int32 familyIndex; int32 i = 0; if (get_address_family(args[i], familyIndex)) i++; if (kFamilies[familyIndex].family != AF_INET) { close(socket); // replace socket with one of the correct address family socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0); if (socket < 0) { fprintf(stderr, "%s: Address family \"%s\" is not available.\n", kProgramName, kFamilies[familyIndex].name); exit(1); } } if (index == 0) { // the interface does not exist yet, we have to add it first request.ifr_parameter.base_name[0] = '\0'; request.ifr_parameter.device[0] = '\0'; request.ifr_parameter.sub_type = 0; // the default device is okay for us if (ioctl(socket, SIOCAIFADDR, &request, sizeof(request)) < 0) { fprintf(stderr, "%s: Could not add interface: %s\n", kProgramName, strerror(errno)); exit(1); } } // try to parse address if (parse_address(familyIndex, args[i], address)) { hasAddress = true; i++; if (parse_address(familyIndex, args[i], mask)) { hasMask = true; i++; } } // parse parameters and flags while (i < argCount) { if (!strcmp(args[i], "peer")) { if (!parse_address(familyIndex, args[i + 1], peer)) { fprintf(stderr, "%s: Option 'peer' needs valid address " "parameter\n", kProgramName); exit(1); } hasPeer = true; i++; } else if (!strcmp(args[i], "nm") || !strcmp(args[i], "netmask")) { if (hasMask) { fprintf(stderr, "%s: Netmask is specified twice\n", kProgramName); exit(1); } if (!parse_address(familyIndex, args[i + 1], mask)) { fprintf(stderr, "%s: Option 'netmask' needs valid address " "parameter\n", kProgramName); exit(1); } hasMask = true; i++; } else if (!strcmp(args[i], "bc") || !strcmp(args[i], "broadcast")) { if (hasBroadcast) { fprintf(stderr, "%s: broadcast address is specified twice\n", kProgramName); exit(1); } if (!parse_address(familyIndex, args[i + 1], broadcast)) { fprintf(stderr, "%s: Option 'broadcast' needs valid address " "parameter\n", kProgramName); exit(1); } hasBroadcast = true; addFlags |= IFF_BROADCAST; i++; } else if (!strcmp(args[i], "mtu")) { mtu = args[i + 1] ? strtol(args[i + 1], NULL, 0) : 0; if (mtu <= 500) { fprintf(stderr, "%s: Option 'mtu' expected valid max transfer " "unit size\n", kProgramName); exit(1); } i++; } else if (!strcmp(args[i], "metric")) { if (i + 1 >= argCount) { fprintf(stderr, "%s: Option 'metric' exptected parameter\n", kProgramName); exit(1); } metric = strtol(args[i + 1], NULL, 0); i++; } else if (!strcmp(args[i], "media")) { if (ioctl(socket, SIOCGIFMEDIA, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Unable to detect media type\n", kProgramName); exit(1); } if (i + 1 >= argCount) { fprintf(stderr, "%s: Option 'media' exptected parameter\n", kProgramName); exit(1); } if (!media_parse_subtype(args[i + 1], IFM_TYPE(request.ifr_media), &media)) { fprintf(stderr, "%s: Invalid parameter for option 'media': " "'%s'\n", kProgramName, args[i + 1]); exit(1); } i++; } else if (!strcmp(args[i], "up") || !strcmp(args[i], "-down")) { addFlags |= IFF_UP; } else if (!strcmp(args[i], "down") || !strcmp(args[i], "-up")) { removeFlags |= IFF_UP; } else if (!strcmp(args[i], "bcast")) { addFlags |= IFF_BROADCAST; } else if (!strcmp(args[i], "-bcast")) { removeFlags |= IFF_BROADCAST; } else if (!strcmp(args[i], "promisc")) { addFlags |= IFF_PROMISC; } else if (!strcmp(args[i], "-promisc")) { removeFlags |= IFF_PROMISC; } else if (!strcmp(args[i], "allmulti")) { addFlags |= IFF_ALLMULTI; } else if (!strcmp(args[i], "-allmulti")) { removeFlags |= IFF_ALLMULTI; } else if (!strcmp(args[i], "loopback")) { addFlags |= IFF_LOOPBACK; } else if (!strcmp(args[i], "auto-config")) { doAutoConfig = true; } else usage(1); i++; } if ((addFlags & removeFlags) != 0) { fprintf(stderr, "%s: Contradicting flags specified\n", kProgramName); exit(1); } if (doAutoConfig && (hasAddress || hasMask || hasBroadcast || hasPeer)) { fprintf(stderr, "%s: Contradicting changes specified\n", kProgramName); exit(1); } // set address/mask/broadcast/peer if (hasAddress) { memcpy(&request.ifr_addr, &address, address.sa_len); if (ioctl(socket, SIOCSIFADDR, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting address failed: %s\n", kProgramName, strerror(errno)); exit(1); } } if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Getting flags failed: %s\n", kProgramName, strerror(errno)); exit(1); } currentFlags = request.ifr_flags; if (hasMask) { memcpy(&request.ifr_mask, &mask, mask.sa_len); if (ioctl(socket, SIOCSIFNETMASK, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting subnet mask failed: %s\n", kProgramName, strerror(errno)); exit(1); } } if (hasBroadcast) { memcpy(&request.ifr_broadaddr, &broadcast, broadcast.sa_len); if (ioctl(socket, SIOCSIFBRDADDR, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting broadcast address failed: %s\n", kProgramName, strerror(errno)); exit(1); } } if (hasPeer) { memcpy(&request.ifr_dstaddr, &peer, peer.sa_len); if (ioctl(socket, SIOCSIFDSTADDR, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting peer address failed: %s\n", kProgramName, strerror(errno)); exit(1); } } // set flags if (hasAddress || hasMask || hasBroadcast || hasPeer) removeFlags = IFF_AUTO_CONFIGURED | IFF_CONFIGURING; if (addFlags || removeFlags) { request.ifr_flags = (currentFlags & ~removeFlags) | addFlags; if (ioctl(socket, SIOCSIFFLAGS, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting flags failed: %s\n", kProgramName, strerror(errno)); } } // set options if (mtu != -1) { request.ifr_mtu = mtu; if (ioctl(socket, SIOCSIFMTU, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting MTU failed: %s\n", kProgramName, strerror(errno)); } } if (metric != -1) { request.ifr_metric = metric; if (ioctl(socket, SIOCSIFMETRIC, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting metric failed: %s\n", kProgramName, strerror(errno)); } } if (media != -1) { request.ifr_media = media; if (ioctl(socket, SIOCSIFMEDIA, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting media failed: %s\n", kProgramName, strerror(errno)); } } // start auto configuration, if asked for if (doAutoConfig) { BMessage message(kMsgConfigureInterface); message.AddString("device", name); BMessage address; address.AddString("family", "inet"); address.AddBool("auto_config", true); message.AddMessage("address", &address); BMessenger networkServer(kNetServerSignature); if (networkServer.IsValid()) { BMessage reply; status_t status = networkServer.SendMessage(&message, &reply); if (status != B_OK) { fprintf(stderr, "%s: Sending auto-config message failed: %s\n", kProgramName, strerror(status)); } else if (reply.FindInt32("status", &status) == B_OK && status != B_OK) { fprintf(stderr, "%s: Auto-configuring failed: %s\n", kProgramName, strerror(status)); } } else { fprintf(stderr, "%s: The net_server needs to run for the auto " "configuration!\n", kProgramName); } } }
void list_interface(int socket, const char* name) { ifreq request; if (!prepare_request(request, name)) return; if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) < 0) { fprintf(stderr, "%s: Interface \"%s\" does not exist.\n", kProgramName, name); return; } printf("%s", name); size_t length = strlen(name); if (length < 8) putchar('\t'); else printf("\n\t"); // get link level interface for this interface int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0); if (linkSocket < 0) { printf("No link level: %s\n", strerror(errno)); } else { const char *type = "unknown"; char address[256]; strcpy(address, "none"); if (ioctl(socket, SIOCGIFPARAM, &request, sizeof(struct ifreq)) == 0) { prepare_request(request, request.ifr_parameter.device); if (ioctl(linkSocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) == 0) { sockaddr_dl &link = *(sockaddr_dl *)&request.ifr_addr; switch (link.sdl_type) { case IFT_ETHER: { type = "Ethernet"; if (link.sdl_alen > 0) { uint8 *mac = (uint8 *)LLADDR(&link); sprintf(address, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } else strcpy(address, "not available"); break; } case IFT_LOOP: type = "Local Loopback"; break; case IFT_MODEM: type = "Modem"; break; } } } printf("Hardware Type: %s, Address: %s\n", type, address); close(linkSocket); } if (ioctl(socket, SIOCGIFMEDIA, &request, sizeof(struct ifreq)) == 0 && (request.ifr_media & IFM_ACTIVE) != 0) { // dump media state in case we're linked const char* type = "unknown"; bool show = false; for (int32 i = 0; kMediaTypes[i].type >= 0; i++) { // loopback don't really have a media anyway if (IFM_TYPE(request.ifr_media) == 0/*IFT_LOOP*/) break; // only check for generic or correct subtypes if (kMediaTypes[i].type && kMediaTypes[i].type != IFM_TYPE(request.ifr_media)) continue; for (int32 j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) { if (kMediaTypes[i].subtypes[j].subtype == IFM_SUBTYPE(request.ifr_media)) { // found a match type = kMediaTypes[i].subtypes[j].pretty; show = true; break; } } } if (show) printf("\tMedia Type: %s\n", type); } uint32 flags = 0; if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0) flags = request.ifr_flags; for (int32 i = 0; kFamilies[i].family >= 0; i++) { int familySocket = ::socket(kFamilies[i].family, SOCK_DGRAM, 0); if (familySocket < 0) continue; if (ioctl(familySocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) == 0) { printf("\t%s addr: ", kFamilies[i].name); kFamilies[i].print_address(&request.ifr_addr); if ((flags & IFF_BROADCAST) != 0 && ioctl(familySocket, SIOCGIFBRDADDR, &request, sizeof(struct ifreq)) == 0 && request.ifr_broadaddr.sa_family == kFamilies[i].family) { printf(", Bcast: "); kFamilies[i].print_address(&request.ifr_broadaddr); } if (ioctl(familySocket, SIOCGIFNETMASK, &request, sizeof(struct ifreq)) == 0 && request.ifr_mask.sa_family == kFamilies[i].family) { printf(", Mask: "); kFamilies[i].print_address(&request.ifr_mask); } putchar('\n'); } close(familySocket); } // Print MTU, metric, flags printf("\tMTU: "); if (ioctl(socket, SIOCGIFMTU, &request, sizeof(struct ifreq)) == 0) printf("%d", request.ifr_mtu); else printf("-"); printf(", Metric: "); if (ioctl(socket, SIOCGIFMETRIC, &request, sizeof(struct ifreq)) == 0) printf("%d", request.ifr_metric); else printf("-"); if (flags != 0) { const struct { int value; const char *name; } kFlags[] = { {IFF_UP, "up"}, {IFF_NOARP, "noarp"}, {IFF_BROADCAST, "broadcast"}, {IFF_LOOPBACK, "loopback"}, {IFF_PROMISC, "promiscuous"}, {IFF_ALLMULTI, "allmulti"}, {IFF_AUTOUP, "autoup"}, {IFF_LINK, "link"}, {IFF_AUTO_CONFIGURED, "auto-configured"}, {IFF_CONFIGURING, "configuring"}, }; bool first = true; for (uint32 i = 0; i < sizeof(kFlags) / sizeof(kFlags[0]); i++) { if ((flags & kFlags[i].value) != 0) { if (first) { printf(","); first = false; } putchar(' '); printf(kFlags[i].name); } } } putchar('\n'); // Print statistics if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) == 0) { printf("\tReceive: %d packets, %d errors, %Ld bytes, %d mcasts, %d dropped\n", request.ifr_stats.receive.packets, request.ifr_stats.receive.errors, request.ifr_stats.receive.bytes, request.ifr_stats.receive.multicast_packets, request.ifr_stats.receive.dropped); printf("\tTransmit: %d packets, %d errors, %Ld bytes, %d mcasts, %d dropped\n", request.ifr_stats.send.packets, request.ifr_stats.send.errors, request.ifr_stats.send.bytes, request.ifr_stats.send.multicast_packets, request.ifr_stats.send.dropped); printf("\tCollisions: %d\n", request.ifr_stats.collisions); } putchar('\n'); }
static int monitor_mode(pcap_t *p, int set) { int sock; struct ifmediareq req; int *media_list; int i; int can_do; struct ifreq ifr; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't open socket: %s", pcap_strerror(errno)); return (PCAP_ERROR); } memset(&req, 0, sizeof req); (void)strlcpy(req.ifm_name, p->opt.source, sizeof req.ifm_name); /* * Find out how many media types we have. */ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { /* * Can't get the media types. */ switch (errno) { case ENXIO: /* * There's no such device. */ close(sock); return (PCAP_ERROR_NO_SUCH_DEVICE); case EINVAL: /* * Interface doesn't support SIOC{G,S}IFMEDIA. */ close(sock); return (PCAP_ERROR_RFMON_NOTSUP); default: snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA 1: %s", pcap_strerror(errno)); close(sock); return (PCAP_ERROR); } } if (req.ifm_count == 0) { /* * No media types. */ close(sock); return (PCAP_ERROR_RFMON_NOTSUP); } /* * Allocate a buffer to hold all the media types, and * get the media types. */ media_list = (int *) calloc(req.ifm_count, sizeof(int)); if (media_list == NULL) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); close(sock); return (PCAP_ERROR); } req.ifm_ulist = media_list; if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA: %s", pcap_strerror(errno)); free(media_list); close(sock); return (PCAP_ERROR); } /* * Look for an 802.11 "automatic" media type. * We assume that all 802.11 adapters have that media type, * and that it will carry the monitor mode supported flag. */ can_do = 0; for (i = 0; i < req.ifm_count; i++) { if (IFM_TYPE(media_list[i]) == IFM_IEEE80211 && IFM_SUBTYPE(media_list[i]) == IFM_AUTO) { /* OK, does it do monitor mode? */ if (media_list[i] & IFM_IEEE80211_MONITOR) { can_do = 1; break; } } } free(media_list); if (!can_do) { /* * This adapter doesn't support monitor mode. */ close(sock); return (PCAP_ERROR_RFMON_NOTSUP); } if (set) { /* * Don't just check whether we can enable monitor mode, * do so, if it's not already enabled. */ if ((req.ifm_current & IFM_IEEE80211_MONITOR) == 0) { /* * Monitor mode isn't currently on, so turn it on, * and remember that we should turn it off when the * pcap_t is closed. */ /* * If we haven't already done so, arrange to have * "pcap_close_all()" called when we exit. */ if (!pcap_do_addexit(p)) { /* * "atexit()" failed; don't put the interface * in monitor mode, just give up. */ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "atexit failed"); close(sock); return (PCAP_ERROR); } memset(&ifr, 0, sizeof(ifr)); (void)strlcpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name)); ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR; if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSIFMEDIA: %s", pcap_strerror(errno)); close(sock); return (PCAP_ERROR); } p->md.must_do_on_close |= MUST_CLEAR_RFMON; /* * Add this to the list of pcaps to close when we exit. */ pcap_add_to_pcaps_to_close(p); } } return (0); }
static void media_status(int s) { struct ifmediareq ifmr; int *media_list, i; (void) memset(&ifmr, 0, sizeof(ifmr)); (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { /* * Interface doesn't support SIOC{G,S}IFMEDIA. */ return; } if (ifmr.ifm_count == 0) { warnx("%s: no media types?", name); return; } media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); if (media_list == NULL) err(1, "malloc"); ifmr.ifm_ulist = media_list; if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) err(1, "SIOCGIFMEDIA"); printf("\tmedia: "); print_media_word(ifmr.ifm_current, 1); if (ifmr.ifm_active != ifmr.ifm_current) { putchar(' '); putchar('('); print_media_word(ifmr.ifm_active, 0); putchar(')'); } putchar('\n'); if (ifmr.ifm_status & IFM_AVALID) { printf("\tstatus: "); switch (IFM_TYPE(ifmr.ifm_active)) { case IFM_ETHER: case IFM_ATM: if (ifmr.ifm_status & IFM_ACTIVE) printf("active"); else printf("no carrier"); break; case IFM_FDDI: case IFM_TOKEN: if (ifmr.ifm_status & IFM_ACTIVE) printf("inserted"); else printf("no ring"); break; case IFM_IEEE80211: if (ifmr.ifm_status & IFM_ACTIVE) { /* NB: only sta mode associates */ if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA) printf("associated"); else printf("running"); } else printf("no carrier"); break; } putchar('\n'); } if (ifmr.ifm_count > 0 && supmedia) { printf("\tsupported media:\n"); for (i = 0; i < ifmr.ifm_count; i++) { printf("\t\t"); print_media_word_ifconfig(media_list[i]); putchar('\n'); } } free(media_list); }