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); }
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; }
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); }