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