xref: /csrg-svn/sys/net/if_loop.c (revision 21290)
1 /*	if_loop.c	6.5	85/05/30	*/
2 
3 /*
4  * Loopback interface driver for protocol testing and timing.
5  */
6 
7 #include "param.h"
8 #include "systm.h"
9 #include "mbuf.h"
10 #include "socket.h"
11 #include "errno.h"
12 #include "ioctl.h"
13 
14 #include "../net/if.h"
15 #include "../net/netisr.h"
16 #include "../net/route.h"
17 
18 #include "in.h"
19 #include "in_systm.h"
20 #include "ip.h"
21 #include "ip_var.h"
22 
23 #ifdef vax
24 #include "../vax/mtpr.h"
25 #endif
26 
27 #ifdef NS
28 #include "../netns/ns.h"
29 #include "../netns/ns_if.h"
30 #endif
31 
32 #define	LOMTU	(1024+512)
33 
34 struct	ifnet loif;
35 int	looutput(), loioctl();
36 
37 loattach()
38 {
39 	register struct ifnet *ifp = &loif;
40 	register struct sockaddr_in *sin;
41 
42 	ifp->if_name = "lo";
43 	ifp->if_mtu = LOMTU;
44 	ifp->if_ioctl = loioctl;
45 	ifp->if_output = looutput;
46 	if_attach(ifp);
47 }
48 
49 looutput(ifp, m0, dst)
50 	struct ifnet *ifp;
51 	struct mbuf *m0;
52 	struct sockaddr *dst;
53 {
54 	int s = splimp();
55 	register struct ifqueue *ifq;
56 
57 	ifp->if_opackets++;
58 	switch (dst->sa_family) {
59 
60 #ifdef INET
61 	case AF_INET:
62 		ifq = &ipintrq;
63 		if (IF_QFULL(ifq)) {
64 			IF_DROP(ifq);
65 			m_freem(m0);
66 			splx(s);
67 			return (ENOBUFS);
68 		}
69 		IF_ENQUEUE(ifq, m0);
70 		schednetisr(NETISR_IP);
71 		break;
72 #endif
73 #ifdef NS
74 	case AF_NS:
75 		ifq = &nsintrq;
76 		if (IF_QFULL(ifq)) {
77 			IF_DROP(ifq);
78 			m_freem(m0);
79 			splx(s);
80 			return (ENOBUFS);
81 		}
82 		IF_ENQUEUE(ifq, m0);
83 		schednetisr(NETISR_NS);
84 		break;
85 #endif
86 	default:
87 		splx(s);
88 		printf("lo%d: can't handle af%d\n", ifp->if_unit,
89 			dst->sa_family);
90 		m_freem(m0);
91 		return (EAFNOSUPPORT);
92 	}
93 	ifp->if_ipackets++;
94 	splx(s);
95 	return (0);
96 }
97 
98 /*
99  * Process an ioctl request.
100  */
101 /* ARGSUSED */
102 loioctl(ifp, cmd, data)
103 	register struct ifnet *ifp;
104 	int cmd;
105 	caddr_t data;
106 {
107 	int error = 0;
108 
109 	switch (cmd) {
110 
111 	case SIOCSIFADDR:
112 		ifp->if_flags |= IFF_UP;
113 		/*
114 		 * Everything else is done at a higher level.
115 		 */
116 		break;
117 
118 	default:
119 		error = EINVAL;
120 	}
121 	return (error);
122 }
123