/* * Query lsof for open TCP connections. Assumes lsof, awk, sort, and uniq # are accessible via the current path. * * $Id: lsof.c,v 1.6 1996/11/21 02:02:00 jdd Exp $ */ #include #ifdef LSOF #include #include #include #include #include #include #include #include #include "tcplist.h" #include "utils.h" #ifndef LSOFCMD #ifdef OLDLSOF /* Older versions of lsof use -H instead of -n */ #define LSOFCMD "lsof -HPsli TCP | awk '{print $3,$NF}' | sort | uniq" #else /* !OLDLSOF */ /* These use the current (as of 3.62W, at least) parameters for lsof */ #define LSOFCMD "lsof -nPsli TCP | awk '{print $3,$(NF - 1)}' | sort | uniq" #endif /* !OLDLSOF */ #endif /* LSOFCMD */ #ifndef WHITESPACE #define WHITESPACE " \t\n" #endif /* WHITESPACE */ struct hostlist *make_hostlist(localaddr, servershow) u_long *localaddr; int servershow; { FILE *fp; char buff[BUFSIZ], *cp; int i, lport, fport, uid; u_long laddr, faddr; struct passwd *pw; struct hostlist *hlist = NUL(struct hostlist *); buff[sizeof(buff)-1]='\0'; /* make sure we have null termination */ #ifndef INSECURE (void)setuid(getuid()); /* just in case installed setuid/setgrpid */ #endif /* ndef INSECURE */ signal(SIGPIPE, SIG_IGN); if(NULL==(fp=popen(LSOFCMD, "r"))){ Error("Can't run lsof. Check your $PATH."); } /* grab and throw away initial header */ if(NULL==fgets(buff, sizeof(buff)-1,fp)){ Error("Can't get lsof output header"); } while(NULL!=fgets(buff,sizeof(buff)-1,fp)){ struct connection *cn; struct hostlist *hl; int found; buff[strlen(buff)-1]='\0'; /* strip trailing newline */ #ifdef DEBUG dfprintf(3, stderr, ">> %s\n", buff); #endif /* DEBUG */ /* get uid */ if(NULL==(cp=strtok(buff, WHITESPACE))) continue; uid=atoi(cp); if(0==uid && '0'!=*cp) continue; /* we split the next field as follows: */ /* Syntax: sourceaddr:lport->destaddr:destport */ /* or: *:lport */ /* or: sourceaddr->destaddr:destport */ if(NULL==(cp=strtok(NULL, WHITESPACE))) continue; if('*'==*cp){ /* *:lport case */ if(!servershow) continue; laddr=*localaddr; /* source port */ lport=atoi(cp+2); if(0==lport) continue; faddr=INADDR_ANY; fport=PORT_ANY; } else { char *p1, *p2; /* split field into local and remote halves */ if(NULL==(p1=strtok(cp, "->"))) continue; if(NULL==(p2=strtok(NULL, "->"))) continue; /* split halves */ if(NULL==(cp=strtok(p1, ":"))) continue; laddr=inet_addr(cp); #ifdef DEBUG dfprintf(5, stderr, "Local address is %s\n", cp); #endif /* DEBUG */ cp=strtok(NULL, ":"); if(NULL==cp) { lport=PORT_ANY; } else { lport=atoi(cp); } #ifdef DEBUG dfprintf(5, stderr, "Local port is %u\n", lport); #endif /* DEBUG */ /* split halves */ if(NULL==(cp=strtok(p2, ":"))) continue; faddr=inet_addr(cp); #ifdef DEBUG dfprintf(5, stderr, "Foreign address is %s\n", cp); #endif /* DEBUG */ cp=strtok(NULL, ":"); if(NULL==cp) { fport=PORT_ANY; } else { fport=atoi(cp); } #ifdef DEBUG dfprintf(5, stderr, "Foreign port is %u\n", lport); #endif /* DEBUG */ } 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(faddr == hl->addr){ /* found it */ found = TRUE; break; } } if(!found){ /* create new hostlist entry */ hl=new(struct hostlist); hl->addr = faddr; *localaddr = laddr; hl->conn = NUL(struct connection *); hl->next = hlist; hlist = hl; } /* create new connection entry */ cn=new(struct connection); cn->remote=fport; cn->local=lport; cn->user=s(pw->pw_name); cn->next=hl->conn; hl->conn=cn; } (void)fclose(fp); return(hlist); } #endif /* LSOF */