1*6045Swnj /* raw_pup.c 4.6 82/03/05 */ 25671Ssam 35671Ssam #include "../h/param.h" 45671Ssam #include "../h/mbuf.h" 55671Ssam #include "../h/socket.h" 65671Ssam #include "../h/protosw.h" 75671Ssam #include "../h/socketvar.h" 85671Ssam #include "../net/in.h" 95671Ssam #include "../net/in_systm.h" 105671Ssam #include "../net/pup.h" 115671Ssam #include "../net/raw_cb.h" 12*6045Swnj #include "../net/if.h" 136040Sroot #include "../errno.h" 145671Ssam 155671Ssam /* 165671Ssam * Raw PUP protocol interface. 175671Ssam */ 185671Ssam 195671Ssam /*ARGSUSED*/ 205847Sroot rpup_ctlinput(m) 215671Ssam struct mbuf *m; 225671Ssam { 235847Sroot COUNT(RPUP_CTLINPUT); 245671Ssam } 255671Ssam 265671Ssam /* 275671Ssam * Encapsulate packet in PUP header which is supplied by the 285671Ssam * user. This is done to allow user to specify PUP identifier. 295671Ssam */ 30*6045Swnj rpup_output(m, so) 31*6045Swnj register struct mbuf *m; 325671Ssam struct socket *so; 335671Ssam { 345671Ssam register struct rawcb *rp = sotorawcb(so); 355671Ssam register struct pup_header *pup; 365671Ssam int len; 375671Ssam struct mbuf *n; 385671Ssam struct sockaddr_pup *spup; 396027Ssam struct ifnet *ifp; 405671Ssam 415847Sroot COUNT(RPUP_OUTPUT); 425671Ssam /* 435671Ssam * Verify user has supplied necessary space 445671Ssam * for the header and check parameters in it. 455671Ssam */ 465671Ssam if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct pup_header)) && 47*6045Swnj (m = m_pullup(m, sizeof(struct pup_header))) == 0) 485671Ssam goto bad; 495671Ssam pup = mtod(m, struct pup_header *); 505671Ssam if (pup->pup_type == 0) 515671Ssam goto bad; 525671Ssam if (pup->pup_tcontrol && (pup->pup_tcontrol & ~PUP_TRACE)) 535671Ssam goto bad; 545671Ssam for (len = 0, n = m; n; n = n->m_next) 555671Ssam len += n->m_len; 565671Ssam pup->pup_length = len; 575671Ssam spup = (struct sockaddr_pup *)&rp->rcb_addr; 585671Ssam pup->pup_dport = spup->spup_addr; 595671Ssam 605671Ssam /* 615671Ssam * Insure proper source address is included. 625671Ssam */ 63*6045Swnj spup = (struct sockadrr_pup *)&(rp->rcb_socket->so_addr); 645671Ssam pup->pup_sport = spup->spup_addr; 655671Ssam /* for now, assume user generates PUP checksum. */ 665671Ssam 676027Ssam ifp = if_ifonnetof(&rp->rcb_addr); 686027Ssam if (ifp == 0) { 696027Ssam ifp = if_gatewayfor(&rp->rcb_addr); 706027Ssam if (ifp == 0) 716027Ssam goto bad; 726027Ssam } 735671Ssam return (enoutput((struct ifnet *)rp->rcb_pcb, m, PF_PUP)); 745671Ssam 755671Ssam bad: 765671Ssam m_freem(m); 775671Ssam return (0); 785671Ssam } 79