Date: Fri, 24 Jul 2009 03:51:02 GMT From: Gabor Pali <pgj@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 166486 for review Message-ID: <200907240351.n6O3p2JQ034946@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166486 Change 166486 by pgj@petymeg-current on 2009/07/24 03:50:21 Add support for retrieving statistics on bpf(4) peers to libnetstat(3): - It both features monitoring via sysctl(8) [net.bpf.sstats], and information extraction from kernel memory images via kvm(3). - New abstraction: bpf_type (BPF descriptor). Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#12 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#32 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_bpf.c#1 add .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#30 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#36 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#12 (text+ko) ==== @@ -3,7 +3,8 @@ .include <bsd.own.mk> LIB= netstat -SRCS= netstat_socket.c netstat_mbuf.c netstat_if.c netstat_util.c +SRCS= netstat_socket.c netstat_mbuf.c netstat_if.c netstat_bpf.c \ + netstat_util.c INCS= netstat.h ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#32 (text+ko) ==== @@ -41,6 +41,8 @@ #define IFTYPE_MAXNAME 32 #define IFTYPE_MAXADDRCNT 8 +#define BPFTYPE_MAXNAME IFNAMSIZ + #define NETSTAT_ERROR_UNDEFINED 0 #define NETSTAT_ERROR_NOMEMORY 1 #define NETSTAT_ERROR_VERSION 2 @@ -60,9 +62,21 @@ #define NETSTAT_INTERFACE_KVM 0x01 #define NETSTAT_INTERFACE_ALL 0x02 +/* netstat_bpf(): */ +#define NETSTAT_BPF_KVM 0x01 + /* Testing flags for interface_type: */ #define NETSTAT_IF_UP 0x01 /* interface is up */ +/* Flags for bpf_type: */ +#define NETSTAT_BPF_PROMISC 0x01 /* if listening prmoiscuously */ +#define NETSTAT_BPF_IMMEDIATE 0x02 /* return on packet arrival */ +#define NETSTAT_BPF_HDRCMPLT 0x04 /* fill in src lladdr automatically */ +#define NETSTAT_BPF_FEEDBACK 0x08 /* feed back sent packets */ +#define NETSTAT_BPF_ASYNC 0x10 /* packet reception should generate signal */ +#define NETSTAT_BPF_LOCKED 0x20 /* descriptor is locked */ + + /* Enum for TCP states: */ enum tcp_state { tcps_Closed, @@ -88,6 +102,14 @@ layer_MAX, }; +enum bpf_dir { + bpfdir_Invalid, + bpfdir_In, + bpfdir_Out, + bpfdir_InOut, + bpfdir_MAX, +}; + struct socket_type; struct sockaddr_type; struct sockbuf_type; @@ -104,6 +126,9 @@ struct interface_type_list; struct interface_type_iterator; +struct bpf_type; +struct bpf_type_list; +struct bpf_type_iterator; __BEGIN_DECLS const char *netstat_strerror(int); @@ -244,6 +269,7 @@ u_int64_t netstat_ft_get_mcasts(const struct face_type *); u_int64_t netstat_ft_get_errors(const struct face_type *); +/* Interface addresses: */ int netstat_iat_get_family(const struct intfaddr_type *); const char *netstat_iat_get_address(const struct intfaddr_type *, int numeric); const char *netstat_iat_get_network(const struct intfaddr_type *, int numeric); @@ -254,6 +280,30 @@ u_int64_t netstat_iat_get_obytes(const struct intfaddr_type *); u_int32_t netstat_iat_get_refcount(const struct intfaddr_type *); -/* Interface addresses: */ +/* BPF peers: */ +struct bpf_type_list *netstat_bptl_alloc(void); +void netstat_bptl_free(struct bpf_type_list *); +int netstat_bptl_geterror(const struct bpf_type_list *); +int netstat_bptl_length(const struct bpf_type_list *); + +int netstat_bpti_alloc(struct bpf_type_list *list, + struct bpf_type_iterator **iterator); +const struct bpf_type *netstat_bpti_first(struct bpf_type_iterator *); +const struct bpf_type *netstat_bpti_next(struct bpf_type_iterator *); +void netstat_bpti_free(struct bpf_type_iterator *); +void netstat_bpt_free(struct bpf_type *); + +int netstat_bpf(const char *name, struct bpf_type_list *list, int flags, + void *kvm_handle); +int netstat_bpt_get_flags(const struct bpf_type *); +enum bpf_dir netstat_bpt_get_direction(const struct bpf_type *); +u_int32_t netstat_bpt_get_pid(const struct bpf_type *); +const char *netstat_bpt_get_ifname(const struct bpf_type *); +u_int64_t netstat_bpt_get_recv(const struct bpf_type *); +u_int64_t netstat_bpt_get_drop(const struct bpf_type *); +u_int64_t netstat_bpt_get_match(const struct bpf_type *); +u_int64_t netstat_bpt_get_slen(const struct bpf_type *); +u_int64_t netstat_bpt_get_hlen(const struct bpf_type *); +const char *netstat_bpt_get_pidname(const struct bpf_type *); #endif /* !_NETSTAT_H_ */ ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#30 (text+ko) ==== @@ -36,6 +36,7 @@ #include <sys/un.h> #include <sys/unpcb.h> #include <kvm.h> +#include <net/if.h> #include <netinet/in.h> #include <netinet/in_pcb.h> #include <netinet/tcp_var.h> @@ -240,6 +241,35 @@ struct interface_type *iti_next; }; +/* Berkeley Packet Filter (descriptor). */ +struct bpf_type { + int bpt_flags; + u_int32_t bpt_slen; /* current length of store buffer */ + u_int32_t bpt_hlen; /* current length of hold buffer */ + u_int64_t bpt_recv; /* number of packets received */ + u_int64_t bpt_drop; /* number of packets dropped */ + u_int64_t bpt_match; /* number of packets which matched + filter */ + u_int32_t bpt_pid; /* PID which created descriptor */ + char *bpt_pidname; + enum bpf_dir bpt_direction; /* select packet direction */ + char bpt_ifname[BPFTYPE_MAXNAME]; /* interface name */ + + LIST_ENTRY(bpf_type) bpt_list; +}; + +struct bpf_type_list { + LIST_HEAD(, bpf_type) bptl_list; + int bptl_length; + int bptl_error; +}; + +struct bpf_type_iterator { + struct bpf_type_list *bpti_list; + struct bpf_type *bpti_first; + struct bpf_type *bpti_next; +}; + int kread_data(kvm_t *kvm, u_long kvm_pointer, void *address, size_t size); int kread_string(kvm_t *kvm, u_long kvm_pointer, char *buffer, int buflen); @@ -261,6 +291,9 @@ int type, int physical, const char *name); struct intfaddr_type *_netstat_iat_allocate(int family, int type); +void _netstat_bptl_empty(struct bpf_type_list *list); +struct bpf_type *_netstat_bpt_allocate(struct bpf_type_list *list, + const char *ifname); /* XXX: merge these into a common address resolution routine. */ const char *routename(in_addr_t in, int numeric); ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#36 (text+ko) ==== @@ -1026,6 +1026,181 @@ return (iatp->iat_refcount); } +void +_netstat_bptl_empty(struct bpf_type_list *list) +{ + struct bpf_type *btp; + + while ((btp = LIST_FIRST(&list->bptl_list))) { + LIST_REMOVE(btp, bpt_list); + netstat_bpt_free(btp); + } + + list->bptl_length = 0; +} + +struct bpf_type * +_netstat_bpt_allocate(struct bpf_type_list *list, const char *ifname) +{ + struct bpf_type *btp; + + btp = malloc(sizeof(*btp)); + if (btp == NULL) + return (NULL); + + bzero(btp, sizeof(*btp)); + strlcpy(btp->bpt_ifname, ifname, BPFTYPE_MAXNAME); + LIST_INSERT_HEAD(&list->bptl_list, btp, bpt_list); + list->bptl_length += 1; + return (btp); +} + +struct bpf_type_list * +netstat_bptl_alloc(void) +{ + struct bpf_type_list *btlp; + + btlp = malloc(sizeof(*btlp)); + if (btlp == NULL) + return (NULL); + + LIST_INIT(&btlp->bptl_list); + btlp->bptl_error = NETSTAT_ERROR_UNDEFINED; + btlp->bptl_length = 0; + return (btlp); +} + +void +netstat_bptl_free(struct bpf_type_list *list) +{ + _netstat_bptl_empty(list); + free(list); +} + +int +netstat_bptl_geterror(const struct bpf_type_list *list) +{ + return (list->bptl_error); +} + +int +netstat_bptl_length(const struct bpf_type_list *list) +{ + return (list->bptl_length); +} + +int +netstat_bpti_alloc(struct bpf_type_list *list, + struct bpf_type_iterator **iterator) +{ + struct bpf_type_iterator *btp; + + btp = malloc(sizeof(*btp)); + if (btp == NULL) + return (-1); + + bzero(btp, sizeof(*btp)); + btp->bpti_list = list; + btp->bpti_first = LIST_FIRST(&list->bptl_list); + if (btp->bpti_first != NULL) + btp->bpti_next = LIST_NEXT(btp->bpti_first, bpt_list); + *iterator = btp; + return (0); +} + +const struct bpf_type * +netstat_bpti_first(struct bpf_type_iterator *btip) +{ + if (btip->bpti_first != NULL) + btip->bpti_next = LIST_NEXT(btip->bpti_first, bpt_list); + return (btip->bpti_first); +} + +const struct bpf_type * +netstat_bpti_next(struct bpf_type_iterator *btip) +{ + const struct bpf_type *btp; + + btp = btip->bpti_next; + if (btip->bpti_next != NULL) + btip->bpti_next = LIST_NEXT(btip->bpti_next, bpt_list); + + return (btp); +} + +void +netstat_bpti_free(struct bpf_type_iterator *btip) +{ + free(btip); +} + +void +netstat_bpt_free(struct bpf_type *btp) +{ + free(btp->bpt_pidname); + free(btp); +} + +int +netstat_bpt_get_flags(const struct bpf_type *btp) +{ + return (btp->bpt_flags); +} + +enum bpf_dir +netstat_bpt_get_direction(const struct bpf_type *btp) +{ + return (btp->bpt_direction); +} + +u_int32_t +netstat_bpt_get_pid(const struct bpf_type *btp) +{ + return (btp->bpt_pid); +} + +const char * +netstat_bpt_get_ifname(const struct bpf_type *btp) +{ + return (btp->bpt_ifname); +} + +u_int64_t +netstat_bpt_get_recv(const struct bpf_type *btp) +{ + return (btp->bpt_recv); +} + +u_int64_t +netstat_bpt_get_drop(const struct bpf_type *btp) +{ + return (btp->bpt_drop); +} + +u_int64_t +netstat_bpt_get_match(const struct bpf_type *btp) +{ + return (btp->bpt_match); +} + +u_int64_t +netstat_bpt_get_slen(const struct bpf_type *btp) +{ + return (btp->bpt_slen); +} + +u_int64_t +netstat_bpt_get_hlen(const struct bpf_type *btp) +{ + return (btp->bpt_hlen); +} + +const char * +netstat_bpt_get_pidname(const struct bpf_type *btp) +{ + return (btp->bpt_pidname); +} + const char * routename(in_addr_t in, int numeric) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907240351.n6O3p2JQ034946>