+
+
+/*
+ * Get a list of available data link type of the interface.
+ */
+static int
+bpf_getdltlist(
+ struct bpf_d *d,
+ struct bpf_dltlist *bfl)
+{
+ u_int n;
+ int error;
+ struct ifnet *ifp;
+ struct bpf_if *bp;
+ user_addr_t dlist;
+
+ if (IS_64BIT_PROCESS(current_proc())) {
+ dlist = CAST_USER_ADDR_T(bfl->bfl_u.bflu_pad);
+ }
+ else {
+ dlist = CAST_USER_ADDR_T(bfl->bfl_u.bflu_list);
+ }
+
+ ifp = d->bd_bif->bif_ifp;
+ n = 0;
+ error = 0;
+ for (bp = bpf_iflist; bp; bp = bp->bif_next) {
+ if (bp->bif_ifp != ifp)
+ continue;
+ if (dlist != 0) {
+ if (n >= bfl->bfl_len) {
+ return (ENOMEM);
+ }
+ error = copyout(&bp->bif_dlt, dlist, sizeof(bp->bif_dlt));
+ dlist += sizeof(bp->bif_dlt);
+ }
+ n++;
+ }
+ bfl->bfl_len = n;
+ return (error);
+}
+
+/*
+ * Set the data link type of a BPF instance.
+ */
+static int
+bpf_setdlt(struct bpf_d *d, uint32_t dlt)
+
+
+{
+ int error, opromisc;
+ struct ifnet *ifp;
+ struct bpf_if *bp;
+
+ if (d->bd_bif->bif_dlt == dlt)
+ return (0);
+ ifp = d->bd_bif->bif_ifp;
+ for (bp = bpf_iflist; bp; bp = bp->bif_next) {
+ if (bp->bif_ifp == ifp && bp->bif_dlt == dlt)
+ break;
+ }
+ if (bp != NULL) {
+ opromisc = d->bd_promisc;
+ bpf_detachd(d);
+ error = bpf_attachd(d, bp);
+ if (error) {
+ printf("bpf_setdlt: bpf_attachd %s%d failed (%d)\n",
+ ifnet_name(bp->bif_ifp), ifnet_unit(bp->bif_ifp), error);
+ return error;
+ }
+ reset_d(d);
+ if (opromisc) {
+ lck_mtx_unlock(bpf_mlock);
+ error = ifnet_set_promiscuous(bp->bif_ifp, 1);
+ lck_mtx_lock(bpf_mlock);
+ if (error)
+ printf("bpf_setdlt: ifpromisc %s%d failed (%d)\n",
+ ifnet_name(bp->bif_ifp), ifnet_unit(bp->bif_ifp), error);
+ else
+ d->bd_promisc = 1;
+ }
+ }
+ return (bp == NULL ? EINVAL : 0);
+}
+