* Handle `netstat -B' stats request */
| 2935 | * Handle `netstat -B' stats request |
| 2936 | */ |
| 2937 | static int |
| 2938 | bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) |
| 2939 | { |
| 2940 | static const struct xbpf_d zerostats; |
| 2941 | struct xbpf_d *xbdbuf, *xbd, tempstats; |
| 2942 | int index, error; |
| 2943 | struct bpf_if *bp; |
| 2944 | struct bpf_d *bd; |
| 2945 | |
| 2946 | /* |
| 2947 | * XXX This is not technically correct. It is possible for non |
| 2948 | * privileged users to open bpf devices. It would make sense |
| 2949 | * if the users who opened the devices were able to retrieve |
| 2950 | * the statistics for them, too. |
| 2951 | */ |
| 2952 | error = priv_check(req->td, PRIV_NET_BPF); |
| 2953 | if (error) |
| 2954 | return (error); |
| 2955 | /* |
| 2956 | * Check to see if the user is requesting that the counters be |
| 2957 | * zeroed out. Explicitly check that the supplied data is zeroed, |
| 2958 | * as we aren't allowing the user to set the counters currently. |
| 2959 | */ |
| 2960 | if (req->newptr != NULL) { |
| 2961 | if (req->newlen != sizeof(tempstats)) |
| 2962 | return (EINVAL); |
| 2963 | memset(&tempstats, 0, sizeof(tempstats)); |
| 2964 | error = SYSCTL_IN(req, &tempstats, sizeof(tempstats)); |
| 2965 | if (error) |
| 2966 | return (error); |
| 2967 | if (bcmp(&tempstats, &zerostats, sizeof(tempstats)) != 0) |
| 2968 | return (EINVAL); |
| 2969 | bpf_zero_counters(); |
| 2970 | return (0); |
| 2971 | } |
| 2972 | if (req->oldptr == NULL) |
| 2973 | return (SYSCTL_OUT(req, 0, bpf_bpfd_cnt * sizeof(*xbd))); |
| 2974 | if (bpf_bpfd_cnt == 0) |
| 2975 | return (SYSCTL_OUT(req, 0, 0)); |
| 2976 | xbdbuf = malloc(req->oldlen, M_BPF, M_WAITOK); |
| 2977 | BPF_LOCK(); |
| 2978 | if (req->oldlen < (bpf_bpfd_cnt * sizeof(*xbd))) { |
| 2979 | BPF_UNLOCK(); |
| 2980 | free(xbdbuf, M_BPF); |
| 2981 | return (ENOMEM); |
| 2982 | } |
| 2983 | index = 0; |
| 2984 | CK_LIST_FOREACH(bp, &bpf_iflist, bif_next) { |
| 2985 | /* Send writers-only first */ |
| 2986 | CK_LIST_FOREACH(bd, &bp->bif_wlist, bd_next) { |
| 2987 | xbd = &xbdbuf[index++]; |
| 2988 | bpfstats_fill_xbpf(xbd, bd); |
| 2989 | } |
| 2990 | CK_LIST_FOREACH(bd, &bp->bif_dlist, bd_next) { |
| 2991 | xbd = &xbdbuf[index++]; |
| 2992 | bpfstats_fill_xbpf(xbd, bd); |
| 2993 | } |
| 2994 | } |
nothing calls this directly
no test coverage detected