1 /* raw_pup.c 4.15 82/10/20 */ 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 "../netpup/pup.h" 9 #include "../net/raw_cb.h" 10 #include "../net/if.h" 11 #include <errno.h> 12 13 /* 14 * Raw PUP protocol interface. 15 */ 16 17 /* 18 * Encapsulate packet in PUP header which is supplied by the 19 * user. This is done to allow user to specify PUP identifier. 20 */ 21 rpup_output(m, so) 22 register struct mbuf *m; 23 struct socket *so; 24 { 25 register struct rawcb *rp = sotorawcb(so); 26 register struct pup_header *pup; 27 int len, error = 0; 28 struct mbuf *n; 29 struct sockaddr_pup *dst; 30 struct ifnet *ifp; 31 32 /* 33 * Verify user has supplied necessary space 34 * for the header and check parameters in it. 35 */ 36 if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct pup_header)) && 37 (m = m_pullup(m, sizeof(struct pup_header))) == 0) { 38 error = EMSGSIZE; /* XXX */ 39 goto bad; 40 } 41 pup = mtod(m, struct pup_header *); 42 if (pup->pup_type == 0) { 43 error = EPERM; /* XXX */ 44 goto bad; 45 } 46 if (pup->pup_tcontrol && (pup->pup_tcontrol & ~PUP_TRACE)) { 47 error = EPERM; /* XXX */ 48 goto bad; 49 } 50 for (len = 0, n = m; n; n = n->m_next) 51 len += n->m_len; 52 pup->pup_length = len; 53 #if vax || pdp11 || ns16032 54 pup->pup_length = htons(pup->pup_length); 55 #endif 56 /* assume user generates PUP checksum. */ 57 dst = (struct sockaddr_pup *)&rp->rcb_faddr; 58 pup->pup_dport = dst->spup_addr; 59 ifp = if_ifonnetof((int)pup->pup_dnet); 60 if (ifp) { 61 if (rp->rcb_flags & RAW_LADDR) { 62 register struct sockaddr_pup *src; 63 64 src = (struct sockaddr_pup *)&rp->rcb_laddr; 65 pup->pup_sport = src->spup_addr; 66 } else { 67 pup->pup_snet = ifp->if_net; 68 pup->pup_shost = ifp->if_host[0]; 69 /* socket is specified by user */ 70 } 71 return ((*ifp->if_output)(ifp, m, (struct sockaddr *)dst)); 72 } 73 error = ENETUNREACH; 74 bad: 75 m_freem(m); 76 return (error); 77 } 78