/* * Handle MRT setsockopt commands to modify the multicast routing tables. */ int ip6_mrouter_set(struct socket *so, struct sockopt *sopt) { int error, optval; struct mif6ctl mifc; struct mf6cctl mfcc; mifi_t mifi; if (sopt->sopt_name != MRT6_INIT && so != ip6_mrouter) return (EACCES); error = 0; switch (sopt->sopt_name) { #ifdef MRT6_OINIT case MRT6_OINIT: #endif case MRT6_INIT: error = sockopt_getint(sopt, &optval); if (error) break; return (ip6_mrouter_init(so, optval, sopt->sopt_name)); case MRT6_DONE: return (ip6_mrouter_done()); case MRT6_ADD_MIF: error = sockopt_get(sopt, &mifc, sizeof(mifc)); if (error) break; return (add_m6if(&mifc)); case MRT6_DEL_MIF: error = sockopt_get(sopt, &mifi, sizeof(mifi)); if (error) break; return (del_m6if(&mifi)); case MRT6_ADD_MFC: error = sockopt_get(sopt, &mfcc, sizeof(mfcc)); if (error) break; return (add_m6fc(&mfcc)); case MRT6_DEL_MFC: error = sockopt_get(sopt, &mfcc, sizeof(mfcc)); if (error) break; return (del_m6fc(&mfcc)); case MRT6_PIM: error = sockopt_getint(sopt, &optval); if (error) break; return (set_pim6(&optval)); default: error = EOPNOTSUPP; } return (error); }
static int btsco_open(void *hdl, int flags) { struct sockaddr_bt sa; struct btsco_softc *sc = hdl; struct sockopt sopt; int err, timo; DPRINTF("%s flags 0x%x\n", sc->sc_name, flags); /* flags FREAD & FWRITE? */ if (sc->sc_sco != NULL || sc->sc_sco_l != NULL) return EIO; KASSERT(mutex_owned(bt_lock)); memset(&sa, 0, sizeof(sa)); sa.bt_len = sizeof(sa); sa.bt_family = AF_BLUETOOTH; bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); if (sc->sc_flags & BTSCO_LISTEN) { err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc); if (err) goto done; err = sco_bind_pcb(sc->sc_sco_l, &sa); if (err) { sco_detach_pcb(&sc->sc_sco_l); goto done; } err = sco_listen_pcb(sc->sc_sco_l); if (err) { sco_detach_pcb(&sc->sc_sco_l); goto done; } timo = 0; /* no timeout */ } else { err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc); if (err) goto done; err = sco_bind_pcb(sc->sc_sco, &sa); if (err) { sco_detach_pcb(&sc->sc_sco); goto done; } bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); err = sco_connect_pcb(sc->sc_sco, &sa); if (err) { sco_detach_pcb(&sc->sc_sco); goto done; } timo = BTSCO_TIMEOUT; } sc->sc_state = BTSCO_WAIT_CONNECT; while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT) err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo); switch (sc->sc_state) { case BTSCO_CLOSED: /* disconnected */ err = sc->sc_err; /* fall through to */ case BTSCO_WAIT_CONNECT: /* error */ if (sc->sc_sco != NULL) sco_detach_pcb(&sc->sc_sco); if (sc->sc_sco_l != NULL) sco_detach_pcb(&sc->sc_sco_l); break; case BTSCO_OPEN: /* hurrah */ sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0); (void)sco_getopt(sc->sc_sco, &sopt); (void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu)); sockopt_destroy(&sopt); break; default: UNKNOWN(sc->sc_state); break; } done: DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n", err, sc->sc_state, sc->sc_mtu); return err; }