"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/k_sunos57.c" (18 Jan 2000, 7340 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_sunos57.c" see the Fossies "Dox" file reference documentation.

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