xref: /original-bsd/sys/net/if_loop.c (revision a910c8b7)
1 /*	if_loop.c	6.4	85/04/27	*/
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	LONET	127
33 #define	LOHOST	1			/* can't be 0, that's broadcast */
34 #define	LOMTU	(1024+512)
35 
36 struct	ifnet loif;
37 int	looutput(), loioctl();
38 
39 loattach()
40 {
41 	register struct ifnet *ifp = &loif;
42 	register struct sockaddr_in *sin;
43 
44 	ifp->if_name = "lo";
45 	ifp->if_mtu = LOMTU;
46 	ifp->if_ioctl = loioctl;
47 	ifp->if_output = looutput;
48 	if_attach(ifp);
49 }
50 
51 looutput(ifp, m0, dst)
52 	struct ifnet *ifp;
53 	struct mbuf *m0;
54 	struct sockaddr *dst;
55 {
56 	int s = splimp();
57 	register struct ifqueue *ifq;
58 
59 	ifp->if_opackets++;
60 	switch (dst->sa_family) {
61 
62 #ifdef INET
63 	case AF_INET:
64 		ifq = &ipintrq;
65 		if (IF_QFULL(ifq)) {
66 			IF_DROP(ifq);
67 			m_freem(m0);
68 			splx(s);
69 			return (ENOBUFS);
70 		}
71 		IF_ENQUEUE(ifq, m0);
72 		schednetisr(NETISR_IP);
73 		break;
74 #endif
75 #ifdef NS
76 	case AF_NS:
77 		ifq = &nsintrq;
78 		if (IF_QFULL(ifq)) {
79 			IF_DROP(ifq);
80 			m_freem(m0);
81 			splx(s);
82 			return (ENOBUFS);
83 		}
84 		IF_ENQUEUE(ifq, m0);
85 		schednetisr(NETISR_NS);
86 		break;
87 #endif
88 	default:
89 		splx(s);
90 		printf("lo%d: can't handle af%d\n", ifp->if_unit,
91 			dst->sa_family);
92 		m_freem(m0);
93 		return (EAFNOSUPPORT);
94 	}
95 	ifp->if_ipackets++;
96 	splx(s);
97 	return (0);
98 }
99 
100 /*
101  * Process an ioctl request.
102  */
103 /* ARGSUSED */
104 loioctl(ifp, cmd, data)
105 	register struct ifnet *ifp;
106 	int cmd;
107 	caddr_t data;
108 {
109 	int error = 0;
110 
111 	switch (cmd) {
112 
113 	case SIOCSIFADDR:
114 		ifp->if_flags |= IFF_UP;
115 		/*
116 		 * Everything else is done at a higher level.
117 		 */
118 		break;
119 
120 	default:
121 		error = EINVAL;
122 	}
123 	return (error);
124 }
125