home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / ipacl / Driver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-12  |  5.3 KB  |  274 lines

  1.  
  2. /* Copyright (C) Gerhard Fuernkranz 1992 */
  3.  
  4. #include <sys/types.h>
  5. #include <sys/param.h>
  6. #include <sys/sysmacros.h>
  7. #include <sys/errno.h>
  8. #include <sys/signal.h>
  9. #ifdef SYSV
  10. #include <sys/cred.h>
  11. #include <sys/proc.h>
  12. #endif                /* SYSV */
  13. #include <sys/user.h>        /* XXX - TOM */
  14. #include <sys/stropts.h>
  15. #include <sys/stream.h>
  16. #include <sys/strlog.h>
  17. #include <sys/log.h>
  18. #include <netinet/nihdr.h>
  19. #include <sys/dlpi.h>
  20. #include <sys/socket.h>
  21. #include <sys/socketvar.h>
  22. #include <net/if.h>
  23. #include <net/strioc.h>
  24. #include <netinet/in.h>
  25. #include <netinet/in_systm.h>
  26. #include <netinet/ip.h>
  27. #include <netinet/ip_var.h>
  28. #include <netinet/ip_icmp.h>
  29. #include <netinet/in_var.h>
  30. #include <netinet/tcp.h>
  31. /* #include <netinet/tcpip.h> */
  32. #include <sys/kmem.h>
  33.  
  34. /* Include the code for the matcher machine */
  35.  
  36. #include "matcher.c"
  37.  
  38. static mblk_t *prog;
  39.  
  40. static int ipaccopen (), ipaccclose (), ipaccrput (), ipaccwput ();
  41.  
  42. /* The T-streams module. */
  43.  
  44. static struct module_info ipaccm_info =
  45. {
  46.   0, "ipacc", 0, INFPSZ, 4096, 1024,
  47. };
  48.  
  49. static struct qinit ipaccurinit =
  50. {ipaccrput, NULL, ipaccopen, ipaccclose, NULL, &ipaccm_info, NULL};
  51.  
  52. static struct qinit ipaccuwinit =
  53. {ipaccwput, NULL, ipaccopen, ipaccclose, NULL, &ipaccm_info, NULL};
  54.  
  55. struct streamtab ipaccinfo =
  56. {&ipaccurinit, &ipaccuwinit, NULL, NULL};
  57.  
  58. /* Open routine of the T-module. */
  59.  
  60. static int
  61. ipaccopen (q, dev, flag, sflag)
  62.      queue_t *q;
  63. {
  64.   return 0;
  65. }
  66.  
  67. /* Close routine of the T-module. */
  68.  
  69. static int
  70. ipaccclose (q)
  71.      queue_t *q;
  72. {
  73.   return 0;
  74. }
  75.  
  76. /* Put routine of the iupcc-module. */
  77.  
  78. static int
  79. ipaccrput (q, bp)
  80.      queue_t *q;
  81.      mblk_t *bp;
  82. {
  83.   union N_primitives *p;
  84.   struct ip *ip;
  85.   struct tcphdr *ti;
  86.   struct iocblk *io;
  87.   unsigned short sport, dport;
  88.   int hlen;
  89.  
  90.   switch (bp->b_datap->db_type)
  91.     {
  92.  
  93.     case M_PROTO:
  94.     case M_PCPROTO:
  95.  
  96.       p = (void *) bp->b_rptr;
  97.       switch (p->prim_type)
  98.     {
  99.     case N_UNITDATA_REQ:
  100.     case N_UNITDATA_IND:
  101.  
  102.       if (bp->b_cont->b_wptr - bp->b_cont->b_rptr < sizeof (struct ip) + 4)
  103.         if (!pullupmsg (bp->b_cont, sizeof (struct ip) + 4))
  104.           {
  105.         freemsg (bp);
  106.         return;
  107.           }
  108.  
  109.       ip = (void *) bp->b_cont->b_rptr;
  110.       hlen = ip->ip_hl << 2;
  111.  
  112.       if (bp->b_cont->b_wptr - bp->b_cont->b_rptr < hlen + 4)
  113.         {
  114.           if (!pullupmsg (bp->b_cont, hlen + 4))
  115.         {
  116.           freemsg (bp);
  117.           return;
  118.         }
  119.           ip = (void *) bp->b_cont->b_rptr;
  120.         }
  121.  
  122.       ti = (struct tcphdr *) ((char *) ip + hlen);
  123.       sport = ntohs (ti->th_sport);
  124.       dport = ntohs (ti->th_dport);
  125.  
  126.       /* ICMP packets are generally allowed - with the exception of ICMP
  127.          redirect messages. */
  128.  
  129.       if (ip->ip_p == IPPROTO_ICMP)
  130.         {
  131.           struct icmp *icp = (struct icmp *) ((char *) ip + hlen);
  132.  
  133.           if (icp->icmp_type > ICMP_MAXTYPE ||
  134.           icp->icmp_type == ICMP_REDIRECT)
  135.         {
  136.           /* Message is not allowed - discard it */
  137.           freemsg (bp);
  138.           return;
  139.         }
  140.         }
  141.  
  142.       /* Other packets will be fed thru the filter program. */
  143.  
  144.       else if (!matcher (ip->ip_src.s_addr, ip->ip_dst.s_addr,
  145.                  sport, dport, ip->ip_p))
  146.         {
  147.           /* Message is not allowed - discard it */
  148.           freemsg (bp);
  149.           return;
  150.         }
  151.     }
  152.       break;
  153.     }
  154.  
  155.   putnext (q, bp);
  156. }
  157.  
  158. static int
  159. ipaccwput (q, bp)
  160.      queue_t *q;
  161.      mblk_t *bp;
  162. {
  163.   union N_primitives *p;
  164.   struct ip *ip;
  165.   struct tcphdr *ti;
  166.   struct iocblk *io;
  167.   unsigned short sport, dport;
  168.  
  169.   switch (bp->b_datap->db_type)
  170.     {
  171.  
  172.     case M_IOCTL:
  173.       io = (void *) bp->b_rptr;
  174.       if (io->ioc_cmd == ('I' << 24 | 'P' << 16 | 'A' << 8 | 0))
  175.     {
  176.       mblk_t *tmp;
  177.       int s;
  178.       if (bp->b_cont == NULL)
  179.         {
  180.           bp->b_datap->db_type = M_IOCNAK;
  181.           io->ioc_error = EINVAL;
  182.           qreply (q, bp);
  183.           return;
  184.         }
  185.       if ((io->ioc_error = drv_priv (io->ioc_cr)) != 0)
  186.         {
  187.           bp->b_datap->db_type = M_IOCNAK;
  188.           qreply (q, bp);
  189.           return;
  190.         }
  191.       if ((tmp = dupmsg (bp->b_cont)) != NULL)
  192.         {
  193.           if (!pullupmsg (tmp, -1))
  194.         {
  195.           freemsg (tmp);
  196.           tmp = NULL;
  197.         }
  198.         }
  199.       if (tmp == NULL)
  200.         {
  201.           bp->b_datap->db_type = M_IOCNAK;
  202.           io->ioc_error = ENOSR;
  203.           qreply (q, bp);
  204.           return;
  205.         }
  206.  
  207.       s = splstr ();
  208.       if (prog)
  209.         freemsg (prog);
  210.       prog = tmp;
  211.       set_pc ((unsigned short *) tmp->b_rptr);
  212.       splx (s);
  213.  
  214.       /* call OK, ack it */
  215.  
  216.       bp->b_datap->db_type = M_IOCACK;
  217.       qreply (q, bp);
  218.       return;
  219.     }
  220.       break;
  221.  
  222.     case M_PROTO:
  223.     case M_PCPROTO:
  224.  
  225.       p = (void *) bp->b_rptr;
  226.       switch (p->prim_type)
  227.     {
  228.     case N_UNITDATA_REQ:
  229.     case N_UNITDATA_IND:
  230.  
  231.       if (bp->b_cont->b_wptr - bp->b_cont->b_rptr < sizeof (struct ip) + 4)
  232.         if (!pullupmsg (bp->b_cont, sizeof (struct ip) + 4))
  233.           {
  234.         freemsg (bp);
  235.         return;
  236.           }
  237.  
  238.       ip = (void *) bp->b_cont->b_rptr;
  239.       ti = (struct tcphdr *) (ip + 1);
  240.       sport = ntohs (ti->th_sport);
  241.       dport = ntohs (ti->th_dport);
  242.  
  243.       /* ICMP packets are generally allowed - with the exception of ICMP
  244.          redirect messages. */
  245.  
  246.       if (ip->ip_p == IPPROTO_ICMP)
  247.         {
  248.           struct icmp *icp = (struct icmp *) (ip + 1);
  249.  
  250.           if (icp->icmp_type > ICMP_MAXTYPE ||
  251.           icp->icmp_type == ICMP_REDIRECT)
  252.         {
  253.           /* Message is not allowed - discard it */
  254.           freemsg (bp);
  255.           return;
  256.         }
  257.         }
  258.  
  259.       /* Other packets will be fed thru the filter program. */
  260.  
  261.       else if (!matcher (ip->ip_src.s_addr, ip->ip_dst.s_addr,
  262.                  sport, dport, ip->ip_p))
  263.         {
  264.           /* Message is not allowed - discard it */
  265.           freemsg (bp);
  266.           return;
  267.         }
  268.     }
  269.       break;
  270.     }
  271.  
  272.   putnext (q, bp);
  273. }
  274.