xref: /original-bsd/sys/netiso/idrp_usrreq.c (revision 3705696b)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)idrp_usrreq.c	8.1 (Berkeley) 06/10/93
8  */
9 
10 #include <sys/param.h>
11 #include <sys/proc.h>
12 #include <sys/systm.h>
13 #include <sys/malloc.h>
14 #include <sys/mbuf.h>
15 #include <sys/socket.h>
16 #include <sys/socketvar.h>
17 #include <sys/protosw.h>
18 #include <sys/errno.h>
19 
20 #include <net/route.h>
21 #include <net/if.h>
22 
23 #include <netiso/argo_debug.h>
24 #include <netiso/iso.h>
25 #include <netiso/clnp.h>
26 #include <netiso/clnl.h>
27 #include <netiso/iso_pcb.h>
28 #include <netiso/iso_var.h>
29 
30 int idrp_input();
31 struct	isopcb	idrp_isop;
32 static	struct	sockaddr_iso idrp_addrs[2] =
33 {  { sizeof(idrp_addrs), AF_ISO, }, { sizeof(idrp_addrs[1]), AF_ISO, } };
34 /*
35  * IDRP initialization
36  */
37 idrp_init()
38 {
39 	extern struct clnl_protosw clnl_protox[256];
40 
41 	idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop;
42 	idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr;
43 	idrp_isop.isop_laddr = &idrp_isop.isop_sladdr;
44 	idrp_isop.isop_sladdr = idrp_addrs[1];
45 	idrp_isop.isop_sfaddr = idrp_addrs[1];
46 	clnl_protox[ISO10747_IDRP].clnl_input = idrp_input;
47 }
48 
49 /*
50  * CALLED FROM:
51  * 	tpclnp_input().
52  * FUNCTION and ARGUMENTS:
53  * Take a packet (m) from clnp, strip off the clnp header
54  * and mke suitable for the idrp socket.
55  * No return value.
56  */
57 idrp_input(m, src, dst)
58 	register struct mbuf *m;
59 	struct sockaddr_iso *src, *dst;
60 {
61 	if (idrp_isop.isop_socket == 0) {
62 	bad:	m_freem(m);
63 		return 0;
64 	}
65 	bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data));
66 	bcopy((caddr_t)&(src->siso_addr), (caddr_t)&idrp_addrs[0].siso_addr,
67 		1 + src->siso_nlen);
68 	bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data));
69 	bcopy((caddr_t)&(dst->siso_addr), (caddr_t)&idrp_addrs[1].siso_addr,
70 		1 + dst->siso_nlen);
71 	if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
72 		(struct sockaddr *)idrp_addrs, m, (struct mbuf *)0) == 0)
73 		goto bad;
74 	sorwakeup(idrp_isop.isop_socket);
75 	return 0;
76 }
77 
78 idrp_output(m, addr)
79 	struct mbuf *m, *addr;
80 {
81 	register struct sockaddr_iso *siso = mtod(addr, struct sockaddr_iso *);
82 	int s = splnet(), i;
83 
84 	bcopy((caddr_t)&(siso->siso_addr),
85 	      (caddr_t)&idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
86 	siso++;
87 	bcopy((caddr_t)&(siso->siso_addr),
88 	      (caddr_t)&idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
89 	i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
90 	splx(s);
91 	return (i);
92 }
93 
94 u_long	idrp_sendspace = 3072;		/* really max datagram size */
95 u_long	idrp_recvspace = 40 * 1024;	/* 40 1K datagrams */
96 
97 /*ARGSUSED*/
98 idrp_usrreq(so, req, m, addr, control)
99 	struct socket *so;
100 	int req;
101 	struct mbuf *m, *addr, *control;
102 {
103 	int error = 0;
104 
105 	 /* Note: need to block idrp_input while changing
106 	 * the udp pcb queue and/or pcb addresses.
107 	 */
108 	switch (req) {
109 
110 	case PRU_ATTACH:
111 		if (idrp_isop.isop_socket != NULL) {
112 			error = ENXIO;
113 			break;
114 		}
115 		idrp_isop.isop_socket = so;
116 		error = soreserve(so, idrp_sendspace, idrp_recvspace);
117 		break;
118 
119 	case PRU_SHUTDOWN:
120 		socantsendmore(so);
121 		break;
122 
123 	case PRU_SEND:
124 		return (idrp_output(m, addr));
125 
126 	case PRU_ABORT:
127 		soisdisconnected(so);
128 	case PRU_DETACH:
129 		idrp_isop.isop_socket = 0;
130 		break;
131 
132 
133 	case PRU_SENSE:
134 		/*
135 		 * stat: don't bother with a blocksize.
136 		 */
137 		return (0);
138 
139 	default:
140 		return (EOPNOTSUPP);	/* do not free mbuf's */
141 	}
142 
143 release:
144 	if (control) {
145 		printf("idrp control data unexpectedly retained\n");
146 		m_freem(control);
147 	}
148 	if (m)
149 		m_freem(m);
150 	return (error);
151 }
152