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 / svr4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  7.1 KB  |  344 lines

  1. /*
  2. ** kernel/svr4.c                    SVR4 specific 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. ** Last update: 17 March 1993
  8. **
  9. ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
  10. */
  11.  
  12. #define STRNET
  13.  
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #include <ctype.h>
  17. #include <nlist.h>
  18. #include <pwd.h>
  19. #include <signal.h>
  20. #include <syslog.h>
  21.  
  22. #  include "kvm.h"
  23.  
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <sys/param.h>
  27. #include <sys/ioctl.h>
  28. #include <sys/socket.h>
  29.  
  30. #include <sys/socketvar.h>
  31.  
  32. #define KERNEL
  33.  
  34. #include <sys/file.h>
  35.  
  36. #include <fcntl.h>
  37.  
  38. #include <unistd.h>
  39. #include <sys/fcntl.h>
  40. #include <sys/stream.h>
  41. #include <sys/stat.h>
  42. #include <sys/cred.h>
  43. #include <sys/vnode.h>
  44. #include <sys/mkdev.h>
  45. #define ucred cred
  46.  
  47. #include <sys/wait.h>
  48.   
  49. #undef KERNEL
  50.  
  51. #include <net/if.h>
  52. #include <net/route.h>
  53. #include <netinet/in.h>
  54.  
  55. #ifndef ATTSVR4
  56. #include <netinet/in_pcb.h>
  57. #endif
  58.  
  59. #include <netinet/tcp.h>
  60. #include <netinet/ip_var.h>
  61. #include <netinet/tcp_timer.h>
  62. #include <netinet/tcp_var.h>
  63.  
  64. #include <arpa/inet.h>
  65.  
  66. #include "identd.h"
  67. #include "error.h"
  68.  
  69.  
  70. extern void *calloc();
  71. extern void *malloc();
  72.  
  73.  
  74. struct nlist nl[] =
  75. {
  76. #ifndef ATTSVR4
  77.       
  78. #define N_FILE  0
  79. #define N_TCB 1
  80.       
  81.   { "file" },
  82.   { "tcb" },
  83.  
  84. #else                   /* AT&T's hacked version below */
  85.  
  86. #define N_FILE  0
  87. #define N_TCPD 1
  88. #define N_TCPD_CNT 2
  89.  
  90.   { "file" },
  91.   { "tcpd" },
  92.   { "tcpd_cnt" },
  93. #endif            /* ATTSVR4 */
  94.   
  95.   { "" }
  96. };
  97.  
  98. static kvm_t *kd;
  99.  
  100. #ifndef ATTSVR4
  101. static struct inpcb tcb;
  102. #endif
  103.  
  104. #ifdef ATTSVR4
  105. static struct tcpd tcpd;    /* we will read this one at a time */
  106. static int tcpd_cnt;            /* # of tcpd's we have */
  107. #endif
  108.  
  109.  
  110. int k_open()
  111. {
  112.   /*
  113.   ** Open the kernel memory device
  114.   */
  115.   if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
  116.     ERROR("main: kvm_open");
  117.   
  118.   /*
  119.   ** Extract offsets to the needed variables in the kernel
  120.   */
  121.   if (kvm_nlist(kd, nl) != 0)
  122.     ERROR("main: kvm_nlist");
  123.  
  124.   return 0;
  125. }
  126.  
  127.  
  128. /*
  129. ** Get a piece of kernel memory with error handling.
  130. ** Returns 1 if call succeeded, else 0 (zero).
  131. */
  132. static int getbuf(addr, buf, len, what)
  133.   long addr;
  134.   char *buf;
  135.   int len;
  136.   char *what;
  137. {
  138.   if (kvm_read(kd, addr, buf, len) < 0)
  139.   {
  140.     if (syslog_flag)
  141.       syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
  142.          addr, len, what);
  143.  
  144.     return 0;
  145.   }
  146.   
  147.   return 1;
  148. }
  149.  
  150.  
  151.  
  152. /*
  153. ** Traverse the inpcb list until a match is found.
  154. ** Returns NULL if no match.
  155. */
  156. static short
  157.     getlist(pcbp, faddr, fport, laddr, lport)
  158. #ifdef ATTSVR4
  159.   struct tcpd *pcbp;
  160. #else
  161.   struct inpcb *pcbp;
  162. #endif
  163.   struct in_addr *faddr;
  164.   int fport;
  165.   struct in_addr *laddr;
  166.   int lport;
  167. {
  168. #ifdef ATTSVR4
  169.   struct tcpcb *head;
  170.   struct tcpcb tcpcb;
  171.   int i;
  172.   int address_of_tcpcb;
  173. #else  
  174.   struct inpcb *head;
  175. #endif
  176.  
  177.   if (!pcbp)
  178.     return -1;
  179.  
  180. #ifdef ATTSVR4
  181.   i = 0;    /* because we have already read 1 we inc later of the struct */
  182.   do
  183.   {
  184.     /* don't ask be why (HACK) but the forth element that td_tcpcb
  185.     ** points to contains the address of the tcpcb
  186.     ** the struct is struct msgb which is a bunch of pointers
  187.     ** to arrays (in <sys/stream.h> and the fouth element of the
  188.     ** struct seems to always have the address...there is no comments
  189.     ** in the .h files to indict why this is, and since I don't have
  190.     ** source I don't know why....I found this info using crash looking
  191.     ** around the structure tcpd, using the command 'od -x address count'
  192.     **
  193.     ** I assume that this would change....but it seems to work on AT&T SVR4.0
  194.     ** Rel. 2.1
  195.     **
  196.     ** Bradley E. Smith <brad@bradley.bradley.edu>
  197.     */
  198.     if (!getbuf( (long) pcbp->td_tcpcb + (3 * sizeof(int)),
  199.         &address_of_tcpcb, sizeof(int), "&address_of_tcpcb") )
  200.     {
  201.       return -1;
  202.     }
  203.     
  204.     if (!getbuf( address_of_tcpcb, &tcpcb, sizeof(tcpcb) , "&tcpcb"))
  205.     {
  206.       return -1;
  207.     }
  208.     
  209.     i++;    /* for the read */
  210.     if (!tcpcb.t_laddr || !tcpcb.t_faddr) /* skip unused entrys */
  211.     continue;
  212.     
  213.     /* have to convert these babies */
  214.     if ( tcpcb.t_faddr == htonl(faddr->s_addr) &&
  215.      tcpcb.t_laddr == htonl(laddr->s_addr) &&
  216.      tcpcb.t_fport == htons(fport) &&
  217.      tcpcb.t_lport == htons(lport) )
  218.  
  219.       return pcbp->td_dev;
  220.     
  221.     /* if we get here we need to read the tcpd followed by tcpcb, but
  222.     ** first we check if we are at the end of the tcpd struct
  223.     */
  224.   } while ( (i != tcpd_cnt) &&
  225.        getbuf((long) (nl[N_TCPD].n_value + ( i * sizeof(struct tcpd)) ),
  226.           pcbp, sizeof(struct tcpd), "tcpdlist")  );
  227.   
  228. #else
  229.   
  230.   head = pcbp->inp_prev;
  231.   do 
  232.   {
  233.     if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
  234.      pcbp->inp_laddr.s_addr == laddr->s_addr &&
  235.      pcbp->inp_fport        == fport &&
  236.      pcbp->inp_lport        == lport )
  237.       return pcbp->inp_minor;
  238.   } while (pcbp->inp_next != head &&
  239.        getbuf((long) pcbp->inp_next,
  240.           pcbp,
  241.           sizeof(struct inpcb),
  242.           "tcblist"));
  243. #endif /* not ATTSVR4 */
  244.  
  245.   return -1;
  246. }
  247.  
  248.  
  249.  
  250. /*
  251. ** Return the user number for the connection owner in the int pointed
  252. ** at in the uid argument.
  253. */
  254. int k_getuid(faddr, fport, laddr, lport, uid)
  255.   struct in_addr *faddr;
  256.   int fport;
  257.   struct in_addr *laddr;
  258.   int lport;
  259.   int *uid;
  260. {
  261.   long addr;
  262.   struct stat s;
  263.   short tcpmajor;    /* Major number of the tcp device */
  264.   short sockp;        /* Really a device minor number */
  265.   struct file *filehead, file;
  266.   struct ucred ucb;
  267.  
  268.   
  269.   /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
  270.   if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
  271.     return -1;
  272.  
  273.   /* we just need to determine the major number of the tcp module, which
  274.      is the minor number of the tcp clone device /dev/tcp */
  275.   if (stat("/dev/tcp", &s))
  276.     ERROR("stat(\"/dev/tcp\")");
  277.   
  278.   tcpmajor = minor(s.st_rdev);
  279.  
  280.   /* -------------------- TCP PCB LIST -------------------- */
  281. #ifdef ATTSVR4
  282.   /* get the number of tcpd structs together */
  283.   if (!getbuf(nl[N_TCPD_CNT].n_value, &tcpd_cnt,
  284.           sizeof(tcpd_cnt), "&tcpd_cnt"))
  285.     return -1;
  286.   
  287.   if (!getbuf(nl[N_TCPD].n_value, &tcpd, sizeof(tcpd), "&tcpd"))
  288.     return -1;
  289.   
  290.   sockp = getlist(&tcpd, faddr, fport, laddr, lport);
  291. #else
  292.   if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
  293.     return -1;
  294.   
  295.   tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
  296.   sockp = getlist(&tcb, faddr, fport, laddr, lport);
  297. #endif
  298.   
  299.   if (sockp < 0)
  300.     return -1;
  301.  
  302.  
  303.   /*
  304.   * Get the pointer to the head of the file list
  305.   */
  306.   if (!getbuf(nl[N_FILE].n_value, &filehead, sizeof(struct file *)))
  307.     return -1;
  308.   
  309.   file.f_next = filehead;
  310.   do
  311.   {
  312.     struct vnode vnode;
  313.  
  314.     /*
  315.     ** Grab a file record
  316.     */
  317.     if (!getbuf((long)file.f_next, &file, sizeof(struct file), "file"))
  318.       return -1;
  319.  
  320.     /*
  321.     ** Grab the vnode information to check whether this file is the
  322.     ** correct major & minor char device
  323.     */
  324.     if (!getbuf((off_t)file.f_vnode, &vnode, sizeof(struct vnode), "vnode"))
  325.       return -1;
  326.     
  327.     if ((vnode.v_type == VCHR) && (major(vnode.v_rdev) == tcpmajor) &&
  328.     (minor(vnode.v_rdev) == sockp))
  329.     {
  330.       /*
  331.       ** We've found it!
  332.       */
  333.       if (!getbuf((off_t)file.f_cred, &ucb, sizeof(struct cred), "cred"))
  334.     return -1;
  335.       
  336.       *uid = ucb.cr_ruid;
  337.       return 0;
  338.     }
  339.     
  340.   } while (file.f_next != filehead);
  341.   
  342.   return -1;
  343. }
  344.