static int virtif_create(struct ifnet *ifp) { uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0x0a, 0x00, 0x0b, 0x0e, 0x01 }; char enaddrstr[3*ETHER_ADDR_LEN]; struct virtif_sc *sc = ifp->if_softc; int error; if (sc->sc_viu) panic("%s: already created", ifp->if_xname); enaddr[2] = cprng_fast32() & 0xff; enaddr[5] = sc->sc_num & 0xff; if ((error = VIFHYPER_CREATE(sc->sc_linkstr, sc, enaddr, &sc->sc_viu)) != 0) { printf("VIFHYPER_CREATE failed: %d\n", error); return error; } ether_ifattach(ifp, enaddr); ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr); aprint_normal_ifnet(ifp, "Ethernet address %s\n", enaddrstr); IFQ_SET_READY(&ifp->if_snd); return 0; }
static int allocif(int unit, struct shmif_sc **scp) { uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0xa0, 0x00, 0x00, 0x00, 0x00 }; struct shmif_sc *sc; struct ifnet *ifp; uint32_t randnum; int error; randnum = cprng_fast32(); memcpy(&enaddr[2], &randnum, sizeof(randnum)); sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); sc->sc_memfd = -1; sc->sc_unit = unit; sc->sc_uuid = cprng_fast64(); ifp = &sc->sc_ec.ec_if; snprintf(ifp->if_xname, sizeof(ifp->if_xname), "shmif%d", unit); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_init = shmif_init; ifp->if_ioctl = shmif_ioctl; ifp->if_start = shmif_start; ifp->if_stop = shmif_stop; ifp->if_mtu = ETHERMTU; ifp->if_dlt = DLT_EN10MB; mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); cv_init(&sc->sc_cv, "shmifcv"); if_initialize(ifp); ether_ifattach(ifp, enaddr); if_register(ifp); aprint_verbose("shmif%d: Ethernet address %s\n", unit, ether_sprintf(enaddr)); if (scp) *scp = sc; error = 0; if (rump_threads) { error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, shmif_rcv, ifp, &sc->sc_rcvl, "shmif"); } else { printf("WARNING: threads not enabled, shmif NOT working\n"); } if (error) { shmif_unclone(ifp); } return error; }
/* * Since there is no state kept on the ports tried, we might actually * give up before exhausting the free ports. */ static int algo_random_pick(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr, kauth_cred_t cred) { uint16_t count, num_ephemeral; uint16_t mymin, mymax, lastport; uint16_t *next_ephemeral; int error; DPRINTF("%s called\n", __func__); error = pcb_getports(inp_hdr, &lastport, &mymin, &mymax, &next_ephemeral, algo); if (error) return error; num_ephemeral = mymax - mymin + 1; DPRINTF("num_ephemeral: %u\n", num_ephemeral); *next_ephemeral = mymin + (cprng_fast32() % num_ephemeral); DPRINTF("next_ephemeral initially: %u\n", *next_ephemeral); count = num_ephemeral; do { if (check_suitable_port(*next_ephemeral, inp_hdr, cred)) { *port = *next_ephemeral; DPRINTF("%s returning port %d\n", __func__, *port); return 0; } *next_ephemeral = mymin + (cprng_fast32() % num_ephemeral); count--; DPRINTF("next_ephemeral: %u count: %u\n", *next_ephemeral, count); } while (count > 0); DPRINTF("%s returning EINVAL\n", __func__); return EINVAL; }
static int algo_randinc(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr, kauth_cred_t cred) { static const uint16_t N = 500; /* Determines the trade-off */ uint16_t count, num_ephemeral; uint16_t mymin, mymax, lastport; uint16_t *next_ephemeral; uint16_t myport; int error; DPRINTF("%s called\n", __func__); error = pcb_getports(inp_hdr, &lastport, &mymin, &mymax, &next_ephemeral, algo); if (error) return error; if (*next_ephemeral == 0) *next_ephemeral = cprng_fast32() & 0xffff; /* Ephemeral port selection function */ num_ephemeral = mymax - mymin + 1; count = num_ephemeral; do { *next_ephemeral = *next_ephemeral + (cprng_fast32() % N) + 1; myport = mymin + (*next_ephemeral % num_ephemeral); if (check_suitable_port(myport, inp_hdr, cred)) { *port = myport; DPRINTF("%s returning port %d\n", __func__, *port); return 0; } count--; } while (count > 0); return EINVAL; }
static int algo_doublehash(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr, kauth_cred_t cred) { uint16_t count, num_ephemeral; uint16_t mymin, mymax, lastport; uint16_t *next_ephemeral; uint16_t offset, myport; static uint16_t dhtable[8]; size_t idx; int error; DPRINTF("%s called\n", __func__); error = pcb_getports(inp_hdr, &lastport, &mymin, &mymax, &next_ephemeral, algo); if (error) return error; if (!iscompletetuple(inp_hdr)) { *port = 0; return 0; } /* first time initialization */ if (dhtable[0] == 0) for (size_t i = 0; i < __arraycount(dhtable); i++) dhtable[i] = cprng_fast32() & 0xffff; /* Ephemeral port selection function */ num_ephemeral = mymax - mymin + 1; offset = Fhash(inp_hdr); idx = Fhash(inp_hdr) % __arraycount(dhtable); /* G */ count = num_ephemeral; do { myport = mymin + (offset + dhtable[idx]) % num_ephemeral; dhtable[idx]++; if (check_suitable_port(myport, inp_hdr, cred)) { *port = myport; DPRINTF("%s returning port %d\n", __func__, *port); return 0; } count--; } while (count > 0); DPRINTF("%s returning EINVAL\n", __func__); return EINVAL; }
STATIC int check_loss(test_pars_t *tp, int rxtx) { return (tp->lose_random[rxtx]) ? (cprng_fast32() % tp->lose_random[rxtx]) : 0; }