示例#1
0
文件: if_tap.c 项目: ryo/netbsd-src
/*
 * The helper functions make Andrew Brown's interface really
 * shine.  It makes possible to create value on the fly whether
 * the sysctl value is read or written.
 *
 * As shown as an example in the man page, the first step is to
 * create a copy of the node to have sysctl_lookup work on it.
 *
 * Here, we have more work to do than just a copy, since we have
 * to create the string.  The first step is to collect the actual
 * value of the node, which is a convenient pointer to the softc
 * of the interface.  From there we create the string and use it
 * as the value, but only for the *copy* of the node.
 *
 * Then we let sysctl_lookup do the magic, which consists in
 * setting oldp and newp as required by the operation.  When the
 * value is read, that means that the string will be copied to
 * the user, and when it is written, the new value will be copied
 * over in the addr array.
 *
 * If newp is NULL, the user was reading the value, so we don't
 * have anything else to do.  If a new value was written, we
 * have to check it.
 *
 * If it is incorrect, we can return an error and leave 'node' as
 * it is:  since it is a copy of the actual node, the change will
 * be forgotten.
 *
 * Upon a correct input, we commit the change to the ifnet
 * structure of our interface.
 */
static int
tap_sysctl_handler(SYSCTLFN_ARGS)
{
	struct sysctlnode node;
	struct tap_softc *sc;
	struct ifnet *ifp;
	int error;
	size_t len;
	char addr[3 * ETHER_ADDR_LEN];
	uint8_t enaddr[ETHER_ADDR_LEN];

	node = *rnode;
	sc = node.sysctl_data;
	ifp = &sc->sc_ec.ec_if;
	(void)ether_snprintf(addr, sizeof(addr), CLLADDR(ifp->if_sadl));
	node.sysctl_data = addr;
	error = sysctl_lookup(SYSCTLFN_CALL(&node));
	if (error || newp == NULL)
		return (error);

	len = strlen(addr);
	if (len < 11 || len > 17)
		return (EINVAL);

	/* Commit change */
	if (ether_aton_r(enaddr, sizeof(enaddr), addr) != 0)
		return (EINVAL);
	if_set_sadl(ifp, enaddr, ETHER_ADDR_LEN, false);
	return (error);
}
示例#2
0
void
eco_ifattach(struct ifnet *ifp, const uint8_t *lla)
{
	struct ecocom *ec = (void *)ifp;

	ifp->if_type = IFT_ECONET;
	ifp->if_addrlen = ECO_ADDR_LEN;
	ifp->if_hdrlen = ECO_HDR_LEN;
	ifp->if_dlt = DLT_ECONET;
	ifp->if_mtu = ECO_MTU;

	ifp->if_output	 = eco_output;
	ifp->if_input	 = eco_input;
	ifp->if_start	 = eco_start;
	ifp->if_ioctl	 = eco_ioctl;

/*	ifp->if_baudrate...; */
	if_set_sadl(ifp, lla, ECO_ADDR_LEN, FALSE);

	ifp->if_broadcastaddr = eco_broadcastaddr;

	LIST_INIT(&ec->ec_retries);

	bpf_attach(ifp, ifp->if_dlt, ECO_HDR_LEN);
}
示例#3
0
文件: if_tap.c 项目: ryo/netbsd-src
/*
 * Helper function to set Ethernet address.  This has been replaced by
 * the generic SIOCALIFADDR ioctl on a PF_LINK socket.
 */
static int
tap_lifaddr(struct ifnet *ifp, u_long cmd, struct ifaliasreq *ifra)
{
	const struct sockaddr *sa = &ifra->ifra_addr;

	if (sa->sa_family != AF_LINK)
		return (EINVAL);

	if_set_sadl(ifp, sa->sa_data, ETHER_ADDR_LEN, false);

	return (0);
}