1*23170Smckusick /* 2*23170Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23170Smckusick * All rights reserved. The Berkeley software License Agreement 4*23170Smckusick * specifies the terms and conditions for redistribution. 5*23170Smckusick * 6*23170Smckusick * @(#)raw_imp.c 6.5 (Berkeley) 06/08/85 7*23170Smckusick */ 85637Sroot 917069Sbloom #include "param.h" 1017069Sbloom #include "mbuf.h" 1117069Sbloom #include "socket.h" 1217069Sbloom #include "protosw.h" 1317069Sbloom #include "socketvar.h" 1417069Sbloom #include "errno.h" 1510900Ssam 1610900Ssam #include "../net/if.h" 1713453Ssam #include "../net/route.h" 1810900Ssam #include "../net/raw_cb.h" 1910900Ssam 208401Swnj #include "../netinet/in.h" 218401Swnj #include "../netinet/in_systm.h" 2218414Skarels #include "../netinet/in_var.h" 2317069Sbloom #include "if_imp.h" 245637Sroot 255637Sroot /* 265637Sroot * Raw interface to IMP. 275637Sroot */ 285637Sroot 295637Sroot /* 305637Sroot * Generate IMP leader and pass packet to impoutput. 315637Sroot * The user must create a skeletal leader in order to 325637Sroot * communicate message type, message subtype, etc. 335637Sroot * We fill in holes where needed and verify parameters 345637Sroot * supplied by user. 355637Sroot */ 365847Sroot rimp_output(m, so) 375637Sroot register struct mbuf *m; 385637Sroot struct socket *so; 395637Sroot { 405637Sroot struct mbuf *n; 416509Ssam int len, error = 0; 425647Ssam register struct imp_leader *ip; 435637Sroot register struct sockaddr_in *sin; 445637Sroot register struct rawcb *rp = sotorawcb(so); 4518414Skarels struct in_ifaddr *ia; 465772Swnj struct control_leader *cp; 475637Sroot 485637Sroot /* 495637Sroot * Verify user has supplied necessary space 505637Sroot * for the leader and check parameters in it. 515637Sroot */ 525772Swnj if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) && 536509Ssam (m = m_pullup(m, sizeof(struct control_leader))) == 0) { 546509Ssam error = EMSGSIZE; /* XXX */ 556509Ssam goto bad; 566509Ssam } 575772Swnj cp = mtod(m, struct control_leader *); 585772Swnj if (cp->dl_mtype == IMPTYPE_DATA) 595772Swnj if (m->m_len < sizeof(struct imp_leader) && 606509Ssam (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { 616509Ssam error = EMSGSIZE; /* XXX */ 626509Ssam goto bad; 636509Ssam } 645647Ssam ip = mtod(m, struct imp_leader *); 656509Ssam if (ip->il_format != IMP_NFF) { 666509Ssam error = EMSGSIZE; /* XXX */ 675637Sroot goto bad; 686509Ssam } 695870Sroot #ifdef notdef 705647Ssam if (ip->il_link != IMPLINK_IP && 716509Ssam (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { 726509Ssam error = EPERM; 735637Sroot goto bad; 746509Ssam } 755870Sroot #endif 765637Sroot 775637Sroot /* 785637Sroot * Fill in IMP leader -- impoutput refrains from rebuilding 795637Sroot * the leader when it sees the protocol family PF_IMPLINK. 805637Sroot * (message size calculated by walking through mbuf's) 815637Sroot */ 825637Sroot for (len = 0, n = m; n; n = n->m_next) 835637Sroot len += n->m_len; 846161Ssam ip->il_length = htons((u_short)(len << 3)); 856509Ssam sin = (struct sockaddr_in *)&rp->rcb_faddr; 8618414Skarels imp_addr_to_leader(ip, sin->sin_addr.s_addr); /* BRL */ 876339Ssam /* no routing here */ 8818414Skarels ia = in_iaonnetof(in_netof(sin->sin_addr)); 8918414Skarels if (ia) 9018414Skarels return (impoutput(ia->ia_ifp, m, (struct sockaddr *)sin)); 916509Ssam error = ENETUNREACH; 925637Sroot bad: 935637Sroot m_freem(m); 946509Ssam return (error); 955637Sroot } 96