PERFORCE change 164165 for review
Gabor Pali
pgj at FreeBSD.org
Fri Jun 12 11:13:47 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=164165
Change 164165 by pgj at petymeg-current on 2009/06/12 11:13:28
- Add KVM extraction code for inet
- Refine NPCB_### macros
- Refine ipproto
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#21 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#21 (text+ko) ====
@@ -55,7 +55,8 @@
{ "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
static int
-net_local_pcblist_sysctl(int type, struct socket_type_list *list, int flags)
+net_local_pcblist_sysctl(int family, int type, struct socket_type_list *list,
+ int flags)
{
char *buf;
size_t len;
@@ -90,7 +91,7 @@
xunp = (struct xunpcb *)xug;
/* Keep active PCBs only. */
if (xunp->xu_unp.unp_gencnt <= oxug->xug_gen) {
- stp = _netstat_st_allocate(list, PF_LOCAL, type,
+ stp = _netstat_st_allocate(list, family, type,
socktype[type]);
extract_xunpcb_data(xunp, stp);
}
@@ -100,38 +101,46 @@
return (0);
}
-static int
-net_inet_pcblist_sysctl(int protocol, struct socket_type_list *list, int flags)
+static const char *
+ipproto(int protocol)
{
- char *buf;
- size_t len;
- char mibvar[64];
- const char *ipproto;
-
- struct xinpgen *xig, *oxig;
- struct tcpcb *tp = NULL;
- struct inpcb *inp;
- struct xsocket *so;
-
- struct socket_type *stp;
+ const char * result;
switch (protocol) {
case IPPROTO_TCP:
- ipproto = "tcp";
+ result = "tcp";
break;
case IPPROTO_UDP:
- ipproto = "udp";
+ result = "udp";
break;
case IPPROTO_DIVERT:
- ipproto = "divert";
+ result = "divert";
break;
default:
case IPPROTO_RAW:
- ipproto = "raw";
+ result = "raw";
break;
}
- sprintf(mibvar, "net.inet.%s.pcblist", ipproto);
+ return (result);
+}
+
+static int
+net_inet_pcblist_sysctl(int family, int protocol,
+ struct socket_type_list *list, int flags)
+{
+ char *buf;
+ size_t len;
+ char mibvar[64];
+
+ struct xinpgen *xig, *oxig;
+ struct tcpcb *tp = NULL;
+ struct inpcb *inp;
+ struct xsocket *so;
+
+ struct socket_type *stp;
+
+ sprintf(mibvar, "net.inet.%s.pcblist", ipproto(protocol));
len = 0;
if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
@@ -191,8 +200,8 @@
))
continue;
- stp = _netstat_st_allocate(list, PF_INET, protocol,
- ipproto);
+ stp = _netstat_st_allocate(list, family, protocol,
+ ipproto(protocol));
extract_inet_data(tp, inp, so, stp);
}
@@ -208,7 +217,7 @@
} while (0);
static int
-net_local_pcblist_kvm(int type, struct socket_type_list *list,
+net_local_pcblist_kvm(int family, int type, struct socket_type_list *list,
kvm_t *kvm, struct nlist *nlistp, int flags)
{
struct unp_head head;
@@ -270,7 +279,7 @@
list->stl_error = NETSTAT_ERROR_UNDEFINED;
return (-1);
}
- stp = _netstat_st_allocate(list, PF_LOCAL, type,
+ stp = _netstat_st_allocate(list, family, type,
socktype[type]);
extract_xunpcb_data(&xu, stp);
}
@@ -279,10 +288,83 @@
}
static int
-net_inet_pcblist_kvm(int protocol, struct socket_type_list *list,
+net_inet_pcblist_kvm(int family, int protocol, struct socket_type_list *list,
kvm_t *kvm, struct nlist *nlistp, int flags)
{
- /* XXX: to be filled in. */
+ struct inpcbinfo pcbinfo;
+ struct inpcbhead listhead;
+ struct inpcb *inp;
+ struct xinpcb xi;
+ struct xinpgen xig;
+ struct xtcpcb xt;
+ struct tcpcb *tcb = NULL;
+ struct socket so;
+ struct xsocket *xso;
+ u_long off;
+
+ struct socket_type *stp;
+
+ switch (protocol) {
+ case IPPROTO_TCP:
+ off = nlistp[X_TCBINFO].n_value;
+ break;
+ case IPPROTO_UDP:
+ off = nlistp[X_UDBINFO].n_value;
+ break;
+ case IPPROTO_DIVERT:
+ off = nlistp[X_DIVCBINFO].n_value;
+ break;
+ case IPPROTO_RAW:
+ case IPPROTO_ICMP:
+ case IPPROTO_IGMP:
+ case IPPROTO_PIM:
+ off = nlistp[X_RIPCBINFO].n_value;
+ break;
+ default:
+ list->stl_error = NETSTAT_ERROR_UNDEFINED;
+ return (-1);
+ }
+
+ KREAD(off, &pcbinfo, sizeof(pcbinfo));
+ LIST_FOREACH(inp, &listhead, inp_list) {
+ if (protocol == IPPROTO_TCP) {
+ KREAD(inp, &xt.xt_inp, sizeof(*inp));
+ inp = &xt.xt_inp;
+ } else {
+ KREAD(inp, &xi.xi_inp, sizeof(*inp));
+ inp = &xi.xi_inp;
+ }
+
+ /* Keep active PCBs only. */
+ if (inp->inp_gencnt > pcbinfo.ipi_gencnt)
+ continue;
+
+ if (protocol == IPPROTO_TCP) {
+ if (inp->inp_ppcb == NULL)
+ bzero(&xt.xt_tp, sizeof(xt.xt_tp));
+ else if (inp->inp_flags & INP_TIMEWAIT) {
+ bzero(&xt.xt_tp, sizeof(xt.xt_tp));
+ xt.xt_tp.t_state = TCPS_TIME_WAIT;
+ } else
+ KREAD(inp->inp_ppcb, &xt.xt_tp,
+ sizeof(xt.xt_tp));
+ }
+ if (inp->inp_socket) {
+ KREAD(inp->inp_socket, &so, sizeof(so));
+ if (sotoxsocket(kvm, &so, xso) != 0) {
+ list->stl_error = NETSTAT_ERROR_UNDEFINED;
+ return (-1);
+ }
+ } else {
+ bzero(xso, sizeof(*xso));
+ if (protocol == IPPROTO_TCP)
+ xso->xso_protocol = protocol;
+ }
+ stp = _netstat_st_allocate(list, family, protocol,
+ ipproto(protocol));
+ extract_inet_data(tcb, inp, xso, stp);
+ }
+
return (0);
}
@@ -305,16 +387,17 @@
}
}
-#define NPCB_KVM(family, type, list, kvm, nl, flags) do { \
- if (net_##family##_pcblist_kvm((type), (list), (kvm), (nl), \
+#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do { \
+ if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \
(flags)) != 0) { \
list->stl_error = NETSTAT_ERROR_UNDEFINED; \
return (-1); \
} \
} while (0)
-#define NPCB_SCT(family, type, list, flags) do { \
- if (net_##family##_pcblist_sysctl((type), (list), (flags)) != 0) { \
+#define NPCB_SCT(proc, family, type, list, flags) do { \
+ if (net_##proc##_pcblist_sysctl((family), (type), (list), \
+ (flags)) != 0) { \
list->stl_error = NETSTAT_ERROR_UNDEFINED; \
return (-1); \
} \
@@ -326,21 +409,24 @@
case SOCK_STREAM:
case SOCK_DGRAM:
if (use_kvm)
- NPCB_KVM(local, type, list, kvm, nl, flags);
+ NPCB_KVM(local, domain, type, list, kvm, nl,
+ flags);
else
/* Use sysctl (or something else). */
- NPCB_SCT(local, type, list, flags);
+ NPCB_SCT(local, domain, type, list, flags);
break;
/* All PF_LOCAL */
case 0:
if (use_kvm) {
- NPCB_KVM(local, SOCK_STREAM, list, kvm, nl,
+ NPCB_KVM(local, domain, SOCK_STREAM, list, kvm,
+ nl, flags);
+ NPCB_KVM(local, domain, SOCK_DGRAM, list, kvm,
+ nl, flags);
+ } else {
+ NPCB_SCT(local, domain, SOCK_STREAM, list,
flags);
- NPCB_KVM(local, SOCK_DGRAM, list, kvm, nl,
+ NPCB_SCT(local, domain, SOCK_DGRAM, list,
flags);
- } else {
- NPCB_SCT(local, SOCK_STREAM, list, flags);
- NPCB_SCT(local, SOCK_DGRAM, list, flags);
}
break;
default:
@@ -360,26 +446,31 @@
case IPPROTO_PIM:
case IPPROTO_ICMPV6:
if (use_kvm)
- NPCB_KVM(inet, protocol, list, kvm, nl, flags);
+ NPCB_KVM(inet, domain, protocol, list, kvm, nl,
+ flags);
else
- NPCB_SCT(inet, protocol, list, flags);
+ NPCB_SCT(inet, domain, protocol, list, flags);
break;
/* All PF_INET */
case 0:
if (use_kvm) {
- NPCB_KVM(inet, IPPROTO_TCP, list, kvm, nl,
+ NPCB_KVM(inet, domain, IPPROTO_TCP, list, kvm,
+ nl, flags);
+ NPCB_KVM(inet, domain, IPPROTO_UDP, list, kvm,
+ nl, flags);
+ NPCB_KVM(inet, domain, IPPROTO_DIVERT, list,
+ kvm, nl, flags);
+ NPCB_KVM(inet, domain, IPPROTO_RAW, list, kvm,
+ nl, flags);
+ } else {
+ NPCB_SCT(inet, domain, IPPROTO_TCP, list,
flags);
- NPCB_KVM(inet, IPPROTO_UDP, list, kvm, nl,
+ NPCB_SCT(inet, domain, IPPROTO_UDP, list,
flags);
- NPCB_KVM(inet, IPPROTO_DIVERT, list, kvm, nl,
+ NPCB_SCT(inet, domain, IPPROTO_DIVERT, list,
flags);
- NPCB_KVM(inet, IPPROTO_RAW, list, kvm, nl,
+ NPCB_SCT(inet, domain, IPPROTO_RAW, list,
flags);
- } else {
- NPCB_SCT(inet, IPPROTO_TCP, list, flags);
- NPCB_SCT(inet, IPPROTO_UDP, list, flags);
- NPCB_SCT(inet, IPPROTO_DIVERT, list, flags);
- NPCB_SCT(inet, IPPROTO_RAW, list, flags);
}
break;
default:
More information about the p4-projects
mailing list