Skip site navigation (1)Skip section navigation (2)
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>