if_enc.c revision 1.35
1/*	$OpenBSD: if_enc.c,v 1.35 2001/06/25 05:14:00 angelos Exp $	*/
2/*
3 * The authors of this code are John Ioannidis (ji@tla.org),
4 * Angelos D. Keromytis (kermit@csd.uch.gr) and
5 * Niels Provos (provos@physnet.uni-hamburg.de).
6 *
7 * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
8 * in November 1995.
9 *
10 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11 * by Angelos D. Keromytis.
12 *
13 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14 * and Niels Provos.
15 *
16 * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
17 * and Niels Provos.
18 * Copyright (c) 2001, Angelos D. Keromytis.
19 *
20 * Permission to use, copy, and modify this software with or without fee
21 * is hereby granted, provided that this entire notice is included in
22 * all copies of any software which is or includes a copy or
23 * modification of this software.
24 * You may use this code under the GNU public license if you so wish. Please
25 * contribute changes back to the authors under this freer than GPL license
26 * so that we may further the use of strong encryption without limitations to
27 * all.
28 *
29 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
30 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
31 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
32 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
33 * PURPOSE.
34 */
35
36/*
37 * Encapsulation interface driver.
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/mbuf.h>
43#include <sys/socket.h>
44#include <sys/ioctl.h>
45
46#include <net/if.h>
47#include <net/if_types.h>
48#include <net/route.h>
49#include <net/bpf.h>
50
51#include <net/if_enc.h>
52
53#ifdef	INET
54#include <netinet/in.h>
55#include <netinet/in_var.h>
56#endif
57
58#ifdef INET6
59#ifndef INET
60#include <netinet/in.h>
61#endif
62#include <netinet6/nd6.h>
63#endif /* INET6 */
64
65#ifdef ISO
66extern struct ifqueue clnlintrq;
67#endif
68
69#ifdef NS
70extern struct ifqueue nsintrq;
71#endif
72
73#include "bpfilter.h"
74#include "enc.h"
75
76#ifdef ENCDEBUG
77#define DPRINTF(x)    do { if (encdebug) printf x ; } while (0)
78#else
79#define DPRINTF(x)
80#endif
81
82struct enc_softc encif[NENC];
83
84void	encattach __P((int));
85int	encoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
86	    	       struct rtentry *));
87int	encioctl __P((struct ifnet *, u_long, caddr_t));
88void	encrtrequest __P((int, struct rtentry *, struct sockaddr *));
89void	encstart __P((struct ifnet *));
90
91extern int ifqmaxlen;
92
93void
94encattach(int nenc)
95{
96    struct ifnet *ifp;
97    int i;
98
99    bzero(encif, sizeof(encif));
100
101    for (i = 0; i < NENC; i++)
102    {
103	ifp = &encif[i].sc_if;
104	sprintf(ifp->if_xname, "enc%d", i);
105	ifp->if_softc = &encif[i];
106	ifp->if_mtu = ENCMTU;
107	ifp->if_ioctl = encioctl;
108	ifp->if_output = encoutput;
109	ifp->if_start = encstart;
110	ifp->if_type = IFT_ENC;
111	ifp->if_snd.ifq_maxlen = ifqmaxlen;
112	ifp->if_hdrlen = ENC_HDRLEN;
113	if_attach(ifp);
114
115#if NBPFILTER > 0
116	bpfattach(&encif[i].sc_if.if_bpf, ifp, DLT_ENC, ENC_HDRLEN);
117#endif
118#ifdef INET6
119	nd6_ifattach(ifp);
120#endif
121    }
122}
123
124/*
125 * Start output on the enc interface.
126 */
127void
128encstart(ifp)
129struct ifnet *ifp;
130{
131    struct mbuf *m;
132    int s;
133
134    for (;;)
135    {
136        s = splimp();
137	IF_DROP(&ifp->if_snd);
138        IF_DEQUEUE(&ifp->if_snd, m);
139        splx(s);
140
141        if (m == NULL)
142          return;
143        else
144          m_freem(m);
145    }
146}
147
148int
149encoutput(ifp, m, dst, rt)
150struct ifnet *ifp;
151register struct mbuf *m;
152struct sockaddr *dst;
153register struct rtentry *rt;
154{
155    m_freem(m);
156    return 0;
157}
158
159/* ARGSUSED */
160void
161encrtrequest(cmd, rt, sa)
162int cmd;
163struct rtentry *rt;
164struct sockaddr *sa;
165{
166    if (rt)
167      rt->rt_rmx.rmx_mtu = ENCMTU;
168}
169
170/* ARGSUSED */
171int
172encioctl(ifp, cmd, data)
173register struct ifnet *ifp;
174u_long cmd;
175caddr_t data;
176{
177    switch (cmd)
178    {
179	case SIOCSIFADDR:
180	case SIOCAIFADDR:
181	case SIOCSIFDSTADDR:
182	case SIOCSIFFLAGS:
183	    if (ifp->if_flags & IFF_UP)
184	      ifp->if_flags |= IFF_RUNNING;
185	    else
186	      ifp->if_flags &= ~IFF_RUNNING;
187	    break;
188
189	default:
190	    return EINVAL;
191    }
192
193    return 0;
194}
195