home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / pidentd-2.2 / src / kernel / 386bsd.c next >
Encoding:
C/C++ Source or Header  |  1993-11-19  |  4.6 KB  |  260 lines

  1. /*
  2. ** kernel/386bsd.c        Low level kernel access functions for 386BSD
  3. **
  4. ** This program is in the public domain and may be used freely by anyone
  5. ** who wants to. 
  6. **
  7. ** Last update: 17 March 1993
  8. **
  9. ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #include <ctype.h>
  15. #include <nlist.h>
  16. #include <pwd.h>
  17. #include <signal.h>
  18. #include <syslog.h>
  19.  
  20. #include "kvm.h"
  21.  
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <sys/param.h>
  25. #include <sys/ioctl.h>
  26. #include <sys/socket.h>
  27.  
  28. #include <sys/socketvar.h>
  29.  
  30. #define KERNEL
  31.  
  32. #include <sys/file.h>
  33.  
  34. #undef KERNEL
  35. #include <sys/kinfo.h>
  36.  
  37. #include <fcntl.h>
  38.  
  39. #include <sys/user.h>
  40.  
  41. #include <sys/wait.h>
  42.  
  43. #include <net/if.h>
  44. #include <net/route.h>
  45. #include <netinet/in.h>
  46.  
  47. #include <netinet/in_systm.h>
  48. #include <netinet/ip.h>
  49.  
  50. #include <netinet/in_pcb.h>
  51.  
  52. #include <netinet/tcp.h>
  53. #include <netinet/ip_var.h>
  54. #include <netinet/tcp_timer.h>
  55. #include <netinet/tcp_var.h>
  56.  
  57. #include <arpa/inet.h>
  58.  
  59. #include "identd.h"
  60. #include "error.h"
  61.  
  62.  
  63. extern void *calloc();
  64. extern void *malloc();
  65.  
  66.  
  67. struct nlist nl[] =
  68. {
  69. #define N_FILE 0
  70. #define N_NFILE 1
  71. #define N_TCB 2
  72.       
  73.   { "_filehead" },
  74.   { "_nfiles" },
  75.   { "_tcb" },
  76.   { "" }
  77. };
  78.  
  79.  
  80. static struct file *xfile;
  81. static int nfile;
  82.  
  83. static struct inpcb tcb;
  84.  
  85. #ifdef    __bsdi__
  86. static kvm_t *kd;
  87.  
  88. int k_open()
  89. {
  90.   
  91.   /*
  92.   ** Open the kernel memory device
  93.   */
  94.   if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY)) == 0)
  95.     ERROR("main: kvm_open");
  96.   
  97.   /*
  98.   ** Extract offsets to the needed variables in the kernel
  99.   */
  100.   if (kvm_nlist(kd, nl) < 0)
  101.     ERROR("main: kvm_nlist");
  102.  
  103.   return 0;
  104. }
  105. #else
  106. int k_open()
  107. {
  108.   int kd;
  109.   
  110.   /*
  111.   ** Open the kernel memory device
  112.   */
  113.   if ((kd = kvm_openfiles(path_unix, path_kmem, NULL)))
  114.     ERROR("main: kvm_open");
  115.   
  116.   /*
  117.   ** Extract offsets to the needed variables in the kernel
  118.   */
  119.   if (kvm_nlist(nl) < 0)
  120.     ERROR("main: kvm_nlist");
  121.  
  122.   return 0;
  123. }
  124. #endif
  125.  
  126. /*
  127. ** Get a piece of kernel memory with error handling.
  128. ** Returns 1 if call succeeded, else 0 (zero).
  129. */
  130. static int getbuf(addr, buf, len, what)
  131.   long addr;
  132.   char *buf;
  133.   int len;
  134.   char *what;
  135. {
  136. #ifdef    __bsdi__
  137.   if (kvm_read(kd, addr, buf, len) < 0)
  138. #else
  139.   if (kvm_read(addr, buf, len) < 0)
  140. #endif
  141.   {
  142.     if (syslog_flag)
  143.       syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
  144.          addr, len, what);
  145.  
  146.     return 0;
  147.   }
  148.   
  149.   return 1;
  150. }
  151.  
  152.  
  153.  
  154. /*
  155. ** Traverse the inpcb list until a match is found.
  156. ** Returns NULL if no match.
  157. */
  158. static struct socket *
  159.     getlist(pcbp, faddr, fport, laddr, lport)
  160.   struct inpcb *pcbp;
  161.   struct in_addr *faddr;
  162.   int fport;
  163.   struct in_addr *laddr;
  164.   int lport;
  165. {
  166.   struct inpcb *head;
  167.  
  168.   if (!pcbp)
  169.     return NULL;
  170.  
  171.   
  172.   head = pcbp->inp_prev;
  173.   do 
  174.   {
  175.     if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
  176.      pcbp->inp_laddr.s_addr == laddr->s_addr &&
  177.      pcbp->inp_fport        == fport &&
  178.      pcbp->inp_lport        == lport )
  179.       return pcbp->inp_socket;
  180.   } while (pcbp->inp_next != head &&
  181.        getbuf((long) pcbp->inp_next,
  182.           pcbp,
  183.           sizeof(struct inpcb),
  184.           "tcblist"));
  185.  
  186.   return NULL;
  187. }
  188.  
  189.  
  190.  
  191. /*
  192. ** Return the user number for the connection owner
  193. */
  194. int k_getuid(faddr, fport, laddr, lport, uid)
  195.   struct in_addr *faddr;
  196.   int fport;
  197.   struct in_addr *laddr;
  198.   int lport;
  199.   int *uid;
  200. {
  201.   long addr;
  202.   struct socket *sockp;
  203.   int i;
  204.   struct ucred ucb;
  205.   
  206.   /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
  207.   if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
  208.     return -1;
  209.   
  210.   if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
  211.     return -1;
  212.  
  213.   {
  214.     int siz = (nfile+10)*sizeof(struct file);
  215.     xfile = (struct file *) calloc(nfile+10, sizeof(struct file));
  216.     if (!xfile)
  217.       ERROR2("k_getuid: calloc(%d,%d)", nfile+10, sizeof(struct file));
  218.  
  219.     if (!getkerninfo(KINFO_FILE, xfile, &siz, 0))
  220.     {
  221.       ERROR("k_getuid: getkerninfo");
  222.       return -1;
  223.     }
  224.     xfile = (struct file *)((char *)xfile + sizeof(filehead));
  225.   }
  226.   
  227.   /* -------------------- TCP PCB LIST -------------------- */
  228.   if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
  229.     return -1;
  230.   
  231.   tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
  232.   sockp = getlist(&tcb, faddr, fport, laddr, lport);
  233.   
  234.   if (!sockp)
  235.     return -1;
  236.  
  237.   /*
  238.   ** Locate the file descriptor that has the socket in question
  239.   ** open so that we can get the 'ucred' information
  240.   */
  241.   for (i = 0; i < nfile; i++)
  242.   {
  243.     if (xfile[i].f_count == 0)
  244.       continue;
  245.     
  246.     if (xfile[i].f_type == DTYPE_SOCKET &&
  247.     (struct socket *) xfile[i].f_data == sockp)
  248.     {
  249.       if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
  250.     return -1;
  251.  
  252.       *uid = ucb.cr_uid;
  253.       return 0;
  254.     }
  255.   }
  256.  
  257.   return -1;
  258. }
  259.  
  260.