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 */
idrp_init()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 */
idrp_input(m,src,dst)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