xref: /original-bsd/sys/net/if_loop.c (revision fbed46ce)
1 /*	if_loop.c	4.11	82/04/16	*/
2 
3 /*
4  * Loopback interface driver for protocol testing and timing.
5  */
6 
7 #include "../h/param.h"
8 #include "../h/systm.h"
9 #include "../h/mbuf.h"
10 #include "../h/socket.h"
11 #include "../net/in.h"
12 #include "../net/in_systm.h"
13 #include "../net/if.h"
14 #include "../net/ip.h"
15 #include "../net/ip_var.h"
16 #include "../h/mtpr.h"
17 #include "../net/route.h"
18 #include <errno.h>
19 
20 #define	LONET	127
21 #define	LOMTU	(1024+512)
22 
23 struct	ifnet loif;
24 int	looutput();
25 
26 loattach()
27 {
28 	register struct ifnet *ifp = &loif;
29 	register struct sockaddr_in *sin;
30 
31 COUNT(LOATTACH);
32 	ifp->if_name = "lo";
33 	ifp->if_mtu = LOMTU;
34 	ifp->if_net = LONET;
35 	sin = (struct sockaddr_in *)&ifp->if_addr;
36 	sin->sin_family = AF_INET;
37 	sin->sin_addr = if_makeaddr(ifp->if_net, 0);
38 	ifp->if_flags = IFF_UP;
39 	ifp->if_output = looutput;
40 	if_attach(ifp);
41 	if_rtinit(ifp, RTF_DIRECT|RTF_UP);
42 }
43 
44 looutput(ifp, m0, dst)
45 	struct ifnet *ifp;
46 	struct mbuf *m0;
47 	struct sockaddr *dst;
48 {
49 	int s = splimp();
50 	register struct ifqueue *ifq;
51 
52 COUNT(LOOUTPUT);
53 	ifp->if_opackets++;
54 	switch (dst->sa_family) {
55 
56 #ifdef INET
57 	case AF_INET:
58 		ifq = &ipintrq;
59 		if (IF_QFULL(ifq)) {
60 			IF_DROP(ifq);
61 			m_freem(m0);
62 			splx(s);
63 			return (ENOBUFS);
64 		}
65 		IF_ENQUEUE(ifq, m0);
66 		schednetisr(NETISR_IP);
67 		break;
68 #endif
69 	default:
70 		splx(s);
71 		printf("lo%d: can't handle af%d\n", ifp->if_unit,
72 			dst->sa_family);
73 		m_freem(m0);
74 		return (EAFNOSUPPORT);
75 	}
76 	ifp->if_ipackets++;
77 	splx(s);
78 	return (0);
79 }
80