Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
Arquivo: qe.c Projeto: ryo/netbsd-src
/*
 * 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);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
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 : "");
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
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)");
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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>");
}
Exemplo n.º 13
0
/*********************************************************************
 *
 *  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);
}
Exemplo n.º 14
0
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);
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
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);
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;
                    }
            }
        }
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
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);
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
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)
{
	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;
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
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)");
}
Exemplo n.º 27
0
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);
		}
	}
}
Exemplo n.º 28
0
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');
}
Exemplo n.º 29
0
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);
}
Exemplo n.º 30
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);
}