add IFF_LOCAL
[unix-history] / usr / src / sys / net / if_loop.c
CommitLineData
b11be056 1/* if_loop.c 6.1 83/07/29 */
0a486d2b
BJ
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"
1cc8c949 11#include "../h/errno.h"
639a8848 12#include "../h/ioctl.h"
1cc8c949 13
0a486d2b 14#include "../net/if.h"
fcfe450e 15#include "../net/netisr.h"
1cc8c949
SL
16#include "../net/route.h"
17
18#include "../netinet/in.h"
19#include "../netinet/in_systm.h"
fcfe450e
BJ
20#include "../netinet/ip.h"
21#include "../netinet/ip_var.h"
1cc8c949 22
b152d3c4
SL
23#ifdef vax
24#include "../vax/mtpr.h"
25#endif
0a486d2b 26
0939c871 27#define LONET 127
40a41e8b 28#define LOHOST 1 /* can't be 0, that's broadcast */
56e0df97 29#define LOMTU (1024+512)
0a486d2b
BJ
30
31struct ifnet loif;
639a8848 32int looutput(), loioctl();
0a486d2b
BJ
33
34loattach()
35{
36 register struct ifnet *ifp = &loif;
ee787340 37 register struct sockaddr_in *sin;
0a486d2b 38
b454c3ea 39 ifp->if_name = "lo";
0a486d2b
BJ
40 ifp->if_mtu = LOMTU;
41 ifp->if_net = LONET;
40a41e8b 42 ifp->if_host[0] = LOHOST;
ee787340
SL
43 sin = (struct sockaddr_in *)&ifp->if_addr;
44 sin->sin_family = AF_INET;
639a8848
SL
45 sin->sin_addr = if_makeaddr(LONET, LOHOST);
46 ifp->if_flags = IFF_UP | IFF_RUNNING;
47 ifp->if_ioctl = loioctl;
0a486d2b 48 ifp->if_output = looutput;
405c9168 49 if_attach(ifp);
a13c006d 50 if_rtinit(ifp, RTF_UP);
0a486d2b
BJ
51}
52
ee787340 53looutput(ifp, m0, dst)
0a486d2b
BJ
54 struct ifnet *ifp;
55 struct mbuf *m0;
ee787340 56 struct sockaddr *dst;
0a486d2b
BJ
57{
58 int s = splimp();
1e977657 59 register struct ifqueue *ifq;
0a486d2b 60
b454c3ea 61 ifp->if_opackets++;
ee787340 62 switch (dst->sa_family) {
0a486d2b
BJ
63
64#ifdef INET
ee787340 65 case AF_INET:
1e977657
BJ
66 ifq = &ipintrq;
67 if (IF_QFULL(ifq)) {
68 IF_DROP(ifq);
ee787340 69 m_freem(m0);
1e977657 70 splx(s);
4c5902e0 71 return (ENOBUFS);
1e977657
BJ
72 }
73 IF_ENQUEUE(ifq, m0);
9c8692e9 74 schednetisr(NETISR_IP);
0a486d2b
BJ
75 break;
76#endif
0a486d2b
BJ
77 default:
78 splx(s);
ee787340
SL
79 printf("lo%d: can't handle af%d\n", ifp->if_unit,
80 dst->sa_family);
81 m_freem(m0);
4c5902e0 82 return (EAFNOSUPPORT);
0a486d2b 83 }
b454c3ea 84 ifp->if_ipackets++;
0a486d2b 85 splx(s);
4c5902e0 86 return (0);
0a486d2b 87}
639a8848
SL
88
89/*
90 * Process an ioctl request.
91 */
92loioctl(ifp, cmd, data)
93 register struct ifnet *ifp;
94 int cmd;
95 caddr_t data;
96{
97 struct ifreq *ifr = (struct ifreq *)data;
98 struct sockaddr_in *sin;
99 int s = splimp(), error = 0;
100
101 switch (cmd) {
102
103 case SIOCSIFADDR:
104 if (ifp->if_flags & IFF_RUNNING)
105 if_rtinit(ifp, -1); /* delete previous route */
106 ifp->if_addr = ifr->ifr_addr;
107 sin = (struct sockaddr_in *)&ifp->if_addr;
108 ifp->if_net = in_netof(sin->sin_addr);
109 ifp->if_host[0] = in_lnaof(sin->sin_addr);
110 if_rtinit(ifp, RTF_UP);
111 break;
112
113 default:
114 error = EINVAL;
115 }
116 splx(s);
117 return (error);
118}