/*
* SGI systems running IRIX 4.x
*
* $Id: irix4.c,v 1.2 1995/08/21 22:59:56 jdd Exp $
*/
#include <stdio.h>
#ifdef IRIX4
#include <stdlib.h>
#include <nlist.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
#define _KERNEL
#include <sys/file.h>
#include <sys/inode.h>
#include <sys/fstyp.h>
#include <sys/fsid.h>
#include <fcntl.h>
#include <sys/user.h>
#include <sys/wait.h>
#undef _KERNEL
#include "tcplist.h"
#include "utils.h"
#include "kvm.h"
struct nlist nl[] = {
#define N_FILE 0
{ "file" },
#define N_V 1
{ "v" },
{ "" },
};
struct hostlist *make_hostlist(localaddr, servershow)
u_long *localaddr;
int servershow;
{
kvm_t *kd;
int nfiles, i;
u_long addr;
struct hostlist *hlist = NUL(struct hostlist *);
struct file *filetable;
char *localhost = NULL;
struct var v;
int socket_index;
socket_index = sysfs(GETFSIND, FSID_SOCKET);
if(NULL==(kd=kvm_open(NULL, NULL, NULL, O_RDONLY, progname))){
Error("kvm_open");
}
if(0!=kvm_nlist(kd, nl)){
Error("kvm_nlist: %d", kvm_nlist(kd, nl));
}
getkvm(kd, nl[N_V].n_value, &v, sizeof(v));
nfiles=v.v_file;
addr=nl[N_FILE].n_value;
filetable=(struct file *)calloc(nfiles, sizeof(struct file));
if(NULL==filetable){
Error("Can't allocate memory for file table.");
}
getkvm(kd, addr, filetable, nfiles * sizeof(struct file));
for(i=0;i<nfiles;i++){
struct socket so, *sp;
struct protosw ps;
struct domain dom;
struct inpcb pcb;
struct inode inode;
struct passwd *pw;
struct connection *cn;
struct hostlist *hl;
int found;
sp=&so;
if(0!=filetable[i].f_count){
int uid;
/* grab the socket out of the kernel. Is it
* a stream socket? If not, go on. */
getkvm(kd, filetable[i].f_inode, &inode, sizeof(inode));
if(socket_index != inode.i_fstyp) continue;
getkvm(kd, soc_fsptr(&inode), &so,
sizeof(struct socket));
if(sp->so_type!=SOCK_STREAM) continue;
/* now get the protosw. */
getkvm(kd, sp->so_proto, &ps, sizeof(ps));
/* ... and its domain. go on if not internet. */
getkvm(kd, ps.pr_domain, &dom, sizeof(dom));
if(dom.dom_family!=AF_INET) continue;
/* If we've gotten this far, it's a tcp socket. Let's
* get the protocol control block... */
if(0==sp->so_pcb) continue;
getkvm(kd, sp->so_pcb, &pcb, sizeof(pcb));
/* (but if foreign addr is ANY, this is a server, so
* if we don't want servers, stop here.) */
if(!servershow){
if(INADDR_ANY == pcb.inp_faddr.s_addr) continue;
}
/* ...and the user id */
uid=inode.i_uid;
pw=getpwuid(uid);
if(NULL==pw){
pw=new(struct passwd);
pw->pw_name=mem(10);
sprintf(pw->pw_name, "#%d", uid);
pw->pw_uid=uid;
}
#ifdef DEBUG
dfprintf(3, stderr, "user id is %d and user is %s\n",
uid, pw->pw_name);
#endif /* DEBUG */
/* is this host already on the hostlist? */
found = FALSE;
for(hl=hlist;NULL!=hl;hl=hl->next){
if(pcb.inp_faddr.s_addr == hl->addr){
/* found it */
found = TRUE;
break;
}
}
if(!found){
/* create new hostlist entry */
hl=new(struct hostlist);
hl->addr = pcb.inp_faddr.s_addr;
*localaddr = pcb.inp_laddr.s_addr;
hl->conn = NUL(struct connection *);
hl->next = hlist;
hlist = hl;
}
/* create new connection entry */
cn=new(struct connection);
cn->remote=pcb.inp_fport;
cn->local=pcb.inp_lport;
cn->user=s(pw->pw_name);
cn->next=hl->conn;
hl->conn=cn;
}
}
return(hlist);
}
#endif /* IRIX4 */
syntax highlighted by Code2HTML, v. 0.9.1