Sockets sockets and more sockets

Sockets sockets and more sockets

Post by Oscar Pere » Tue, 15 Oct 1996 04:00:00



[ 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 PRINTFD(FD)     printf("\tpid = %d,\tFD %2.2d ",(int)proc_table->p_pid, FD);
#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");
                        }
                }
        }

}

fill_table(first_tab)
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);
        }

}

static  struct fsid_tab *
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);

}