summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2001-10-21 21:57:10 +0000
committerdes <des@FreeBSD.org>2001-10-21 21:57:10 +0000
commit90be41ff5d2f1e88a4cf1d9a36a241a2dc159e7a (patch)
tree0ee86c2b6e560fa1bfad07553d5be4d19fc31603 /usr.bin
parent359955a1956383c238da1fab2a6b379f9ce90dd7 (diff)
downloadFreeBSD-src-90be41ff5d2f1e88a4cf1d9a36a241a2dc159e7a.zip
FreeBSD-src-90be41ff5d2f1e88a4cf1d9a36a241a2dc159e7a.tar.gz
Teach truss(1) to display sockaddrs. It currently knows about AF_INET,
AF_INET6 and AF_UNIX sockaddrs, and will recognize accept(), bind(), connect(), getpeername() and getsockname() as syscalls taking sockaddr arguments. Some enterprising soul might want to add (and test) support for the send() / recv() family of syscalls as well. MFC after: 1 week
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/truss/syscall.h2
-rw-r--r--usr.bin/truss/syscalls.c83
2 files changed, 82 insertions, 3 deletions
diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h
index 5e556e1..a663573 100644
--- a/usr.bin/truss/syscall.h
+++ b/usr.bin/truss/syscall.h
@@ -22,7 +22,7 @@
*/
enum Argtype { None = 1, Hex, Octal, Int, String, Ptr, Stat, Ioctl, Quad,
- Signal };
+ Signal, Sockaddr };
#define ARG_MASK 0xff
#define OUT 0x100
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index cd92deb..2512225 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -39,13 +39,19 @@ static const char rcsid[] =
* arguments.
*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#include <err.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <sys/types.h>
-#include <signal.h>
+
#include "syscall.h"
/*
@@ -83,6 +89,16 @@ struct syscall syscalls[] = {
{ "access", 1, 2, { { String | IN, 0 }, { Int, 1 }}},
{ "sigaction", 1, 3,
{ { Signal, 0 }, { Ptr | IN, 1 }, { Ptr | OUT, 2 }}},
+ { "accept", 1, 3,
+ { { Hex, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
+ { "bind", 1, 3,
+ { { Hex, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } },
+ { "connect", 1, 3,
+ { { Hex, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } },
+ { "getpeername", 1, 3,
+ { { Hex, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
+ { "getsockname", 1, 3,
+ { { Hex, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
{ 0, 0, 0, { { 0, 0 }}},
};
@@ -106,6 +122,32 @@ get_syscall(const char *name) {
}
/*
+ * get_struct
+ *
+ * Copy a fixed amount of bytes from the process.
+ */
+
+int
+get_struct(int procfd, void *offset, void *buf, int len) {
+ char *pos;
+ FILE *p;
+ int c, fd;
+
+ if ((fd = dup(procfd)) == -1)
+ err(1, "dup");
+ if ((p = fdopen(fd, "r")) == NULL)
+ err(1, "fdopen");
+ fseek(p, (long)offset, SEEK_SET);
+ for (pos = (char *)buf; len--; pos++) {
+ if ((c = fgetc(p)) == EOF)
+ return -1;
+ *pos = c;
+ }
+ fclose(p);
+ return 0;
+}
+
+/*
* get_string
* Copy a string from the process. Note that it is
* expected to be a C string, but if max is set, it will
@@ -243,6 +285,43 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args) {
}
}
break;
+ case Sockaddr:
+ {
+ struct sockaddr *sa;
+ char addr[64];
+ u_char sa_len;
+ char *p, *q;
+ int i, len;
+
+ /* yuck: get sa_len */
+ get_struct(fd, (void *)args[sc->offset], (void *)&sa_len, sizeof sa_len);
+ sa = malloc(sa_len);
+ get_struct(fd, (void *)args[sc->offset], (void *)sa, sa_len);
+
+ tmp = malloc(100);
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ inet_ntop(AF_INET, &sin->sin_addr, addr, sizeof addr);
+ sprintf(tmp, "{ AF_INET %s:%d }", addr, htons(sin->sin_port));
+ } else if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ inet_ntop(AF_INET6, &sin6->sin6_addr, addr, sizeof addr);
+ sprintf(tmp, "{ AF_INET6 [%s]:%d }", addr, htons(sin6->sin6_port));
+ } else if (sa->sa_family == AF_UNIX) {
+ struct sockaddr_un *sun = (struct sockaddr_un *)sa;
+ sprintf(tmp, "{ AF_UNIX \"%s\" }", sun->sun_path);
+ } else {
+ p = tmp;
+ p += sprintf(p, "{ sa_len = %d, sa_family = %d, sa_data = {",
+ sa->sa_len, sa->sa_family);
+ for (q = sa->sa_data; q < ((char *)sa) + sa_len; q++)
+ p += sprintf(p, " 0x%02x,", *q);
+ p--;
+ p += sprintf(p, "} }");
+ }
+ free(sa);
+ }
+ break;
}
return tmp;
}
OpenPOWER on IntegriCloud