PERFORCE change 164301 for review
Gabor Pali
pgj at FreeBSD.org
Sat Jun 13 22:39:37 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=164301
Change 164301 by pgj at petymeg-current on 2009/06/13 22:39:26
- Add a simple version of addr_type (inside socket_type) as an
abstraction for addresses connected to a connection (max. 2
addresses per socket at the moment).
- Use addr_type for unix domain sockets and inet socket, however
the latter one needs some work (no support for getting address
in numeric format yet).
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#26 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#17 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#15 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#17 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#14 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#13 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#26 (text+ko) ====
@@ -10,6 +10,8 @@
#include <err.h>
#include <errno.h>
#include <kvm.h>
+#include <libutil.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
#include <netinet/tcp_var.h>
@@ -20,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "netstat.h"
#include "netstat_internal.h"
@@ -50,6 +53,14 @@
static void extract_xunpcb_data(struct xunpcb *, struct socket_type *);
static void extract_inet_data(struct tcpcb *, struct inpcb *,
struct xsocket *, struct socket_type *);
+
+static char ntop_buf[INET6_ADDRSTRLEN];
+
+static struct addr_type *extract_inet_address(int type, const char *proto,
+ struct in_addr *in, u_short port, int anonport);
+static struct addr_type *extract_inet6_address(int type, const char *proto,
+ struct in6_addr *in, u_short port);
+
static int netstat_local_sockets(int, struct socket_type_list *, kvm_t *,
struct nlist *, int);
static int netstat_inet_sockets(int, int, struct socket_type_list *,
@@ -557,6 +568,7 @@
extract_xunpcb_data(struct xunpcb *xpcb, struct socket_type *stp)
{
struct sockaddr_un *sa;
+ char address[1024];
strlcpy(stp->st_extname, stp->st_name, SOCKTYPE_MAXNAME);
stp->st_qlen = xpcb->xu_socket.so_qlen;
@@ -582,13 +594,17 @@
stp->st_refs = (u_long)LIST_FIRST(&xpcb->xu_unp.unp_refs);
stp->st_reflink = (u_long)LIST_NEXT(&xpcb->xu_unp, unp_reflink);
stp->st_flags = SOCKTYPE_VNODE | SOCKTYPE_CONN | SOCKTYPE_REFS;
+ stp->st_addrcnt = 0;
if (xpcb->xu_unp.unp_addr) {
sa = (struct sockaddr_un *)&xpcb->xu_addr;
- sprintf(stp->st_address, "%.*s",
+ sprintf(address, "%.*s",
(int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
sa->sun_path);
- } else {
- stp->st_address[0] = '\0';
+ stp->st_address[stp->st_addrcnt] =
+ _netstat_at_allocate(NETSTAT_ADDRTYPE_LOCAL, address, NULL);
+ stp->st_address[stp->st_addrcnt]->at_port = 0;
+ strcpy(stp->st_address[stp->st_addrcnt]->at_portname, "*");
+ stp->st_addrcnt += 1;
}
stp->st_tcpstate[0] = '\0';
}
@@ -623,10 +639,7 @@
stp->st_refs = (u_long)0;
stp->st_reflink = (u_long)0;
stp->st_flags = 0;
- /* XXX: Remove this. */
- stp->XXX_inpcb = *inp;
- /* XXX: address is missing. */
- stp->st_address[0] = '\0';
+ stp->st_addrcnt = 0;
if (tp != NULL) {
if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
sprintf(stp->st_tcpstate, "%d", tp->t_state);
@@ -654,4 +667,132 @@
vchar = ((inp->inp_vflag & INP_IPV4) != 0) ?
"4 " : " ";
sprintf(stp->st_extname, "%-3.3s%-2.2s", stp->st_name, vchar);
+ /* local address */
+ if (inp->inp_vflag & INP_IPV4) {
+ stp->st_address[stp->st_addrcnt] =
+ extract_inet_address(NETSTAT_ADDRTYPE_INET_LOCAL,
+ stp->st_name, &inp->inp_laddr, inp->inp_lport,
+ inp->inp_vflag & INP_ANONPORT);
+ }
+#ifdef INET6
+ else if (inp->inp_vflag & INP_IPV6) {
+ stp->st_address[stp->st_addrcnt] =
+ extract_inet6_address(NETSTAT_ADDRTYPE_INET6_LOCAL,
+ stp->st_name, &inp->in6p_laddr, inp->inp_lport);
+ }
+#endif
+ stp->st_addrcnt += 1;
+ /* foreign address */
+ if (inp->inp_vflag & INP_IPV6) {
+ stp->st_address[stp->st_addrcnt] =
+ extract_inet_address(NETSTAT_ADDRTYPE_INET_FOREIGN,
+ stp->st_name, &inp->inp_faddr, inp->inp_fport,
+ inp->inp_vflag & INP_ANONPORT);
+ }
+#ifdef INET6
+ else if (inp->inp_vflag & INP_IPV6) {
+ stp->st_address[stp->st_addrcnt] =
+ extract_inet6_address(NETSTAT_ADDRTYPE_INET6_FOREIGN,
+ stp->st_name, &inp->in6p_faddr, inp->inp_fport);
+ }
+#endif
+ stp->st_addrcnt += 1;
+}
+
+struct addr_type *
+extract_inet_address(int type, const char *proto, struct in_addr *in,
+ u_short port, int anonport)
+{
+ struct addr_type *result;
+ char address[256];
+ struct hostent *hp;
+ struct netent *np;
+ struct servent *sp = NULL;
+ int net, lna;
+ char *cp;
+
+ cp = NULL;
+ if (in->s_addr != INADDR_ANY) {
+ net = inet_netof(*in);
+ lna = inet_lnaof(*in);
+
+ if (lna == INADDR_ANY) {
+ np = getnetbyaddr(net, AF_INET);
+ if (np != NULL)
+ cp = np->n_name;
+ }
+ if (cp == NULL) {
+ hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
+ if (hp != NULL) {
+ cp = hp->h_name;
+ trimdomain(cp, strlen(cp));
+ }
+ }
+ }
+ if (in->s_addr == INADDR_ANY)
+ strcpy(address, "*");
+ else if (cp) {
+ strlcpy(address, cp, sizeof(address));
+ } else {
+ in->s_addr = ntohl(in->s_addr);
+#define C(x) ((u_int)((x) & 0xff))
+ sprintf(address, "%u.%u.%u.%u", C(in->s_addr >> 24),
+ C(in->s_addr >> 16), C(in->s_addr >> 8),
+ C(in->s_addr));
+ }
+ result = _netstat_at_allocate(type, address, NULL);
+ result->at_port = port;
+ sp = getservbyport((int)port, proto);
+ if ((sp != NULL || port == 0) && !anonport)
+ sprintf(result->at_portname, "%.15s", sp ? sp->s_name : "*");
+ else
+ sprintf(result->at_portname, "%d", ntohs(port));
+
+ return (result);
+#undef C
+}
+
+struct addr_type *
+extract_inet6_address(int type, const char *proto, struct in6_addr *in,
+ u_short port)
+{
+ struct addr_type *result;
+ char address[256], domain[MAXHOSTNAMELEN];
+ struct hostent *hp;
+ struct servent *sp = NULL;
+ char *cp;
+
+ if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
+ (cp = index(domain, '.')))
+ strcpy(domain, cp + 1);
+ else
+ domain[0] = '\0';
+ cp = NULL;
+ if (!IN6_IS_ADDR_UNSPECIFIED(in)) {
+ hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET6);
+ if (hp != NULL) {
+ if ((cp = index(hp->h_name, '.')) &&
+ !strcmp(cp + 1, domain))
+ *cp = '\0';
+ cp = hp->h_name;
+ }
+ }
+ if (IN6_IS_ADDR_UNSPECIFIED(in))
+ strcpy(address, "*");
+ else if (cp)
+ strcpy(address, cp);
+ else
+ sprintf(address, "%s",
+ inet_ntop(AF_INET6, (void *)in, ntop_buf,
+ sizeof(ntop_buf)));
+
+ result = _netstat_at_allocate(type, address, NULL);
+ result->at_port = port;
+ sp = getservbyport((int)port, proto);
+ if (sp != NULL || port == 0)
+ sprintf(result->at_portname, "%.15s", sp ? sp->s_name : "*");
+ else
+ sprintf(result->at_portname, "%d", ntohs(port));
+
+ return (result);
}
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#17 (text+ko) ====
@@ -9,6 +9,7 @@
#define SOCKTYPE_MAXNAME 32
#define SOCKTYPE_MAXADDR SOCK_MAXADDRLEN
+#define SOCKTYPE_MAXADDRCNT 2
#define NETSTAT_ERROR_UNDEFINED 0
#define NETSTAT_ERROR_NOMEMORY 1
@@ -26,6 +27,8 @@
struct socket_type_list;
struct socket_type_iterator;
+struct addr_type;
+
__BEGIN_DECLS
const char *netstat_strerror(int);
@@ -49,6 +52,7 @@
void netstat_sti_free(struct socket_type_iterator *iterator);
void netstat_st_free(struct socket_type *stp);
+void netstat_at_free(struct addr_type *atp);
int netstat_socket(int domain, int type, int protocol,
struct socket_type_list *, int flags, void *kvm_handle);
@@ -81,10 +85,17 @@
u_long netstat_st_get_conn(const struct socket_type *stp);
u_long netstat_st_get_refs(const struct socket_type *stp);
u_long netstat_st_get_reflink(const struct socket_type *stp);
-const char *netstat_st_get_address(const struct socket_type *stp);
const char *netstat_st_get_tcpstate(const struct socket_type *stp);
-/* XXX: Remove this hacks. */
-struct inpcb XXX_netstat_st_get_inpcb(const struct socket_type *stp);
+/* Addresses: */
+int netstat_st_get_addrcnt(const struct socket_type *stp);
+struct addr_type *netstat_st_get_address(const struct socket_type *stp,
+ int index);
+
+const char *netstat_at_get_name(const struct addr_type *atp);
+void netstat_at_get_address(const struct addr_type *atp,
+ void *addr);
+u_short netstat_at_get_port(const struct addr_type *atp);
+const char *netstat_at_get_portname(const struct addr_type *atp);
__END_DECLS
#endif /* !_NETSTAT_H_ */
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#15 (text+ko) ====
@@ -13,15 +13,28 @@
#include <netinet/in_pcb.h>
#include <netinet/tcp_var.h>
-/* XXX: not used yet */
+#include "netstat.h"
+
/* Address type:
* local, foreign, node (Netgraph), raw (domain)
*/
-struct address_type {
+struct addr_type {
+ /* XXX: this should be an enum? */
int at_type;
- struct sockaddr_storage at_address;
+ char at_name[1024];
+ void *at_address;
+ u_short at_port;
+ char at_portname[32];
};
+#define NETSTAT_ADDRTYPE_LOCAL 0
+#define NETSTAT_ADDRTYPE_INET_LOCAL 1
+#define NETSTAT_ADDRTYPE_INET_FOREIGN 2
+#define NETSTAT_ADDRTYPE_INET46_LOCAL 3
+#define NETSTAT_ADDRTYPE_INET46_FOREIGN 4
+#define NETSTAT_ADDRTYPE_INET6_LOCAL 5
+#define NETSTAT_ADDRTYPE_INET6_FOREIGN 6
+
/* Socket (PCB) type: a connection. */
struct socket_type {
/* Static properties. */
@@ -31,11 +44,9 @@
char st_name[SOCKTYPE_MAXNAME];
char st_extname[SOCKTYPE_MAXNAME];
-#if 0
- /* XXX: not used yet */
- struct address_type *st_address; /* address(es) */
- int st_addrcnt; /* address count */
-#endif
+ /* address(es) */
+ struct addr_type *st_address[SOCKTYPE_MAXADDRCNT];
+ int st_addrcnt; /* address count */
u_int st_snd_cc; /* actual chars in the send buffer */
u_int st_snd_mcnt;
@@ -60,12 +71,8 @@
u_long st_conn; /* control block of connected socket */
u_long st_refs; /* referencing socket linked list */
u_long st_reflink; /* link in references list */
- char st_address[SOCKTYPE_MAXADDR];
char st_tcpstate[16];
- /* XXX: Removables. */
- struct inpcb XXX_inpcb;
-
/* list of types */
LIST_ENTRY(socket_type) st_list;
};
@@ -96,5 +103,8 @@
const char *name);
void _netstat_st_reset_stats(struct socket_type *list);
+struct addr_type *_netstat_at_allocate(int type, const char *name,
+ void *address);
+
int sotoxsocket(kvm_t * kvm, struct socket *so, struct xsocket *xso);
#endif /* !_NETSTAT_INTERNAL_H_ */
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#17 (text+ko) ====
@@ -155,6 +155,10 @@
void
netstat_st_free(struct socket_type *stp)
{
+ int i;
+
+ for (i = 0; i < stp->st_addrcnt; i++)
+ netstat_at_free(stp->st_address[i]);
free(stp);
}
@@ -285,6 +289,28 @@
free(iterator);
}
+/* Address type */
+struct addr_type *
+_netstat_at_allocate(int type, const char *name, void __unused *address)
+{
+ struct addr_type *atp;
+
+ atp = malloc(sizeof(*atp));
+ if (atp == NULL)
+ return (NULL);
+
+ bzero(atp, sizeof(*atp));
+ atp->at_type = type;
+ strlcpy(atp->at_name, name, 1024);
+ return (atp);
+}
+
+void
+netstat_at_free(struct addr_type *atp)
+{
+ free(atp);
+}
+
/* Accessor functions. */
int
netstat_st_get_family(const struct socket_type *stp)
@@ -443,20 +469,55 @@
}
const char *
-netstat_st_get_address(const struct socket_type *stp)
+netstat_st_get_tcpstate(const struct socket_type *stp)
+{
+ return (stp->st_tcpstate);
+}
+
+int
+netstat_st_get_addrcnt(const struct socket_type *stp)
+{
+
+ return (stp->st_addrcnt);
+}
+
+struct addr_type *
+netstat_st_get_address(const struct socket_type *stp,
+ int index)
{
- return (stp->st_address);
+ struct addr_type *result = NULL;
+
+ if (0 <= index && index < stp->st_addrcnt) {
+ result = (struct addr_type *)malloc(sizeof(struct addr_type));
+ if (result != NULL) {
+ memcpy(result, stp->st_address[index],
+ sizeof(struct addr_type));
+ }
+ }
+
+ return (result);
}
const char *
-netstat_st_get_tcpstate(const struct socket_type *stp)
+netstat_at_get_name(const struct addr_type *atp)
+{
+ return (atp->at_name);
+}
+
+void
+netstat_at_get_address(const struct addr_type *atp, void *addr)
+{
+ /* XXX: stub */
+}
+
+u_short
+netstat_at_get_port(const struct addr_type *atp)
{
- return (stp->st_tcpstate);
+ return (atp->at_port);
}
-/* XXX: Remove this hacks. */
-struct inpcb
-XXX_netstat_st_get_inpcb(const struct socket_type *stp)
+const char *
+netstat_at_get_portname(const struct addr_type *atp)
{
- return (stp->XXX_inpcb);
+ return (atp->at_portname);
}
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#14 (text+ko) ====
@@ -95,6 +95,8 @@
#ifdef INET6
static int udp_done, tcp_done;
#endif /* INET6 */
+void addr_print(const struct addr_type *atp, const char *proto,
+ int numeric);
/*
* Print a summary of connections related to an Internet
@@ -157,9 +159,8 @@
{
static int first = 1;
char buf1[15];
- struct inpcb inp;
+ struct addr_type *laddr, *faddr;
- inp = XXX_netstat_st_get_inpcb(stp);
if (first) {
if (!Lflag) {
printf("Active Internet connections");
@@ -206,66 +207,16 @@
printf("%6u %6u ", netstat_st_get_rcv_cc(stp),
netstat_st_get_snd_cc(stp));
}
- if (numeric_port) {
- if (inp.inp_vflag & INP_IPV4) {
- inetprint(&inp.inp_laddr, (int)inp.inp_lport,
- netstat_st_get_name(stp), 1);
- if (!Lflag)
- inetprint(&inp.inp_faddr,
- (int)inp.inp_fport,
- netstat_st_get_name(stp), 1);
- }
-#ifdef INET6
- else if (inp.inp_vflag & INP_IPV6) {
- inet6print(&inp.in6p_laddr,
- (int)inp.inp_lport, netstat_st_get_name(stp), 1);
- if (!Lflag)
- inet6print(&inp.in6p_faddr,
- (int)inp.inp_fport,
- netstat_st_get_name(stp), 1);
- } /* else nothing printed now */
-#endif /* INET6 */
- } else if (inp.inp_flags & INP_ANONPORT) {
- if (inp.inp_vflag & INP_IPV4) {
- inetprint(&inp.inp_laddr, (int)inp.inp_lport,
- netstat_st_get_name(stp), 1);
- if (!Lflag)
- inetprint(&inp.inp_faddr,
- (int)inp.inp_fport,
- netstat_st_get_name(stp), 0);
- }
-#ifdef INET6
- else if (inp.inp_vflag & INP_IPV6) {
- inet6print(&inp.in6p_laddr,
- (int)inp.inp_lport, netstat_st_get_name(stp), 1);
- if (!Lflag)
- inet6print(&inp.in6p_faddr,
- (int)inp.inp_fport,
- netstat_st_get_name(stp), 0);
- } /* else nothing printed now */
-#endif /* INET6 */
- } else {
- if (inp.inp_vflag & INP_IPV4) {
- inetprint(&inp.inp_laddr, (int)inp.inp_lport,
- netstat_st_get_name(stp), 0);
- if (!Lflag)
- inetprint(&inp.inp_faddr,
- (int)inp.inp_fport,
- netstat_st_get_name(stp),
- inp.inp_lport != inp.inp_fport);
- }
-#ifdef INET6
- else if (inp.inp_vflag & INP_IPV6) {
- inet6print(&inp.in6p_laddr,
- (int)inp.inp_lport, netstat_st_get_name(stp), 0);
- if (!Lflag)
- inet6print(&inp.in6p_faddr,
- (int)inp.inp_fport,
- netstat_st_get_name(stp),
- inp.inp_lport != inp.inp_fport);
- } /* else nothing printed now */
-#endif /* INET6 */
+ laddr = netstat_st_get_address(stp, 0); /* local */
+ faddr = netstat_st_get_address(stp, 1); /* foreign */
+ addr_print(laddr, netstat_st_get_name(stp), numeric_port);
+ if (!Lflag) {
+ addr_print(faddr, netstat_st_get_name(stp),
+ numeric_port ||
+ netstat_at_get_port(laddr) != netstat_at_get_port(faddr));
}
+ netstat_at_free(laddr);
+ netstat_at_free(faddr);
if (xflag) {
if (Lflag)
printf("%21s", " ");
@@ -971,3 +922,18 @@
}
return (line);
}
+
+void
+addr_print(const struct addr_type *atp, const char *proto, int numeric)
+{
+ int width;
+ char line[80], *cp;
+
+ /* XXX: Respect numeric for getting name. */
+ sprintf(line, "%.*s", Wflag ? 39 : (Aflag && !numeric) ? 12 : 16,
+ netstat_at_get_name(atp));
+ cp = index(line, '\0');
+ sprintf(cp, "%.15s ", netstat_at_get_portname(atp));
+ width = Wflag ? 45 : Aflag ? 18 : 22;
+ printf("%-*.*s", width, width, line);
+}
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#13 (text+ko) ====
@@ -115,6 +115,7 @@
{
static int first = 1;
char buf1[15];
+ struct addr_type *addr;
if (first && !Lflag) {
printf("Active UNIX domain sockets\n");
@@ -139,5 +140,10 @@
netstat_st_get_vnode(stp), netstat_st_get_conn(stp),
netstat_st_get_refs(stp), netstat_st_get_reflink(stp));
}
- printf(" %s\n", netstat_st_get_address(stp));
+ if (netstat_st_get_addrcnt(stp) > 0) {
+ addr = netstat_st_get_address(stp, 0);
+ printf(" %s", netstat_at_get_name(addr));
+ netstat_at_free(addr);
+ }
+ putchar('\n');
}
More information about the p4-projects
mailing list