add Berkeley header
[unix-history] / usr / src / sys / net / if_loop.c
CommitLineData
8ae0e4b4 1/*
21622db8 2 * Copyright (c) 1982, 1986 Regents of the University of California.
5b519e94 3 * All rights reserved.
8ae0e4b4 4 *
5b519e94
KB
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of California at Berkeley. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
11 *
12 * @(#)if_loop.c 7.3 (Berkeley) %G%
8ae0e4b4 13 */
0a486d2b
BJ
14
15/*
16 * Loopback interface driver for protocol testing and timing.
17 */
18
20666ad3
JB
19#include "param.h"
20#include "systm.h"
21#include "mbuf.h"
22#include "socket.h"
23#include "errno.h"
24#include "ioctl.h"
1cc8c949 25
0a486d2b 26#include "../net/if.h"
fcfe450e 27#include "../net/netisr.h"
1cc8c949
SL
28#include "../net/route.h"
29
2e62d00d
MK
30#include "../machine/mtpr.h"
31
dbc42650
MK
32#ifdef INET
33#include "../netinet/in.h"
34#include "../netinet/in_systm.h"
21622db8 35#include "../netinet/in_var.h"
dbc42650 36#include "../netinet/ip.h"
dbc42650 37#endif
1cc8c949 38
edecfd58
KS
39#ifdef NS
40#include "../netns/ns.h"
41#include "../netns/ns_if.h"
42#endif
43
56e0df97 44#define LOMTU (1024+512)
0a486d2b
BJ
45
46struct ifnet loif;
639a8848 47int looutput(), loioctl();
0a486d2b
BJ
48
49loattach()
50{
51 register struct ifnet *ifp = &loif;
52
b454c3ea 53 ifp->if_name = "lo";
0a486d2b 54 ifp->if_mtu = LOMTU;
484ee22e 55 ifp->if_flags = IFF_LOOPBACK;
639a8848 56 ifp->if_ioctl = loioctl;
0a486d2b 57 ifp->if_output = looutput;
405c9168 58 if_attach(ifp);
0a486d2b
BJ
59}
60
ee787340 61looutput(ifp, m0, dst)
0a486d2b 62 struct ifnet *ifp;
dbc42650 63 register struct mbuf *m0;
ee787340 64 struct sockaddr *dst;
0a486d2b 65{
dbc42650 66 int s;
1e977657 67 register struct ifqueue *ifq;
dbc42650
MK
68 struct mbuf *m;
69
70 /*
71 * Place interface pointer before the data
72 * for the receiving protocol.
73 */
74 if (m0->m_off <= MMAXOFF &&
75 m0->m_off >= MMINOFF + sizeof(struct ifnet *)) {
76 m0->m_off -= sizeof(struct ifnet *);
77 m0->m_len += sizeof(struct ifnet *);
78 } else {
79 MGET(m, M_DONTWAIT, MT_HEADER);
80 if (m == (struct mbuf *)0)
81 return (ENOBUFS);
82 m->m_off = MMINOFF;
83 m->m_len = sizeof(struct ifnet *);
84 m->m_next = m0;
85 m0 = m;
86 }
87 *(mtod(m0, struct ifnet **)) = ifp;
88 s = splimp();
b454c3ea 89 ifp->if_opackets++;
ee787340 90 switch (dst->sa_family) {
0a486d2b
BJ
91
92#ifdef INET
ee787340 93 case AF_INET:
1e977657
BJ
94 ifq = &ipintrq;
95 if (IF_QFULL(ifq)) {
96 IF_DROP(ifq);
ee787340 97 m_freem(m0);
1e977657 98 splx(s);
4c5902e0 99 return (ENOBUFS);
1e977657
BJ
100 }
101 IF_ENQUEUE(ifq, m0);
9c8692e9 102 schednetisr(NETISR_IP);
0a486d2b 103 break;
edecfd58
KS
104#endif
105#ifdef NS
106 case AF_NS:
107 ifq = &nsintrq;
108 if (IF_QFULL(ifq)) {
109 IF_DROP(ifq);
110 m_freem(m0);
111 splx(s);
112 return (ENOBUFS);
113 }
114 IF_ENQUEUE(ifq, m0);
115 schednetisr(NETISR_NS);
116 break;
0a486d2b 117#endif
0a486d2b
BJ
118 default:
119 splx(s);
ee787340
SL
120 printf("lo%d: can't handle af%d\n", ifp->if_unit,
121 dst->sa_family);
122 m_freem(m0);
4c5902e0 123 return (EAFNOSUPPORT);
0a486d2b 124 }
b454c3ea 125 ifp->if_ipackets++;
0a486d2b 126 splx(s);
4c5902e0 127 return (0);
0a486d2b 128}
639a8848
SL
129
130/*
131 * Process an ioctl request.
132 */
bba52753 133/* ARGSUSED */
639a8848
SL
134loioctl(ifp, cmd, data)
135 register struct ifnet *ifp;
136 int cmd;
137 caddr_t data;
138{
bba52753 139 int error = 0;
639a8848
SL
140
141 switch (cmd) {
142
143 case SIOCSIFADDR:
bba52753
MK
144 ifp->if_flags |= IFF_UP;
145 /*
146 * Everything else is done at a higher level.
147 */
639a8848
SL
148 break;
149
150 default:
151 error = EINVAL;
152 }
639a8848
SL
153 return (error);
154}