xref: /csrg-svn/sys/net/raw_cb.c (revision 34844)
123160Smckusick /*
229066Smckusick  * Copyright (c) 1980, 1986 Regents of the University of California.
333183Sbostic  * All rights reserved.
423160Smckusick  *
533183Sbostic  * Redistribution and use in source and binary forms are permitted
6*34844Sbostic  * provided that the above copyright notice and this paragraph are
7*34844Sbostic  * duplicated in all such forms and that any documentation,
8*34844Sbostic  * advertising materials, and other materials related to such
9*34844Sbostic  * distribution and use acknowledge that the software was developed
10*34844Sbostic  * by the University of California, Berkeley.  The name of the
11*34844Sbostic  * University may not be used to endorse or promote products derived
12*34844Sbostic  * from this software without specific prior written permission.
13*34844Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34844Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34844Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1633183Sbostic  *
17*34844Sbostic  *	@(#)raw_cb.c	7.6 (Berkeley) 06/27/88
1823160Smckusick  */
195635Sroot 
2017066Sbloom #include "param.h"
2117066Sbloom #include "systm.h"
2217066Sbloom #include "mbuf.h"
2317066Sbloom #include "socket.h"
2417066Sbloom #include "socketvar.h"
2521769Skarels #include "domain.h"
2621769Skarels #include "protosw.h"
2717066Sbloom #include "errno.h"
2810890Ssam 
2917066Sbloom #include "if.h"
3017066Sbloom #include "route.h"
3117066Sbloom #include "raw_cb.h"
3212783Ssam #include "../netinet/in.h"
335635Sroot 
3429922Skarels #include "../machine/mtpr.h"
3510890Ssam 
365635Sroot /*
375635Sroot  * Routines to manage the raw protocol control blocks.
385635Sroot  *
395635Sroot  * TODO:
405635Sroot  *	hash lookups by protocol family/protocol + address family
416339Ssam  *	take care of unique address problems per AF?
426045Swnj  *	redo address binding to allow wildcards
435635Sroot  */
445635Sroot 
455635Sroot /*
465635Sroot  * Allocate a control block and a nominal amount
475635Sroot  * of buffer space for the socket.
485635Sroot  */
4921769Skarels raw_attach(so, proto)
505635Sroot 	register struct socket *so;
5121769Skarels 	int proto;
525635Sroot {
535635Sroot 	struct mbuf *m;
545635Sroot 	register struct rawcb *rp;
555635Sroot 
569638Ssam 	m = m_getclr(M_DONTWAIT, MT_PCB);
575635Sroot 	if (m == 0)
585635Sroot 		return (ENOBUFS);
5934554Skarels 	if (sbreserve(&so->so_snd, (u_long) RAWSNDQ) == 0)
605635Sroot 		goto bad;
6134554Skarels 	if (sbreserve(&so->so_rcv, (u_long) RAWRCVQ) == 0)
625635Sroot 		goto bad2;
635635Sroot 	rp = mtod(m, struct rawcb *);
645635Sroot 	rp->rcb_socket = so;
655635Sroot 	so->so_pcb = (caddr_t)rp;
665635Sroot 	rp->rcb_pcb = 0;
6721769Skarels 	rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
6821769Skarels 	rp->rcb_proto.sp_protocol = proto;
6921769Skarels 	insque(rp, &rawcb);
705635Sroot 	return (0);
715635Sroot bad2:
725635Sroot 	sbrelease(&so->so_snd);
735635Sroot bad:
745635Sroot 	(void) m_free(m);
755635Sroot 	return (ENOBUFS);
765635Sroot }
775635Sroot 
785635Sroot /*
795635Sroot  * Detach the raw connection block and discard
805635Sroot  * socket resources.
815635Sroot  */
825635Sroot raw_detach(rp)
835635Sroot 	register struct rawcb *rp;
845635Sroot {
855635Sroot 	struct socket *so = rp->rcb_socket;
865635Sroot 
8724774Skarels 	if (rp->rcb_route.ro_rt)
8824774Skarels 		rtfree(rp->rcb_route.ro_rt);
895635Sroot 	so->so_pcb = 0;
905635Sroot 	sofree(so);
915635Sroot 	remque(rp);
9226035Skarels 	if (rp->rcb_options)
9329569Skarels 		m_freem(rp->rcb_options);
948975Sroot 	m_freem(dtom(rp));
955635Sroot }
965635Sroot 
975635Sroot /*
985635Sroot  * Disconnect and possibly release resources.
995635Sroot  */
1005635Sroot raw_disconnect(rp)
1015635Sroot 	struct rawcb *rp;
1025635Sroot {
1038975Sroot 
1046509Ssam 	rp->rcb_flags &= ~RAW_FADDR;
1057517Sroot 	if (rp->rcb_socket->so_state & SS_NOFDREF)
1065635Sroot 		raw_detach(rp);
1075635Sroot }
1085635Sroot 
1098394Swnj raw_bind(so, nam)
1108394Swnj 	register struct socket *so;
1118394Swnj 	struct mbuf *nam;
1128394Swnj {
1138394Swnj 	struct sockaddr *addr = mtod(nam, struct sockaddr *);
1148394Swnj 	register struct rawcb *rp;
1158394Swnj 
1168394Swnj 	if (ifnet == 0)
1178394Swnj 		return (EADDRNOTAVAIL);
1188394Swnj /* BEGIN DUBIOUS */
1198394Swnj 	/*
1208394Swnj 	 * Should we verify address not already in use?
1218394Swnj 	 * Some say yes, others no.
1228394Swnj 	 */
1238394Swnj 	switch (addr->sa_family) {
1248394Swnj 
12525647Skarels #ifdef INET
1268394Swnj 	case AF_IMPLINK:
12712783Ssam 	case AF_INET: {
1288394Swnj 		if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
12918409Skarels 		    ifa_ifwithaddr(addr) == 0)
1308394Swnj 			return (EADDRNOTAVAIL);
1318394Swnj 		break;
13212783Ssam 	}
13312783Ssam #endif
1348394Swnj 
1358394Swnj 	default:
1368394Swnj 		return (EAFNOSUPPORT);
1378394Swnj 	}
1388394Swnj /* END DUBIOUS */
1399184Ssam 	rp = sotorawcb(so);
1408394Swnj 	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
1418394Swnj 	rp->rcb_flags |= RAW_LADDR;
1428394Swnj 	return (0);
1438394Swnj }
1448394Swnj 
1455635Sroot /*
1465635Sroot  * Associate a peer's address with a
1475635Sroot  * raw connection block.
1485635Sroot  */
1498394Swnj raw_connaddr(rp, nam)
1505635Sroot 	struct rawcb *rp;
1518394Swnj 	struct mbuf *nam;
1525635Sroot {
1538394Swnj 	struct sockaddr *addr = mtod(nam, struct sockaddr *);
1548394Swnj 
1556509Ssam 	bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
1566509Ssam 	rp->rcb_flags |= RAW_FADDR;
1575635Sroot }
158