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