Commit | Line | Data |
---|---|---|
39344de3 | 1 | /* |
10cc936d KB |
2 | * Copyright (c) 1992, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
39344de3 KS |
4 | * |
5 | * %sccs.include.redist.c% | |
6 | * | |
10cc936d | 7 | * @(#)idrp_usrreq.c 8.1 (Berkeley) %G% |
39344de3 KS |
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 | } |