1 /* if_loop.c 4.19 83/06/13 */ 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 "../h/errno.h" 12 #include "../h/ioctl.h" 13 14 #include "../net/if.h" 15 #include "../net/netisr.h" 16 #include "../net/route.h" 17 18 #include "../netinet/in.h" 19 #include "../netinet/in_systm.h" 20 #include "../netinet/ip.h" 21 #include "../netinet/ip_var.h" 22 23 #ifdef vax 24 #include "../vax/mtpr.h" 25 #endif 26 27 #define LONET 127 28 #define LOHOST 1 /* can't be 0, that's broadcast */ 29 #define LOMTU (1024+512) 30 31 struct ifnet loif; 32 int looutput(), loioctl(); 33 34 loattach() 35 { 36 register struct ifnet *ifp = &loif; 37 register struct sockaddr_in *sin; 38 39 ifp->if_name = "lo"; 40 ifp->if_mtu = LOMTU; 41 ifp->if_net = LONET; 42 ifp->if_host[0] = LOHOST; 43 sin = (struct sockaddr_in *)&ifp->if_addr; 44 sin->sin_family = AF_INET; 45 sin->sin_addr = if_makeaddr(LONET, LOHOST); 46 ifp->if_flags = IFF_UP | IFF_RUNNING; 47 ifp->if_ioctl = loioctl; 48 ifp->if_output = looutput; 49 if_attach(ifp); 50 if_rtinit(ifp, RTF_UP); 51 } 52 53 looutput(ifp, m0, dst) 54 struct ifnet *ifp; 55 struct mbuf *m0; 56 struct sockaddr *dst; 57 { 58 int s = splimp(); 59 register struct ifqueue *ifq; 60 61 ifp->if_opackets++; 62 switch (dst->sa_family) { 63 64 #ifdef INET 65 case AF_INET: 66 ifq = &ipintrq; 67 if (IF_QFULL(ifq)) { 68 IF_DROP(ifq); 69 m_freem(m0); 70 splx(s); 71 return (ENOBUFS); 72 } 73 IF_ENQUEUE(ifq, m0); 74 schednetisr(NETISR_IP); 75 break; 76 #endif 77 default: 78 splx(s); 79 printf("lo%d: can't handle af%d\n", ifp->if_unit, 80 dst->sa_family); 81 m_freem(m0); 82 return (EAFNOSUPPORT); 83 } 84 ifp->if_ipackets++; 85 splx(s); 86 return (0); 87 } 88 89 /* 90 * Process an ioctl request. 91 */ 92 loioctl(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 } 119