Date: Tue, 18 May 1999 01:36:11 -0500 (EST) From: Alfred Perlstein <bright@rush.net> To: Marc Slemko <marcs@znep.com> Cc: hackers@FreeBSD.ORG Subject: forgot some stuff about sysctl: Re: libkvm sucks Message-ID: <Pine.BSF.3.96.990518013321.26546F-100000@cygnus.rush.net> In-Reply-To: <Pine.BSF.4.05.9905172057160.24565-100000@alive.znep.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 17 May 1999, Marc Slemko wrote: > The premise: libkvm is fatally flawed by design, and fixing it is not an > easy proposition. > > The reasoning: reading from kernel data structures without any locking has > obvious race conditions. > > This is why any identd that uses libkvm sucks and gets into loops all the > time, etc. > > This is why netstat will often bail out in the middle with kvm errors on a > busy machine with lots of TCP connections, especially if you slow it down > by doing hostname lookups. > > In fact, on BSDI systems I have even seen identd hang the entire machine > hard by reading from the wrong address that the IO APIC is mapped at (BSDI > maps it starting at 0xffff0000, which much worse than a random address > for accidental reads). > > In general, I'm no fan of the Linux style proc (by "Linux style" I mean > going crazy with the types of info there and the huge amount of formatting > done in the kernel), but in this case it can work a whole lot better, even > if it is somewhat less efficient. > > I'm sure this isn't a new problem, but I don't recall hearing of any > suggested solutions and I'm not aware of any alternative interface to get > the same info on FreeBSD. Anyone? doh: you also need a buncha headers: #include <stdio.h> #include <unistd.h> #include <pthread.h> #include <string.h> #include <stdarg.h> #include <sys/types.h> #include <pwd.h> #include <sys/time.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sysctl.h> #include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/in_pcb.h> #include <netinet/ip_var.h> #include <netinet/tcp.h> #include <netinet/tcpip.h> #include <netinet/tcp_seq.h> #define TCPSTATES #include <netinet/tcp_fsm.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> #include <netinet/tcp_debug.h> #define NO_ERR 0 #define ERR_SYSCTL 1 #define ERR_MALLOC 2 #define ERR_NOUSER 3 #define ERR_READ 4 #define ERR_TIMEOUT_READ 5 #define ERR_WRITE 6 #define ERR_TIMEOUT_WRITE 7 you may be able to trim this list, and here's that function again: uid_t get_sok_uid(u_short lport, u_short fport, int *err){ /* mostly stolen from netstat */ char *mibvar = "net.inet.tcp.pcblist"; char *buf; int proto = IPPROTO_TCP; uid_t retval = 0; struct tcpcb *tp; struct inpcb *inp; struct xinpgen *xig, *oxig; struct xsocket *so; size_t len = 0; *err = NO_ERR; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { *err = ERR_SYSCTL; return(0); } if ((buf = (char *) malloc(len)) == 0) { *err = ERR_MALLOC; return(0); } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { *err = ERR_SYSCTL; free(buf); return(0); } oxig = xig = (struct xinpgen *)buf; for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); xig->xig_len > sizeof(struct xinpgen); xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { tp = &((struct xtcpcb *)xig)->xt_tp; inp = &((struct xtcpcb *)xig)->xt_inp; so = &((struct xtcpcb *)xig)->xt_socket; /* Ignore sockets for protocols other than the desired one. */ if (so->xso_protocol != proto) continue; /* Ignore PCBs which were freed during copyout. */ if (inp->inp_gencnt > oxig->xig_gen) continue; /* check port */ if ( htons(inp->inp_fport) == fport && htons(inp->inp_lport) == lport){ printf("pgid = %d\n", so->so_pgid); retval = so->so_uid; free(buf); return( retval ); } } *err = ERR_NOUSER; free(buf); } -Alfred To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.990518013321.26546F-100000>