int
wanpipe_generic_register(sdla_t *card, struct ifnet *ifp, char *ifname)
{
	wanpipe_common_t*	common = WAN_IFP_TO_COMMON(ifp);

	if (ifname == NULL || strlen(ifname) > IFNAMSIZ)
		return (EINVAL);
	else
		bcopy(ifname, ifp->if_xname, strlen(ifname));

	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	ifp->if_mtu = PP_MTU;
	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
	common->protocol = IF_PROTO_CISCO;

	((struct sppp *)ifp)->pp_flags |= PP_CISCO;
	((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
	((struct sppp *)ifp)->pp_framebytes = 3;

	ifp->if_ioctl = wanpipe_generic_ioctl;	/* Will set from new_if() */
	ifp->if_start = wanpipe_generic_start;
	ifp->if_watchdog = wanpipe_generic_watchdog;

	if_attach(ifp);
	if_alloc_sadl(ifp);
	sppp_attach(ifp);

#if NBPFILTER > 0
	bpfattach(&ifp->if_bpf, ifp, DLT_PPP, PPP_HEADER_LEN);
#endif /* NBPFILTER > 0 */

	return (0);
}
Example #2
0
static int
wan_ioctl(struct ifnet *ifp, int cmd, struct ifreq *ifr)
{
	sdla_t			*card;
	wanpipe_common_t	*common = WAN_IFP_TO_COMMON(ifp);
	int			err;

	SAN_ASSERT(common == NULL);
	SAN_ASSERT(common->card == NULL);

	if ((err = suser(curproc, 0)) != 0)
		return err;

	switch (cmd) {
	case SIOC_WANPIPE_HWPROBE:
		err = wan_ioctl_hwprobe(ifp, ifr->ifr_data);
		break;

	case SIOC_WANPIPE_DUMP:
		err = wan_ioctl_dump(card, ifr->ifr_data);
		break;

	default:
		err = ENOTTY;
		break;
	}
	return err;
}
Example #3
0
static int
wan_ioctl_hwprobe(struct ifnet *ifp, void *u_def)
{
	sdla_t			*card = NULL;
	wanpipe_common_t	*common = WAN_IFP_TO_COMMON(ifp);
	wanlite_def_t	 	def;
	unsigned char		*str;
	int			err;

	SAN_ASSERT(common == NULL);
	SAN_ASSERT(common->card == NULL);
	card = common->card;
	bzero(&def, sizeof(wanlite_def_t));
	/* Get protocol type */
	def.proto = common->protocol;

	/* Get hardware configuration */
	err = sdla_get_hwprobe(card->hw, (void**)&str);
	if (err)
		return EINVAL;

	strlcpy(def.hwprobe, str, sizeof(def.hwprobe));
	/* Get interface configuration */
	if (IS_TE1(&card->fe_te.te_cfg)) {
		if (IS_T1(&card->fe_te.te_cfg))
			def.iface = IF_IFACE_T1;
		else
			def.iface = IF_IFACE_E1;

		bcopy(&card->fe_te.te_cfg, &def.te_cfg, sizeof(sdla_te_cfg_t));
	}

	err = copyout(&def, u_def, sizeof(def));
	if (err) {
		log(LOG_INFO, "%s: Failed to copy to user space (%d)\n",
		    card->devname, __LINE__);
		return ENOMEM;
	}
	return 0;
}
static int
wanpipe_generic_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
	struct proc		*p = curproc;
	struct ifreq		*ifr = (struct ifreq*)data;
	sdla_t			*card;
	wanpipe_common_t*	common = WAN_IFP_TO_COMMON(ifp);
	struct if_settings	ifsettings;
	unsigned long		ts_map;
	int			err = 0, s;

	if ((card = wanpipe_generic_getcard(ifp)) == NULL)
		return (EINVAL);

	s = splnet();

	switch (cmd) {
	case SIOCSIFADDR:
		// XXX because sppp does an implicit setflags
		log(LOG_INFO, "%s: Bringing interface up.\n",
		    ifp->if_xname);
		if (card->iface_up)
			card->iface_up(ifp);
		wanpipe_generic_start(ifp);
		err = 1;
		break;

	case SIOCSIFMEDIA:
		/* You can't set new media type while card is running */
		if (card->state != WAN_DISCONNECTED) {
			log(LOG_INFO, "%s: Unable to change media type!\n",
			    ifp->if_xname);
			err = EINVAL;
		} else
			err = ifmedia_ioctl(ifp, ifr, &common->ifm, cmd);
		goto ioctl_out;

	case SIOCGIFMEDIA:
		err = ifmedia_ioctl(ifp, ifr, &common->ifm, cmd);
		goto ioctl_out;

	case SIOCSIFTIMESLOT:
		if ((err = suser(p, p->p_acflag)) != 0)
			goto ioctl_out;
		if (card->state != WAN_DISCONNECTED) {
			log(LOG_INFO, "%s: Unable to change timeslot map!\n",
			    ifp->if_xname);
			err = EINVAL;
			goto ioctl_out;
		}

		err = copyin(ifr->ifr_data, &ts_map, sizeof(ts_map));
		if (err == 0)
			sdla_te_settimeslot(card, ts_map);

		goto ioctl_out;

	case SIOCGIFTIMESLOT:
		ts_map = sdla_te_gettimeslot(card);
		err = copyout(ifr->ifr_data, &ts_map, sizeof(ts_map));
		goto ioctl_out;

	case SIOCSIFFLAGS:
	    	/*
     		** If the interface is marked up - enable communications. 
	     	** If down - disable communications.  IFF_UP is taken 
		** care of before entering this function.
	     	*/
		err = 1;
		if ((ifp->if_flags & IFF_UP) == 0) {
			if ((ifp->if_flags & IFF_RUNNING) == 0)
				break;
			/* bring it down */
			log(LOG_INFO, "%s: Bringing interface down.\n",
			    ifp->if_xname);
			if (card->iface_down)
				card->iface_down(ifp);
		} else { /* bring it up */ 
			if (ifp->if_flags & IFF_RUNNING)
				break;
			log(LOG_INFO, "%s: Bringing interface up.\n",
			    ifp->if_xname);
			if (card->iface_up)
				card->iface_up(ifp);
			wanpipe_generic_start(ifp);
		}
		break;

	case SIOC_WANPIPE_DEVICE:
		err = copyin(ifr->ifr_data, &ifsettings,
		    sizeof(struct if_settings));

		if (err) {
			log(LOG_INFO, "%s: Failed to copy from user space!\n",
						card->devname);
			goto ioctl_out;
		}

		switch (ifsettings.type) {
		case IF_GET_PROTO:
			ifsettings.type = common->protocol;
			err = copyout(&ifsettings, ifr->ifr_data,
			    sizeof(struct if_settings));
			if (err)
				log(LOG_INFO,
				    "%s: Failed to copy to uspace!\n",
				    card->devname);
			break;

		case IF_PROTO_CISCO:
		case IF_PROTO_PPP:
			if ((err = suser(p, p->p_acflag)) != 0)
				goto ioctl_out;
			err = wp_lite_set_proto(ifp, (struct ifreq*)data);
			break;

		case IF_IFACE_T1:
		case IF_IFACE_E1:
			if ((err = suser(p, p->p_acflag)) != 0)
				goto ioctl_out;
			err = wp_lite_set_te1_cfg(ifp, (struct ifreq*)data);
			break;

		default:
			if (card->iface_ioctl)
				err = card->iface_ioctl(ifp, cmd,
				    (struct ifreq*)data);
			break;
		}
		goto ioctl_out;

	default:
		if (card->iface_ioctl) {
			/* Argument seqeunce is change for Linux order */
			err = card->iface_ioctl(ifp, cmd, (struct ifreq*)data);
		}
		break;
	}

	if (err)
		err = sppp_ioctl(ifp, cmd, data);

ioctl_out:
	splx(s);
	return (err);
}