PERFORCE change 166486 for review

Gabor Pali pgj at FreeBSD.org
Fri Jul 24 03:51:03 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166486

Change 166486 by pgj at 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)
 {


More information about the p4-projects mailing list