[ testsockmail 13K ]
Hi,
A few days ago I asked Sun Microsystems Spain if there was a way to asocciate a socket port
to a proccess. I had problems with an X11 application and I had no way to know the socket port
that this application used to comunicate with the xnews server (in a remote machine).
Sun Spain told me thah there was no way to do this.
I discovered in their Sunsolve Online a program called testfile.c and I modified this program
for check the socket descriptors. Here is the result.
I hope this will be usefull for people working with sockets in SunOs 4.1.3.
Sorry for my english.
Let's go Sun Spain, may be one day you can help your users in a best way.
Thank's to SunSolve Online and the people that created this first version of the program.
==========================================================================
Name: Oscar Perez.
Title: System analist.
Company: Union Electrica Fenosa.
Address: C/Capitan Haya, 53. Anexo 1 Norte. 28020 MADRID (SPAIN)
Fax: +34-1-5704349
E-mail: ope...@uef.es
==========================================================================
#include <kvm.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/vfs.h>
#include <ufs/inode.h>
#include <sys/sysmacros.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/route.h>
#include <netinet/in_pcb.h>
#include <netdb.h>
#define KERNEL
#include <sys/file.h>
#include <fcntl.h>
#include <stdio.h>
#include <mntent.h>
#define T_NFS "nfs"
#define T_4_2 "4.2"
#define T_SIZ sizeof(T_NFS)
struct fsid_tab {
fsid_t fsid;
char type[T_SIZ];
char dir[MAXPATHLEN];
struct fsid_tab *next_tab;
#define RD_FAILED(I) {fprintf(stderr, "%s: kvm_read failed (%d)\n", progname, I);exit(1);}
static char *progname;
static struct fsid_tab *find_table_entry();
main(argc, argv)
int argc;
char **argv;
{
kvm_t *kd, *kvm_open();
struct proc *proc_table, *kvm_next_proc();
struct user *user_table, *kvm_getu();
struct fsid_tab *current_tab, *first_tab=(struct fsid_tab
*)0;
int i, ok, first,tipo;
char c;
static struct vnode vnode;
static struct inode inode;
static struct vfs vfs;
static struct socket vs;
static struct socket vs2;
static struct socket *vs3;
static struct protosw *protovs;
static struct inpcb insock;
static struct proc procesos;
struct hostent *hostlocal;
struct hostent *hostremoto;
static struct file *file_table[NOFILE_IN_U];
static struct file file_struct;
if(NOFILE_IN_U != 64) {
fprintf(stderr,
"This program is compatible with 4.1.3 ONLY!\n");
exit(1);
}
progname = argv[0];
if((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, progname)) == NULL) {
fprintf(stderr, "%s: kvm_open failed\n", progname);
exit(1);
}
fill_table(&first_tab);
if(kvm_setproc(kd) < 0) {
fprintf(stderr, "%s: kvm_setproc failed\n", progname);
exit(1);
}
while((proc_table = kvm_nextproc(kd)) != NULL) {
if((user_table = kvm_getu(kd, proc_table)) == NULL) {
fprintf(stderr, "%s: kvm_getu failed\n", progname);
/* exit(1); It will not fail when there are a defunct process */
continue;
}
if(kvm_read(kd, (u_long)user_table->u_cdir, (char *)&vnode,
sizeof(vnode)) < 0)
RD_FAILED(1);
if(kvm_read(kd, (u_long)vnode.v_vfsp, (char *)&vfs,
sizeof(vnode)) < 0)
RD_FAILED(2);
current_tab = find_table_entry(&first_tab, vfs.vfs_fsid);
printf(".....\n");
printf("pid = %d,\tcwd ON filesystem ",
(int)proc_table->p_pid);
if(current_tab == (struct fsid_tab *)0) {
printf("-> ERROR - Can't find filesystem!!!\n");
continue;
}
printf("type %s -> %s\n",current_tab->type,current_tab->dir);
if(!strcmp(current_tab->type, T_4_2)) {
if(kvm_read(kd, (u_long)vnode.v_data, (char *)&inode,
sizeof(inode)) < 0)
RD_FAILED(3);
printf("pid = %d,\tcwd IS inode number -> %ld\n",
(int)proc_table->p_pid,
(u_long)inode.i_number);
}
if(kvm_read(kd, (u_long)user_table->u_ofile,
(char *)file_table, sizeof(file_table)) < 0)
RD_FAILED(4);
first = 1;
for(i = 0; i < NOFILE_IN_U; i++) {
if(file_table[i] == (struct file *)0)
continue;
if(first) {
first = 0;
printf(".....\n");
} else {
printf("\t.....\n");
}
if(kvm_read(kd, (u_long)file_table[i],
(char *)&file_struct, sizeof(file_struct)) < 0)
RD_FAILED(5);
PRINTFD(i);
printf("is type ");
tipo=0;
switch(file_struct.f_type) {
case DTYPE_VNODE:
printf("FILE, ");
tipo=1;
break;
case DTYPE_SOCKET:
printf("SOCKET or PIPE");
tipo=2;
break;
default:
printf("UNKNOWN (???)\n");
continue;
}
if (tipo==1) {
if(kvm_read(kd, (u_long)file_struct.f_data, (char
*)&vnode,
sizeof(vnode)) < 0)
RD_FAILED(6);
ok = 0;
switch(vnode.v_type) {
case VNON:
printf("VNON\n");
break;
case VREG:
++ok;
printf("VREG\n");
break;
case VDIR:
++ok;
printf("VDIR\n");
break;
case VBLK:
printf("VBLK (%d, %d)\n",
major(vnode.v_rdev),
minor(vnode.v_rdev));
break;
case VCHR:
printf("VCHR (%d, %d)\n",
major(vnode.v_rdev),
minor(vnode.v_rdev));
break;
case VLNK:
printf("VLNK\n");
break;
case VSOCK:
printf("VSOCK\n");
break;
case VBAD:
printf("VBAD\n");
break;
case VFIFO:
printf("VFIFO\n");
break;
}
if(kvm_read(kd, (u_long)vnode.v_vfsp, (char *)&vfs,
sizeof(vfs)) < 0){
fprintf(stderr, "%s: kvm_getu failed\n", progname);
/*RD_FAILED(7);Sometimes it fails, I don't know why I'm only
interested in sockets */
}
current_tab = find_table_entry(&first_tab, vfs.vfs_fsid);
PRINTFD(i);
printf("is FOUND ON filesystem ");
if(current_tab == (struct fsid_tab *)0) {
printf("-> ERROR - Can't find filesystem!!!\n");
continue;
}
printf("type %s -> %s\n", current_tab->type,
current_tab->dir);
if(ok && !strcmp(current_tab->type, T_4_2)) {
PRINTFD(i);
if(kvm_read(kd, (u_long)vnode.v_data, (char *)&inode,
sizeof(inode)) < 0)
RD_FAILED(8);
printf("is FOR inode number -> %ld\n",
(u_long)inode.i_number);
}
}
else if (tipo==2) { /* socket or pipe */
if(kvm_read(kd, (u_long)file_struct.f_data, (char *)&vs,
sizeof(vs)) < 0)
RD_FAILED(6);
printf(" State->%x",vs.so_state);
if ((vs.so_rcv).sb_sel != NULL){
if(kvm_read(kd, (u_long)(vs.so_rcv).sb_sel, (char *)&procesos,
sizeof(procesos)) < 0)
RD_FAILED(6);
printf(" Recept proccess-> %d",procesos.p_pid);
}
if ((vs.so_snd).sb_sel != NULL){
if(kvm_read(kd, (u_long)(vs.so_snd).sb_sel, (char *)&procesos,
sizeof(procesos)) < 0)
RD_FAILED(6);
printf(" Send process-> %d",procesos.p_pid);
}
if(kvm_read(kd, (u_long)vs.so_pcb,(char *)&insock,
sizeof(insock)) <0)
RD_FAILED(6);
if ((hostlocal=gethostbyaddr(insock.inp_laddr.S_un,
sizeof(insock.inp_laddr.S_un),0)) != NULL)
printf(" Local host-> %s:%d", hostlocal->h_name,insock.inp_lport);
else if (insock.inp_laddr.S_un.S_un_b.s_b1 != 0)
printf(" Host local-> %d.%d.%d.%d:%d",insock.inp_laddr.S_un.S_un_b.s_b1,
insock.inp_laddr.S_un.S_un_b.s_b2,
insock.inp_laddr.S_un.S_un_b.s_b3,
insock.inp_laddr.S_un.S_un_b.s_b4,insock.inp_lport);
if ((hostremoto=gethostbyaddr(insock.inp_faddr.S_un,
sizeof(insock.inp_faddr.S_un),0)) != NULL)
printf(" Remote host-> %s:%d", hostremoto->h_name,insock.inp_fport);
else if (insock.inp_faddr.S_un.S_un_b.s_b1 != 0)
printf(" Host remoto-> %d.%d.%d.%d:%d",insock.inp_faddr.S_un.S_un_b.s_b1,
insock.inp_faddr.S_un.S_un_b.s_b2,
insock.inp_faddr.S_un.S_un_b.s_b3,
insock.inp_faddr.S_un.S_un_b.s_b4,insock.inp_fport);
printf("\n");
}
}
}
struct fsid_tab **first_tab;
{
struct fsid_tab *current_tab, *ptr_tab;
FILE *fp, *setmntent();
struct mntent *mnt, *getmntent();
struct statfs statbuf;
if((fp = setmntent("/etc/mtab", "r")) == NULL) {
fprintf(stderr, "%s: setmntent failed\n", progname);
exit(1);
}
while((mnt = getmntent(fp)) != NULL) {
ptr_tab=(struct fsid_tab *)malloc(sizeof(struct fsid_tab));
if(ptr_tab == (struct fsid_tab *)0) {
fprintf(stderr, "%s: malloc failed\n", progname);
exit(1);
}
if(*first_tab == (struct fsid_tab *)0)
*first_tab = ptr_tab;
else
current_tab->next_tab = ptr_tab;
current_tab = ptr_tab;
strcpy(current_tab->dir, mnt->mnt_dir);
strncpy(current_tab->type, mnt->mnt_type, T_SIZ - 1);
current_tab->type[T_SIZ - 1] = '\0';
if(statfs(current_tab->dir, &statbuf) < 0) {
perror(progname);
exit(1);
}
current_tab->fsid.val[0] = statbuf.f_fsid.val[0];
current_tab->fsid.val[1] = statbuf.f_fsid.val[1];
current_tab->next_tab = (struct fsid_tab *)0;
}
if(ferror(fp)) {
fprintf(stderr, "%s: getmntent failed\n", progname);
exit(1);
}
find_table_entry(first_tab, fsid_ptr)
struct fsid_tab **first_tab;
fsid_t fsid_ptr;
{
struct fsid_tab *current_tab;
for(current_tab = *first_tab; current_tab != (struct fsid_tab *)0;
current_tab = current_tab->next_tab) {
if((current_tab->fsid.val[0] == fsid_ptr.val[0]) &&
(current_tab->fsid.val[1] == fsid_ptr.val[1]))
break;
}
return(current_tab);