"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/k_sunos56.c" (10 Aug 1999, 7280 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_sunos56.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** k_sunos56.c - SunOS 5.6 kernel access functions
    3 **
    4 ** Copyright (c) 1995-1997 Casper Dik <Casper.Dik@Holland.Sun.COM>
    5 ** Copyright (c) 1997-1998 Peter Eriksson <pen@lysator.liu.se>
    6 **
    7 ** This program is free software; you can redistribute it and/or
    8 ** modify it as you wish - as long as you don't claim that you wrote
    9 ** it.
   10 **
   11 ** This program is distributed in the hope that it will be useful,
   12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   14 */
   15 
   16 #include "config.h"
   17 
   18 #if 0
   19 #define DEBUGHASH
   20 #endif
   21 
   22 #define _KMEMUSER
   23 #define _KERNEL
   24 
   25 /* some definition conflicts. but we must define _KERNEL */
   26 
   27 #define exit        kernel_exit
   28 #define strsignal   kernel_strsignal
   29 #define mutex_init  kernel_mutex_init
   30 #define mutex_destroy   kernel_mutex_destroy
   31 #define sema_init   kernel_sema_init
   32 #define sema_destroy    kernel_sema_destroy
   33 
   34 #include <syslog.h>
   35 
   36 #include <sys/types.h>
   37 #include <sys/socket.h>
   38 #include <sys/signal.h>
   39 #include <sys/param.h>
   40 #include <netinet/in.h>
   41 
   42 #include <stdio.h>
   43 #include <kvm.h>
   44 #include <nlist.h>
   45 #include <math.h>
   46 #include <stddef.h>
   47 #include <sys/fcntl.h>
   48 #include <sys/cred.h>
   49 #include <sys/file.h>
   50 #include <sys/stream.h>
   51 #include <inet/common.h>
   52 #include <inet/ip.h>
   53 
   54 
   55 #define FANOUT_OFFSET(n)  (kip->nl[N_FANOUT].n_value + (n) * sizeof(icf_t) + offsetof(icf_t, icf_ipc))
   56 
   57 #undef exit
   58 #undef strsignal
   59 #undef mutex_init
   60 #undef mutex_destroy
   61 #undef sema_init
   62 #undef sema_destroy
   63 
   64 #undef SEMA_HELD
   65 #undef RW_LOCK_HELD
   66 #undef RW_READ_HELD
   67 #undef RW_WRITE_HELD
   68 #undef MUTEX_HELD
   69 
   70 #include <unistd.h>
   71 #include <string.h>
   72 #include <stddef.h>
   73 
   74 
   75 #include "pidentd.h"
   76 
   77 #define N_FANOUT 0
   78 
   79 struct kainfo
   80 {
   81     kvm_t *kd;
   82     struct nlist nl[2];
   83 };
   84 
   85 
   86 /*
   87 ** Make sure we are running on a supported OS version
   88 */
   89 int
   90 ka_init(void)
   91 {
   92     char osinfo_current[256];
   93 
   94     if (osinfo_get(osinfo_current) == NULL)
   95     return -1;
   96 
   97     return strcmp(osinfo_build, osinfo_current);
   98 }
   99 
  100 
  101 /*
  102 ** Open kernel devices, lookup kernel symbols etc... 
  103 */
  104 int
  105 ka_open(void **misc)
  106 {
  107     struct kainfo *kp;
  108 
  109 
  110     kp = s_malloc(sizeof(*kp));
  111     
  112     /*
  113     ** Open the kernel memory device
  114     */
  115     if ((kp->kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
  116     {
  117     syslog(LOG_ERR, "kvm_open: %m");
  118     s_free(kp);
  119     return -1;
  120     }
  121     
  122     
  123     kp->nl[0].n_name = "ipc_tcp_conn_fanout";
  124     kp->nl[1].n_name = NULL;
  125     
  126     /*
  127     ** Extract offsets to the needed variables in the kernel
  128     */
  129     if (kvm_nlist(kp->kd, kp->nl) != 0)
  130     {
  131     syslog(LOG_ERR, "kvm_nlist: %m");
  132     kvm_close(kp->kd);
  133     s_free(kp);
  134     return -1;
  135     }
  136 
  137     *misc = (void *) kp;
  138     return 0;
  139 }
  140 
  141 
  142 /*
  143 ** Get a piece of kernel memory with error handling.
  144 ** Returns 1 if call succeeded, else 0 (zero).
  145 */
  146 static int
  147 getbuf(kvm_t *kd, off_t addr, char *buf, size_t len, char *what)
  148 {
  149     int i;
  150     ssize_t status;
  151     
  152     
  153     i = 0;
  154     while (i < 5 && (status = kvm_read(kd, addr, buf, len)) < 0)
  155     ++i;
  156     
  157     if (status < 0)
  158     return 0;
  159     
  160     return 1;
  161 }
  162 
  163 
  164 /*
  165 ** Return the user number for the connection owner
  166 */
  167 int
  168 ka_lookup(void *vp, struct kernel *kp)
  169 {
  170     struct kainfo *kip;
  171     queue_t sqr;
  172     ipc_t ic, *icp;
  173     unsigned short uslp, usfp;
  174     unsigned int offset;
  175     file_t tf;
  176     unsigned long zero = 0;
  177     uint16_t *ports;
  178     uint32_t *locaddr, *raddr;
  179 #ifdef DEBUGHASH
  180     int i;
  181 #endif
  182     struct proc *procp;
  183     struct in_addr *faddr;
  184     int fport;
  185     struct in_addr *laddr;
  186     int lport;
  187     
  188     
  189     kip = (struct kainfo *) vp;
  190     
  191     faddr = &kp->remote.sin_addr;
  192     laddr = &kp->local.sin_addr;
  193     fport = kp->remote.sin_port;
  194     lport = kp->local.sin_port;
  195     
  196     usfp = fport;
  197     uslp = lport;
  198     
  199     offset = usfp ^ uslp;
  200     offset ^= (unsigned) faddr->S_un.S_un_b.s_b4 ^ (offset >> 8);
  201     offset &= 0xff;
  202     
  203     if (!getbuf(kip->kd, (off_t) FANOUT_OFFSET(offset),
  204         (char *) &icp,
  205         sizeof(ipc_t *),
  206         "ipc_tcp_fanout[offset]"))
  207     return -1;
  208     
  209 #ifndef DEBUGHASH
  210     if (icp == NULL)
  211     {
  212     syslog(LOG_DEBUG, "ka_lookup: hash miss");
  213     return -1;
  214     }
  215 #endif
  216     
  217     locaddr = (uint32_t *) &ic.ipc_laddr;
  218     raddr = (uint32_t *) &ic.ipc_faddr;
  219     ports = (uint16_t *) &ic.ipc_ports;
  220     
  221 #ifdef DEBUGHASH
  222     for (i = 0; i < 256; i++)
  223     {
  224     if (!getbuf(kip->kd, (off_t) FANOUT_OFFSET(i),
  225             (char *) &icp,
  226             sizeof(ipc_t *),
  227             "ipc_tcp_fanout[offset]"))
  228         return -1;
  229     if (icp == NULL)
  230         continue;
  231 #endif
  232     
  233     while (icp != NULL)
  234     {
  235         if (!getbuf(kip->kd, (off_t) icp,
  236             (char *) &ic,
  237             sizeof(ic),
  238             "hash entry"))
  239         return -1;
  240         
  241         if (usfp == ports[0] && /* remote port */
  242         uslp == ports[1] && /* local port */
  243 #if 0
  244         memcmp(&laddr->s_addr, locaddr, 4) == 0 && /* local */
  245 #else
  246         (memcmp(&laddr->s_addr, locaddr, 4) == 0 ||
  247          /* In SunOS 5.3, the local part can be all zeros */
  248          memcmp(&zero, locaddr, 4) == 0) /* local */ &&
  249 #endif
  250         memcmp(&faddr->s_addr, raddr, 4) == 0)
  251         break;
  252         icp = ic.ipc_hash_next;
  253     }
  254 #ifdef DEBUGHASH
  255     if (icp != NULL)
  256         break;
  257     } /* for i */
  258     if (icp != NULL)
  259     printf("found, offset = %x, i = %x, i ^ offset = %x\n", offset, i,
  260     offset ^ i);
  261 #endif
  262     
  263     if (icp == NULL)
  264     {
  265     syslog(LOG_INFO, "ka_lookup: port not found");
  266     return 0;
  267     }
  268     
  269     if (!getbuf(kip->kd, (off_t) ic.ipc_rq+offsetof(queue_t, q_stream),
  270         (char *) &sqr.q_stream,
  271         sizeof(sqr.q_stream),
  272         "queue.q_stream"))
  273     return -1;
  274     
  275     /* at this point sqr.q_stream holds the pointer to the stream we're
  276        interested in. Now we're going to find the file pointer
  277        that refers to the vnode that refers to this stream stream */
  278     
  279     
  280     if (kvm_setproc(kip->kd) != 0)
  281     return -1;
  282     
  283     while ((procp = kvm_nextproc(kip->kd)) != NULL)
  284     {
  285     struct uf_entry files[NFPCHUNK];
  286     int nfiles = procp->p_user.u_nofiles;
  287     off_t addr = (off_t) procp->p_user.u_flist;
  288     
  289     while (nfiles > 0)
  290     {
  291         int nread = nfiles > NFPCHUNK ? NFPCHUNK : nfiles;
  292         int size = nread * sizeof(struct uf_entry);
  293         int i;
  294         struct file *last = NULL;
  295         vnode_t vp;
  296         
  297         if (!getbuf(kip->kd, addr, (char *) &files[0], size, "ufentries"))
  298         {
  299         return -1;
  300         }
  301         
  302         for (i = 0; i < nread; i++)
  303         {
  304         if (files[i].uf_ofile == 0 || files[i].uf_ofile == last)
  305             continue;
  306         if (!getbuf(kip->kd, (off_t) (last = files[i].uf_ofile),
  307                 (char *) &tf, sizeof(tf), "file pointer"))
  308         {
  309             return -1;
  310         }
  311         
  312         if (tf.f_vnode == NULL)
  313             continue;
  314         
  315         if (!getbuf(kip->kd, (off_t) tf.f_vnode +
  316                 offsetof(vnode_t, v_stream),
  317                 (char *) &vp.v_stream,
  318                 sizeof(vp.v_stream), "vnode.v_stream"))
  319             return -1;
  320         
  321         if (vp.v_stream == sqr.q_stream)
  322         {
  323             cred_t cr;
  324             struct pid p;
  325             
  326             if (!getbuf(kip->kd,
  327                 (off_t) tf.f_cred,
  328                 (char *) &cr,
  329                 sizeof(cr),
  330                 "cred"))
  331             return -1;
  332             
  333             kp->ruid = cr.cr_ruid;
  334             kp->euid = cr.cr_uid;
  335             
  336             if (getbuf(kip->kd,
  337                    (off_t) procp->p_pidp,
  338                    (char *) &p,
  339                    sizeof(struct pid),
  340                    "pidp"))
  341             {
  342             kp->pid = p.pid_id;
  343             /* get cmd */
  344             kp->cmd = s_strdup(procp->p_user.u_comm);
  345             /* get cmd args */
  346             kp->argv = s_strdup(procp->p_user.u_psargs);
  347             }
  348             
  349             return 1;
  350         }
  351         }
  352         nfiles -= nread;
  353         addr += size;
  354     }
  355     }
  356     
  357     return 0;
  358 }