1 /* raw_pup.c 4.3 82/02/15 */ 2 3 #include "../h/param.h" 4 #include "../h/mbuf.h" 5 #include "../h/socket.h" 6 #include "../h/protosw.h" 7 #include "../h/socketvar.h" 8 #include "../net/in.h" 9 #include "../net/in_systm.h" 10 #include "../net/pup.h" 11 #include "../net/raw_cb.h" 12 #include "/usr/include/errno.h" 13 14 /* 15 * Raw PUP protocol interface. 16 */ 17 18 static struct sockaddr_pup pupsrc = { AF_PUP }; 19 static struct sockaddr_pup pupdst = { AF_PUP }; 20 static struct sockproto pupproto = { PF_PUP }; 21 22 /* 23 * Setup generic address and protocol structures 24 * for raw_input routine, then pass them along with 25 * mbuf chain. 26 */ 27 rpup_input(m) 28 struct mbuf *m; 29 { 30 register struct pup_header *pup = mtod(m, struct pup_header *); 31 32 COUNT(RAWPUP_INPUT); 33 pupproto.sp_protocol = pup->pup_type; 34 pupdst.spup_addr = pup->pup_daddr; 35 pupsrc.spup_addr = pup->pup_saddr; 36 raw_input(m, &pupproto, &pupdst, &pupsrc); 37 } 38 39 /*ARGSUSED*/ 40 rpup_ctlinput(m) 41 struct mbuf *m; 42 { 43 COUNT(RPUP_CTLINPUT); 44 } 45 46 /* 47 * Encapsulate packet in PUP header which is supplied by the 48 * user. This is done to allow user to specify PUP identifier. 49 */ 50 rpup_output(m0, so) 51 struct mbuf *m0; 52 struct socket *so; 53 { 54 register struct rawcb *rp = sotorawcb(so); 55 register struct pup_header *pup; 56 int len; 57 struct mbuf *n; 58 struct sockaddr_pup *spup; 59 60 COUNT(RPUP_OUTPUT); 61 /* 62 * Verify user has supplied necessary space 63 * for the header and check parameters in it. 64 */ 65 if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct pup_header)) && 66 (m = m_pullup(m, sizeof(struct pup_header)) == 0) { 67 goto bad; 68 pup = mtod(m, struct pup_header *); 69 if (pup->pup_type == 0) 70 goto bad; 71 if (pup->pup_tcontrol && (pup->pup_tcontrol & ~PUP_TRACE)) 72 goto bad; 73 for (len = 0, n = m; n; n = n->m_next) 74 len += n->m_len; 75 pup->pup_length = len; 76 spup = (struct sockaddr_pup *)&rp->rcb_addr; 77 pup->pup_dport = spup->spup_addr; 78 79 /* 80 * Insure proper source address is included. 81 */ 82 spup = (struct sockadrr_pup *)rp->rcb_socket->so_addr; 83 pup->pup_sport = spup->spup_addr; 84 /* for now, assume user generates PUP checksum. */ 85 86 if (rp->rcb_pcb == 0) /* XXX */ 87 panic("rawpup_output"); 88 return (enoutput((struct ifnet *)rp->rcb_pcb, m, PF_PUP)); 89 90 bad: 91 m_freem(m); 92 return (0); 93 } 94 95 /* 96 * Intercept connects and sends to verify interface 97 * exists for destination address. Disconnects are 98 * also looked at to insure pointer is invalidated. 99 */ 100 rpup_usrreq(so, req, m, addr) 101 struct socket *so; 102 int req; 103 struct mbuf *m; 104 caddr_t addr; 105 { 106 register struct rawcb *rp = sotorawcb(so); 107 108 COUNT(RPUP_USRREQ); 109 if (rp == 0 && req != PRU_ATTACH) 110 return (EINVAL); 111 112 switch (req) { 113 114 /* 115 * Verify address has an interface to go with it 116 * and record information for use in output routine. 117 */ 118 case PRU_SEND: 119 case PRU_CONNECT: { 120 register struct sockaddr_pup *spup; 121 register struct ifnet *ifp; 122 123 spup = (struct sockaddr_pup *)addr; 124 ifp = if_ifonnetof(spup->spup_addr); 125 if (ifp == 0) { 126 ifp = if_gatewayfor(spup->spup_addr); 127 if (ifp == 0) 128 return (EADDRNOTAVAIL); /* XXX */ 129 } 130 rp->rcb_pcb = (caddr_t)ifp; 131 break; 132 } 133 134 case PRU_DISCONNECT: 135 rp->rcb_pcb = 0; 136 break; 137 138 case PRU_CONTROL: 139 return (EOPNOTSUPP); 140 } 141 return (raw_usrreq(so, req, m, addr)); 142 } 143