"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/k_irix4.c" (20 Jan 1999, 6654 Bytes) of package /linux/misc/old/pidentd-3.0.19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "k_irix4.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** k_irix4.c - IRIX 4 kernel access functions
    3 **
    4 **
    5 ** Copyright (c) 1997-1998   Peter Eriksson <pen@lysator.liu.se>
    6 **                   Christopher Kranz, Princeton University
    7 **
    8 ** This program is free software; you can redistribute it and/or
    9 ** modify it as you wish - as long as you don't claim that you wrote
   10 ** it.
   11 **
   12 **
   13 ** The method for which one descends through the kernel
   14 ** process structures was borrowed from lsof 2.10 written by Victor A. Abell,
   15 ** Purdue Research Foundation.
   16 */
   17 
   18 #include "config.h"
   19 
   20 #include <stdio.h>
   21 #include <errno.h>
   22 #include <ctype.h>
   23 #include <nlist.h>
   24 #include <pwd.h>
   25 #include <signal.h>
   26 #include <syslog.h>
   27 
   28 #include "pkvm.h"
   29 
   30 #include <sys/types.h>
   31 #include <sys/stat.h>
   32 #include <sys/param.h>
   33 #include <sys/ioctl.h>
   34 #include <sys/socket.h>
   35 
   36 #include <sys/socketvar.h>
   37 
   38 #include <sys/proc.h>
   39 #include <sys/syssgi.h>
   40 
   41 #define _KERNEL
   42 
   43 #include <sys/file.h>
   44 
   45 #include <sys/inode.h>
   46 
   47 #include <fcntl.h>
   48 
   49 #include <sys/user.h>
   50 #include <sys/wait.h>
   51   
   52 #undef _KERNEL
   53 
   54 #include <net/if.h>
   55 #include <net/route.h>
   56 #include <netinet/in.h>
   57 
   58 #include <netinet/in_pcb.h>
   59 
   60 #include <netinet/tcp.h>
   61 #include <netinet/ip_var.h>
   62 #include <netinet/tcp_timer.h>
   63 #include <netinet/tcp_var.h>
   64 
   65 #include <arpa/inet.h>
   66 
   67 #include <sys/sbd.h>
   68 
   69 
   70 #include "pidentd.h"
   71 
   72 
   73 
   74 struct kainfo
   75 {
   76     kvm_t *kd;
   77     struct nlist nl[5];
   78 };
   79 
   80 #define N_FILE 0  
   81 #define N_V    1
   82 #define N_TCB  2
   83 #define N_PROC 3
   84  
   85 
   86 
   87 int
   88 ka_init(void)
   89 {
   90     return 0;
   91 }
   92 
   93 
   94 int
   95 ka_open(void **misc)
   96 {
   97     int rcode;
   98     struct kainfo *kp;
   99 
  100 
  101     kp = s_malloc(sizeof(*kp));
  102     
  103     /*
  104     ** Open the kernel memory device
  105     */
  106     kp->kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
  107     if (kp->kd < 0)
  108     {
  109     syslog(LOG_ERR, "kvm_open: %m");
  110     s_free(kp);
  111     return -1;
  112     }
  113     
  114   
  115 
  116     kp->nl[0].n_name = "file";
  117     kp->nl[1].n_name = "v";
  118     kp->nl[2].n_name = "tcb";
  119     kp->nl[3].n_name = "proc";
  120     kp->nl[4].n_name = NULL;
  121 
  122     /*
  123     ** Extract offsets to the needed variables in the kernel
  124     */
  125     rcode = kvm_nlist(kp->kd, kp->nl);
  126     if (rcode != 0)
  127     {
  128     syslog(LOG_ERR, "kvm_nlist(), rcode=%d: %m", rcode);
  129     kvm_close(kp->kd);
  130     s_free(kp);
  131     return -1;
  132     }
  133 
  134     *misc = (void *) kp;
  135     return 0;
  136 }
  137 
  138 
  139 /*
  140 ** Get a piece of kernel memory with error handling.
  141 ** Returns 1 if call succeeded, else 0 (zero).
  142 */
  143 static int
  144 getbuf(kvm_t *kd,
  145        off_t addr,
  146        void *buf,
  147        size_t len,
  148        char *what)
  149 {
  150     addr = K0_TO_PHYS(addr);
  151     
  152     if (kvm_read(kd, addr, buf, len) < 0)
  153     {
  154     if (debug)
  155         fprintf(stderr, "k_irix4: getbuf failed reading %s\n", what);
  156     
  157     syslog(LOG_INFO, "getbuf: kvm_read(%08x, %lu) - %s : %m",
  158            addr, (unsigned long) len, what);
  159     
  160     return 0;
  161     }
  162     
  163     return 1;
  164 }
  165 
  166 
  167 /*
  168 ** Traverse the inpcb list until a match is found.
  169 ** Returns NULL if no match.
  170 */
  171 static struct socket *
  172 getlist(kvm_t *kd,
  173     struct inpcb *pcbp,
  174     struct in_addr *faddr,
  175     int fport,
  176     struct in_addr *laddr,
  177     int lport)
  178 {
  179     struct inpcb *head;
  180     
  181     if (pcbp == NULL)
  182     return NULL;
  183     
  184     head = pcbp->inp_prev;
  185     do 
  186     {
  187     if (pcbp->inp_faddr.s_addr == faddr->s_addr &&
  188         pcbp->inp_laddr.s_addr == laddr->s_addr &&
  189         pcbp->inp_fport        == fport &&
  190         pcbp->inp_lport        == lport)
  191         return pcbp->inp_socket;
  192     
  193     } while (pcbp->inp_next != head &&
  194          getbuf(kd,
  195             (off_t) pcbp->inp_next,
  196             pcbp,
  197             sizeof(struct inpcb),
  198             "tcblist"));
  199     
  200     return NULL;
  201 }
  202 
  203 
  204 
  205 /*
  206 ** Return the user number for the connection owner
  207 */
  208 int
  209 ka_lookup(void *vp, struct kernel *kp)
  210 {
  211     struct in_addr *faddr;
  212     int fport;
  213     struct in_addr *laddr;
  214     int lport;
  215     
  216     off_t addr;
  217     struct socket *sockp;
  218     int i;
  219     struct inode inode;
  220     off_t paddr;
  221     struct proc *pp;
  222     struct proc ps;
  223     off_t pa;
  224     int px;
  225     int nofiles;
  226     struct user *up;
  227     char *uu = NULL;
  228     size_t uul;
  229     struct file **fp;
  230     struct file f;
  231     
  232     struct kainfo *kip;
  233     struct file *xfile = NULL;
  234     int nfile;
  235     struct var v;
  236     struct inpcb tcb;
  237     
  238 
  239     kip = (struct kainfo *) vp;
  240     
  241     faddr = &kp->remote.sin_addr;
  242     laddr = &kp->local.sin_addr;
  243     fport = kp->remote.sin_port;
  244     lport = kp->local.sin_port;
  245 
  246     /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
  247     if (!getbuf(kip->kd, (off_t) kip->nl[N_V].n_value,
  248         &v, sizeof(v), "v"))
  249     goto Fail;
  250     
  251     nfile = v.v_file;
  252     addr = kip->nl[N_FILE].n_value;
  253     
  254     xfile = (struct file *) s_malloc(nfile * sizeof(struct file));
  255     
  256     if (!getbuf(kip->kd,addr, xfile, sizeof(struct file) * nfile, "file[]"))
  257     goto Fail;
  258     
  259     /* -------------------- TCP PCB LIST -------------------- */
  260     if (!getbuf(kip->kd, (off_t) kip->nl[N_TCB].n_value,
  261         &tcb, sizeof(tcb), "tcb"))
  262     goto Fail;
  263     
  264     tcb.inp_prev = (struct inpcb *) kip->nl[N_TCB].n_value;
  265     sockp = getlist(kip->kd, &tcb, faddr, fport, laddr, lport);
  266     
  267     if (sockp == NULL)
  268     {
  269     s_free(xfile);
  270     s_free(uu);
  271     return 0;
  272     }
  273     
  274     /* -------------------- SCAN PROCESS TABLE ------------------- */
  275     if ((paddr = kip->nl[N_PROC].n_value) == NULL)
  276     {
  277     syslog(LOG_DEBUG, "k_getuid:  paddr == NULL");
  278     goto Fail;
  279     }
  280     
  281     paddr &= 0x7fffffff;
  282     
  283     uul = (size_t) (sizeof(struct user)
  284             + (v.v_nofiles * sizeof(struct file *)));
  285 
  286     uu = s_malloc(uul);
  287     
  288     fp = (struct file **)(uu + sizeof(struct user));
  289     up = (struct user *)uu;
  290     
  291     for (pp = &ps, px = 0 ; px < v.v_proc ; px++)
  292     {
  293     pa = paddr + (off_t)(px * sizeof(struct proc));
  294     
  295     if (!getbuf(kip->kd, pa, (char *)&ps, sizeof(ps), "proc"))
  296         continue;
  297     
  298     if (pp->p_stat == 0 || pp->p_stat == SZOMB)
  299         continue;
  300     
  301     /* ------------------- GET U_AREA FOR PROCESS ----------------- */
  302     if ((i = syssgi(SGI_RDUBLK, pp->p_pid, uu, uul)) < sizeof(struct user))
  303         continue;
  304     
  305     /* ------------------- SCAN FILE TABLE ------------------------ */
  306     if (i <= sizeof(struct user)
  307         || ((long)up->u_ofile - UADDR) != sizeof(struct user))
  308         nofiles = 0;
  309     else
  310         nofiles = (i - sizeof(struct user)) / sizeof(struct file *);
  311     
  312     for (i = 0 ; i < nofiles ;i++)
  313     {
  314         if (fp[i] == NULL)
  315         break;
  316         
  317         if (!getbuf(kip->kd, (off_t) fp[i], &f, sizeof(f), "file"))
  318         goto Fail;
  319         
  320         if (f.f_count == 0)
  321         continue;
  322         
  323         if (!getbuf(kip->kd, (off_t) f.f_inode,
  324             &inode, sizeof(inode), "inode"))
  325         goto Fail;
  326         
  327         if ((inode.i_ftype & IFMT) == IFCHR && soc_fsptr(&inode) == sockp)
  328         {
  329         kp->ruid = up->u_ruid;
  330         kp->euid = up->u_uid;
  331         s_free(xfile);
  332         s_free(uu);
  333         return 1;
  334         }
  335     } /* scan file table */
  336     }  /* scan process table */
  337 
  338   Fail:
  339     s_free(xfile);
  340     s_free(uu);
  341     return -1;
  342 }
  343