home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) Gerhard Fuernkranz 1992 */
-
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/errno.h>
- #include <sys/signal.h>
- #ifdef SYSV
- #include <sys/cred.h>
- #include <sys/proc.h>
- #endif /* SYSV */
- #include <sys/user.h> /* XXX - TOM */
- #include <sys/stropts.h>
- #include <sys/stream.h>
- #include <sys/strlog.h>
- #include <sys/log.h>
- #include <netinet/nihdr.h>
- #include <sys/dlpi.h>
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #include <net/if.h>
- #include <net/strioc.h>
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/ip_var.h>
- #include <netinet/ip_icmp.h>
- #include <netinet/in_var.h>
- #include <netinet/tcp.h>
- /* #include <netinet/tcpip.h> */
- #include <sys/kmem.h>
-
- /* Include the code for the matcher machine */
-
- #include "matcher.c"
-
- static mblk_t *prog;
-
- static int ipaccopen (), ipaccclose (), ipaccrput (), ipaccwput ();
-
- /* The T-streams module. */
-
- static struct module_info ipaccm_info =
- {
- 0, "ipacc", 0, INFPSZ, 4096, 1024,
- };
-
- static struct qinit ipaccurinit =
- {ipaccrput, NULL, ipaccopen, ipaccclose, NULL, &ipaccm_info, NULL};
-
- static struct qinit ipaccuwinit =
- {ipaccwput, NULL, ipaccopen, ipaccclose, NULL, &ipaccm_info, NULL};
-
- struct streamtab ipaccinfo =
- {&ipaccurinit, &ipaccuwinit, NULL, NULL};
-
- /* Open routine of the T-module. */
-
- static int
- ipaccopen (q, dev, flag, sflag)
- queue_t *q;
- {
- return 0;
- }
-
- /* Close routine of the T-module. */
-
- static int
- ipaccclose (q)
- queue_t *q;
- {
- return 0;
- }
-
- /* Put routine of the iupcc-module. */
-
- static int
- ipaccrput (q, bp)
- queue_t *q;
- mblk_t *bp;
- {
- union N_primitives *p;
- struct ip *ip;
- struct tcphdr *ti;
- struct iocblk *io;
- unsigned short sport, dport;
- int hlen;
-
- switch (bp->b_datap->db_type)
- {
-
- case M_PROTO:
- case M_PCPROTO:
-
- p = (void *) bp->b_rptr;
- switch (p->prim_type)
- {
- case N_UNITDATA_REQ:
- case N_UNITDATA_IND:
-
- if (bp->b_cont->b_wptr - bp->b_cont->b_rptr < sizeof (struct ip) + 4)
- if (!pullupmsg (bp->b_cont, sizeof (struct ip) + 4))
- {
- freemsg (bp);
- return;
- }
-
- ip = (void *) bp->b_cont->b_rptr;
- hlen = ip->ip_hl << 2;
-
- if (bp->b_cont->b_wptr - bp->b_cont->b_rptr < hlen + 4)
- {
- if (!pullupmsg (bp->b_cont, hlen + 4))
- {
- freemsg (bp);
- return;
- }
- ip = (void *) bp->b_cont->b_rptr;
- }
-
- ti = (struct tcphdr *) ((char *) ip + hlen);
- sport = ntohs (ti->th_sport);
- dport = ntohs (ti->th_dport);
-
- /* ICMP packets are generally allowed - with the exception of ICMP
- redirect messages. */
-
- if (ip->ip_p == IPPROTO_ICMP)
- {
- struct icmp *icp = (struct icmp *) ((char *) ip + hlen);
-
- if (icp->icmp_type > ICMP_MAXTYPE ||
- icp->icmp_type == ICMP_REDIRECT)
- {
- /* Message is not allowed - discard it */
- freemsg (bp);
- return;
- }
- }
-
- /* Other packets will be fed thru the filter program. */
-
- else if (!matcher (ip->ip_src.s_addr, ip->ip_dst.s_addr,
- sport, dport, ip->ip_p))
- {
- /* Message is not allowed - discard it */
- freemsg (bp);
- return;
- }
- }
- break;
- }
-
- putnext (q, bp);
- }
-
- static int
- ipaccwput (q, bp)
- queue_t *q;
- mblk_t *bp;
- {
- union N_primitives *p;
- struct ip *ip;
- struct tcphdr *ti;
- struct iocblk *io;
- unsigned short sport, dport;
-
- switch (bp->b_datap->db_type)
- {
-
- case M_IOCTL:
- io = (void *) bp->b_rptr;
- if (io->ioc_cmd == ('I' << 24 | 'P' << 16 | 'A' << 8 | 0))
- {
- mblk_t *tmp;
- int s;
- if (bp->b_cont == NULL)
- {
- bp->b_datap->db_type = M_IOCNAK;
- io->ioc_error = EINVAL;
- qreply (q, bp);
- return;
- }
- if ((io->ioc_error = drv_priv (io->ioc_cr)) != 0)
- {
- bp->b_datap->db_type = M_IOCNAK;
- qreply (q, bp);
- return;
- }
- if ((tmp = dupmsg (bp->b_cont)) != NULL)
- {
- if (!pullupmsg (tmp, -1))
- {
- freemsg (tmp);
- tmp = NULL;
- }
- }
- if (tmp == NULL)
- {
- bp->b_datap->db_type = M_IOCNAK;
- io->ioc_error = ENOSR;
- qreply (q, bp);
- return;
- }
-
- s = splstr ();
- if (prog)
- freemsg (prog);
- prog = tmp;
- set_pc ((unsigned short *) tmp->b_rptr);
- splx (s);
-
- /* call OK, ack it */
-
- bp->b_datap->db_type = M_IOCACK;
- qreply (q, bp);
- return;
- }
- break;
-
- case M_PROTO:
- case M_PCPROTO:
-
- p = (void *) bp->b_rptr;
- switch (p->prim_type)
- {
- case N_UNITDATA_REQ:
- case N_UNITDATA_IND:
-
- if (bp->b_cont->b_wptr - bp->b_cont->b_rptr < sizeof (struct ip) + 4)
- if (!pullupmsg (bp->b_cont, sizeof (struct ip) + 4))
- {
- freemsg (bp);
- return;
- }
-
- ip = (void *) bp->b_cont->b_rptr;
- ti = (struct tcphdr *) (ip + 1);
- sport = ntohs (ti->th_sport);
- dport = ntohs (ti->th_dport);
-
- /* ICMP packets are generally allowed - with the exception of ICMP
- redirect messages. */
-
- if (ip->ip_p == IPPROTO_ICMP)
- {
- struct icmp *icp = (struct icmp *) (ip + 1);
-
- if (icp->icmp_type > ICMP_MAXTYPE ||
- icp->icmp_type == ICMP_REDIRECT)
- {
- /* Message is not allowed - discard it */
- freemsg (bp);
- return;
- }
- }
-
- /* Other packets will be fed thru the filter program. */
-
- else if (!matcher (ip->ip_src.s_addr, ip->ip_dst.s_addr,
- sport, dport, ip->ip_p))
- {
- /* Message is not allowed - discard it */
- freemsg (bp);
- return;
- }
- }
- break;
- }
-
- putnext (q, bp);
- }
-