diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2016-02-24 22:00:35 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2016-02-24 22:00:35 +0000 |
commit | 70209aca164f9d3fe2932e9fbf5be43b49b7aa65 (patch) | |
tree | df21c4220def6941814f79231543ef1c4857ae3a | |
parent | 6607cb5de8c7979567598d7caf52b4e515cfaff6 (diff) |
Notes
-rw-r--r-- | sys/net/bpf.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 661a1cfbd1fb..54dd1842e554 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2681,26 +2681,44 @@ bpf_ifdetach(void *arg __unused, struct ifnet *ifp) static int bpf_getdltlist(struct bpf_d *d, struct bpf_dltlist *bfl) { - int n, error; struct ifnet *ifp; struct bpf_if *bp; + u_int *lst; + int error, n, n1; BPF_LOCK_ASSERT(); ifp = d->bd_bif->bif_ifp; +again: + n1 = 0; + LIST_FOREACH(bp, &bpf_iflist, bif_next) { + if (bp->bif_ifp == ifp) + n1++; + } + if (bfl->bfl_list == NULL) { + bfl->bfl_len = n1; + return (0); + } + if (n1 > bfl->bfl_len) + return (ENOMEM); + BPF_UNLOCK(); + lst = malloc(n1 * sizeof(u_int), M_TEMP, M_WAITOK); n = 0; - error = 0; + BPF_LOCK(); LIST_FOREACH(bp, &bpf_iflist, bif_next) { if (bp->bif_ifp != ifp) continue; - if (bfl->bfl_list != NULL) { - if (n >= bfl->bfl_len) - return (ENOMEM); - error = copyout(&bp->bif_dlt, - bfl->bfl_list + n, sizeof(u_int)); + if (n > n1) { + free(lst, M_TEMP); + goto again; } + lst[n] = bp->bif_dlt; n++; } + BPF_UNLOCK(); + error = copyout(lst, bfl->bfl_list, sizeof(u_int) * n); + free(lst, M_TEMP); + BPF_LOCK(); bfl->bfl_len = n; return (error); } |