xref: /csrg-svn/sys/netiso/idrp_usrreq.c (revision 63222)
156888Ssklower /*
2*63222Sbostic  * Copyright (c) 1992, 1993
3*63222Sbostic  *	The Regents of the University of California.  All rights reserved.
456888Ssklower  *
556888Ssklower  * %sccs.include.redist.c%
656888Ssklower  *
7*63222Sbostic  *	@(#)idrp_usrreq.c	8.1 (Berkeley) 06/10/93
856888Ssklower  */
956888Ssklower 
1056888Ssklower #include <sys/param.h>
1156888Ssklower #include <sys/proc.h>
1256888Ssklower #include <sys/systm.h>
1356888Ssklower #include <sys/malloc.h>
1456888Ssklower #include <sys/mbuf.h>
1556888Ssklower #include <sys/socket.h>
1656888Ssklower #include <sys/socketvar.h>
1756888Ssklower #include <sys/protosw.h>
1856888Ssklower #include <sys/errno.h>
1956888Ssklower 
2056888Ssklower #include <net/route.h>
2156888Ssklower #include <net/if.h>
2256888Ssklower 
2356888Ssklower #include <netiso/argo_debug.h>
2456888Ssklower #include <netiso/iso.h>
2556888Ssklower #include <netiso/clnp.h>
2656888Ssklower #include <netiso/clnl.h>
2756888Ssklower #include <netiso/iso_pcb.h>
2856888Ssklower #include <netiso/iso_var.h>
2956888Ssklower 
3056888Ssklower int idrp_input();
3156888Ssklower struct	isopcb	idrp_isop;
3256888Ssklower static	struct	sockaddr_iso idrp_addrs[2] =
3356888Ssklower {  { sizeof(idrp_addrs), AF_ISO, }, { sizeof(idrp_addrs[1]), AF_ISO, } };
3456888Ssklower /*
3556888Ssklower  * IDRP initialization
3656888Ssklower  */
idrp_init()3756888Ssklower idrp_init()
3856888Ssklower {
3956888Ssklower 	extern struct clnl_protosw clnl_protox[256];
4056888Ssklower 
4156888Ssklower 	idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop;
4256888Ssklower 	idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr;
4356888Ssklower 	idrp_isop.isop_laddr = &idrp_isop.isop_sladdr;
4456888Ssklower 	idrp_isop.isop_sladdr = idrp_addrs[1];
4556888Ssklower 	idrp_isop.isop_sfaddr = idrp_addrs[1];
4656888Ssklower 	clnl_protox[ISO10747_IDRP].clnl_input = idrp_input;
4756888Ssklower }
4856888Ssklower 
4956888Ssklower /*
5056888Ssklower  * CALLED FROM:
5156888Ssklower  * 	tpclnp_input().
5256888Ssklower  * FUNCTION and ARGUMENTS:
5356888Ssklower  * Take a packet (m) from clnp, strip off the clnp header
5456888Ssklower  * and mke suitable for the idrp socket.
5556888Ssklower  * No return value.
5656888Ssklower  */
idrp_input(m,src,dst)5756888Ssklower idrp_input(m, src, dst)
5856888Ssklower 	register struct mbuf *m;
5956888Ssklower 	struct sockaddr_iso *src, *dst;
6056888Ssklower {
6156888Ssklower 	if (idrp_isop.isop_socket == 0) {
6256888Ssklower 	bad:	m_freem(m);
6356888Ssklower 		return 0;
6456888Ssklower 	}
6556888Ssklower 	bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data));
6656888Ssklower 	bcopy((caddr_t)&(src->siso_addr), (caddr_t)&idrp_addrs[0].siso_addr,
6756888Ssklower 		1 + src->siso_nlen);
6856888Ssklower 	bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data));
6956888Ssklower 	bcopy((caddr_t)&(dst->siso_addr), (caddr_t)&idrp_addrs[1].siso_addr,
7056888Ssklower 		1 + dst->siso_nlen);
7156888Ssklower 	if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
7256888Ssklower 		(struct sockaddr *)idrp_addrs, m, (struct mbuf *)0) == 0)
7356888Ssklower 		goto bad;
7456888Ssklower 	sorwakeup(idrp_isop.isop_socket);
7556888Ssklower 	return 0;
7656888Ssklower }
7756888Ssklower 
7856888Ssklower idrp_output(m, addr)
7956888Ssklower 	struct mbuf *m, *addr;
8056888Ssklower {
8156888Ssklower 	register struct sockaddr_iso *siso = mtod(addr, struct sockaddr_iso *);
8256888Ssklower 	int s = splnet(), i;
8356888Ssklower 
8456888Ssklower 	bcopy((caddr_t)&(siso->siso_addr),
8556888Ssklower 	      (caddr_t)&idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
8656888Ssklower 	siso++;
8756888Ssklower 	bcopy((caddr_t)&(siso->siso_addr),
8856888Ssklower 	      (caddr_t)&idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
8956888Ssklower 	i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
9056888Ssklower 	splx(s);
9156888Ssklower 	return (i);
9256888Ssklower }
9356888Ssklower 
9456888Ssklower u_long	idrp_sendspace = 3072;		/* really max datagram size */
9556888Ssklower u_long	idrp_recvspace = 40 * 1024;	/* 40 1K datagrams */
9656888Ssklower 
9756888Ssklower /*ARGSUSED*/
9856888Ssklower idrp_usrreq(so, req, m, addr, control)
9956888Ssklower 	struct socket *so;
10056888Ssklower 	int req;
10156888Ssklower 	struct mbuf *m, *addr, *control;
10256888Ssklower {
10356888Ssklower 	int error = 0;
10456888Ssklower 
10556888Ssklower 	 /* Note: need to block idrp_input while changing
10656888Ssklower 	 * the udp pcb queue and/or pcb addresses.
10756888Ssklower 	 */
10856888Ssklower 	switch (req) {
10956888Ssklower 
11056888Ssklower 	case PRU_ATTACH:
11156888Ssklower 		if (idrp_isop.isop_socket != NULL) {
11256888Ssklower 			error = ENXIO;
11356888Ssklower 			break;
11456888Ssklower 		}
11556888Ssklower 		idrp_isop.isop_socket = so;
11656888Ssklower 		error = soreserve(so, idrp_sendspace, idrp_recvspace);
11756888Ssklower 		break;
11856888Ssklower 
11956888Ssklower 	case PRU_SHUTDOWN:
12056888Ssklower 		socantsendmore(so);
12156888Ssklower 		break;
12256888Ssklower 
12356888Ssklower 	case PRU_SEND:
12456888Ssklower 		return (idrp_output(m, addr));
12556888Ssklower 
12656888Ssklower 	case PRU_ABORT:
12756888Ssklower 		soisdisconnected(so);
12856888Ssklower 	case PRU_DETACH:
12956888Ssklower 		idrp_isop.isop_socket = 0;
13056888Ssklower 		break;
13156888Ssklower 
13256888Ssklower 
13356888Ssklower 	case PRU_SENSE:
13456888Ssklower 		/*
13556888Ssklower 		 * stat: don't bother with a blocksize.
13656888Ssklower 		 */
13756888Ssklower 		return (0);
13856888Ssklower 
13956888Ssklower 	default:
14056888Ssklower 		return (EOPNOTSUPP);	/* do not free mbuf's */
14156888Ssklower 	}
14256888Ssklower 
14356888Ssklower release:
14456888Ssklower 	if (control) {
14556888Ssklower 		printf("idrp control data unexpectedly retained\n");
14656888Ssklower 		m_freem(control);
14756888Ssklower 	}
14856888Ssklower 	if (m)
14956888Ssklower 		m_freem(m);
15056888Ssklower 	return (error);
15156888Ssklower }
152