"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/k_next_mach.c" (20 Jan 1999, 5423 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_next_mach.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** k_next_mach.c - NeXTstep 3 kernel access functions.
    3 **
    4 ** This program is in the public domain and may be used freely by anyone
    5 ** who wants to. 
    6 **
    7 ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
    8 */
    9 
   10 #include "config.h"
   11 
   12 #include <stdio.h>
   13 #include <errno.h>
   14 #include <ctype.h>
   15 #include <sys/types.h>
   16 #include <sys/param.h>
   17 #include <netdb.h>
   18 #include <nlist.h>
   19 #include <pwd.h>
   20 #include <signal.h>
   21 #include <syslog.h>
   22 
   23 #include "pkvm.h"
   24 
   25 #include <sys/socket.h>
   26 #include <sys/socketvar.h>
   27 
   28 #include <sys/ioctl.h>
   29 
   30 /* FIXME: check for features?  */
   31 #ifndef NeXT31
   32 #  define KERNEL
   33 #  define KERNEL_FEATURES 
   34 #else
   35 #  define KERNEL_FILE
   36 #endif
   37 
   38 #include <sys/file.h>
   39 
   40 #ifndef NeXT31
   41 #  undef KERNEL
   42 #  undef KERNEL_FEATURES 
   43 #else
   44 #  undef KERNEL_FILE
   45 #endif
   46 
   47 #include <sys/user.h>
   48 
   49 #include <net/if.h>
   50 #include <net/route.h>
   51 #include <netinet/in.h>
   52 #include <netinet/in_systm.h>
   53 #include <netinet/ip.h>
   54 #include <netinet/tcp.h>
   55 #include <netinet/tcp_timer.h>
   56 #include <netinet/tcp_var.h>
   57 
   58 #include <netinet/in_pcb.h>
   59 #include <netinet/ip_var.h>
   60 
   61 #include "pidentd.h"
   62 
   63 
   64 struct kainfo
   65 {
   66     kvm_t *kd;
   67     struct nlist nl[4];
   68 };
   69 
   70 
   71 #define N_FILE 0  
   72 #define N_NFILE 1
   73 #define N_TCB 2
   74 
   75 
   76 
   77 
   78 int
   79 ka_init(void)
   80 {
   81 #if 0
   82     char osinfo_current[256];
   83 
   84     if (osinfo_get(osinfo_current) == NULL)
   85     return -1;
   86 
   87     return strcmp(osinfo_build, osinfo_current);
   88 #endif
   89     return 0;
   90 }
   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     if ((kp->kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
  107     {
  108     if (debug)
  109         perror("kvm_open");
  110 
  111     syslog(LOG_ERR, "kvm_open: %m");
  112     s_free(kp);
  113     return -1;
  114     }
  115 
  116     kp->nl[0].n_un.n_name = "_file_list";
  117     kp->nl[1].n_un.n_name = "_max_file";
  118     kp->nl[2].n_un.n_name = "_tcb";
  119     kp->nl[3].n_un.n_name = NULL;
  120     
  121     /*
  122     ** Extract offsets to the needed variables in the kernel
  123     */
  124     if ((rcode = kvm_nlist(kp->kd, kp->nl)) != 0)
  125     {
  126     if (debug)
  127         fprintf(stderr, "kvm_nlist: returned %d\n", rcode);
  128 
  129     syslog(LOG_ERR, "kvm_nlist, rcode = %d: %m", rcode);
  130     kvm_close(kp->kd);
  131     s_free(kp);
  132     return -1;
  133     }
  134 
  135     *misc = (void *) kp;
  136     return 0;
  137 }
  138 
  139 
  140 /*
  141 ** Get a piece of kernel memory with error handling.
  142 ** Returns 1 if call succeeded, else 0 (zero).
  143 */
  144 static int
  145 getbuf(kvm_t *kd,
  146        off_t addr,
  147        void *buf,
  148        size_t len,
  149        char *what)
  150 {
  151     if (kvm_read(kd, addr, buf, len) < 0)
  152     {
  153     syslog(LOG_INFO, "getbuf: kvm_read(%08x, %lu) - %s : %m",
  154            addr, (unsigned long) len, what);
  155     
  156     return 0;
  157     }
  158     
  159     return 1;
  160 }
  161 
  162 
  163 
  164 /*
  165 ** Traverse the inpcb list until a match is found 
  166 ** Returns NULL if no match.
  167 */
  168 
  169 static struct socket *
  170 getlist(kvm_t *kd,
  171     struct inpcb *pcbp,
  172     struct in_addr *faddr,
  173     int fport,
  174     struct in_addr *laddr,
  175     int lport)
  176 {
  177     struct inpcb *head;
  178     int limiter = 65536;
  179   
  180     if (pcbp == NULL)
  181     return NULL;        /* Someone gave us a duff one here */
  182   
  183     head = pcbp->inp_prev;
  184     do
  185     {
  186         if (pcbp->inp_faddr.s_addr == faddr->s_addr &&
  187         pcbp->inp_laddr.s_addr == laddr->s_addr &&
  188         pcbp->inp_fport        == fport &&
  189         pcbp->inp_lport        == lport)
  190         return pcbp->inp_socket;
  191 
  192     if (--limiter <= 0)
  193         break;    
  194 
  195     } while (pcbp->inp_next != head &&
  196          getbuf(kd, (off_t) pcbp->inp_next, 
  197                    pcbp, sizeof(struct inpcb), "tcblist"));
  198 
  199     return NULL;            /* Not found */
  200 }
  201 
  202 
  203 /*
  204 ** Return the user number for the connection owner
  205 */
  206 int
  207 ka_lookup(void *vp, struct kernel *kp)
  208 {
  209     struct in_addr *faddr;
  210     int fport;
  211     struct in_addr *laddr;
  212     int lport;
  213 
  214     struct kainfo *kip;
  215     struct ucred ucb;
  216     struct socket *sockp;
  217     int nfile;
  218     struct inpcb tcb;
  219     struct file file_entry;
  220     void *addr;
  221 
  222     kip = (struct kainfo *) vp;
  223 
  224     faddr = &kp->remote.sin_addr;
  225     laddr = &kp->local.sin_addr;
  226     fport = kp->remote.sin_port;
  227     lport = kp->local.sin_port;
  228     
  229     /* -------------------- TCP PCB LIST -------------------- */
  230     if (!getbuf(kip->kd,
  231         (off_t) kip->nl[N_TCB].n_value,
  232         &tcb, sizeof(tcb), "tcb"))
  233     return -1;
  234       
  235     tcb.inp_prev = (struct inpcb *) kip->nl[N_TCB].n_value;
  236     sockp = getlist(kip->kd, &tcb, faddr, fport, laddr, lport);
  237 
  238     if (sockp == NULL)
  239     return 0;
  240 
  241     /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
  242     /* So now we hit the fun Mach kernel structures */
  243     if (!getbuf(kip->kd,
  244         (off_t) kip->nl[N_FILE].n_value,
  245         &addr, sizeof(addr), "&file_table"))
  246     return -1;
  247       
  248     /* We only use nfile as a failsafe in case something goes wrong! */
  249     if (!getbuf(kip->kd,
  250         (off_t) kip->nl[N_NFILE].n_value,
  251         &nfile, sizeof(nfile), "nfile"))
  252     return -1;
  253       
  254     file_entry.links.next = addr;
  255     /* ------------------- SCAN FILE TABLE ------------------------ */
  256     do
  257     {
  258     if (!getbuf(kip->kd,
  259             (off_t) file_entry.links.next,
  260             &file_entry, sizeof(file_entry), "struct file"))
  261         return -1;
  262      
  263     if (file_entry.f_count == 0)
  264         continue;
  265 
  266     if (file_entry.f_type == DTYPE_SOCKET &&
  267         (struct socket *) file_entry.f_data == sockp)
  268     {
  269         if (!getbuf(kip->kd,
  270             (off_t) file_entry.f_cred, 
  271                     &ucb, sizeof(ucb), "ucb"))
  272         return -1;
  273            
  274         kp->ruid = ucb.cr_ruid;
  275         kp->euid = ucb.cr_uid;
  276 
  277         return 1;
  278     }
  279     } while ((file_entry.links.next != addr) && (--nfile));
  280 
  281     return -1;
  282 }