1 /* This file is bootstrapped from the RX release cleared by Transarc legal
2 in 1994, available from ftp.dementia.org/pub/rx
11 #include "rx/rx_kcommon.h"
16 /* Define this here, used externally */
17 #ifdef RX_ENABLE_LOCKS
23 * XXX The following is needed since the include file that contains them (<net/cko.h>)
24 * isn't part of a binary distribution!! XXXX
27 /* CKO_PSEUDO : Account for pseudo_header in the checksum */
29 #define CKO_SUM_MASK 0xffff /* sum is in lower 16 bits */
33 #define CKO_PSEUDO(sum, m, hdr) { \
34 (sum) = 0xffff ^ in_3sum( ((struct ipovly *)(hdr))->ih_src.s_addr, \
35 ((struct ipovly *)(hdr))->ih_dst.s_addr, \
36 ((struct ipovly *)(hdr))->ih_len \
37 + (((struct ipovly *)(hdr))->ih_pr<<16) \
38 + ((m)->m_quad[MQ_CKO_IN] & CKO_SUM_MASK)); \
42 static struct protosw parent_proto
; /* udp proto switch */
54 /* do rx fasttimo processing here */
55 rxevent_RaiseEvents(&temp
);
56 USERPRI
; /* should this be after the call to tproc? */
57 if (tproc
= parent_proto
.pr_fasttimo
)
64 /* hybrid of IRIX/knet.c and rx_kern.c */
65 /* XXX should this be listener or !listener? */
66 #if !defined(RXK_LISTENER_ENV)
67 /* start intercepting basic calls */
71 struct protosw
*tpro
, *last
;
75 last
= inetdomain
.dom_protoswNPROTOSW
;
76 for (tpro
= inetdomain
.dom_protosw
; tpro
< last
; tpro
++) {
77 if (tpro
->pr_protocol
== IPPROTO_UDP
) {
78 /* force UDP checksumming on for AFS */
81 memcpy(&parent_proto
, tpro
, sizeof(parent_proto
));
82 tpro
->pr_input
= rxk_input
;
83 tpro
->pr_fasttimo
= rxk_fasttimo
;
88 osi_Panic("inet:no udp");
91 /* basic packet handling routine called at splnet from softnet loop */
93 rxk_input(struct mbuf
*am
, struct ifnet
*aif
)
100 struct udpiphdr
*tvu
;
104 struct sockaddr_in taddr
;
108 unsigned int comp_sum
;
112 /* make sure we have base ip and udp headers in first mbuf */
113 if (am
->m_off
> MMAXOFF
|| am
->m_len
< 28) {
114 am
= m_pullup(am
, 28);
119 hdr
= (mtod(am
, struct ip
*))->ip_hl
;
121 /* pull up more, the IP hdr is bigger than usual */
122 if (am
->m_len
< (8 + (hdr
<< 2))) {
123 am
= m_pullup(am
, 8 + (hdr
<< 2));
128 ti
= mtod(am
, struct ip
*); /* recompute, since m_pullup allocates new mbuf */
129 tu
= (struct udphdr
*)(((char *)ti
) + (hdr
<< 2)); /* skip ip hdr */
131 ti
= mtod(am
, struct ip
*);
132 tu
= (struct udphdr
*)(((char *)ti
) + 20); /* skip basic ip hdr */
134 /* now read the port out */
138 for (tsp
= ports
, i
= 0; i
< MAXRXPORTS
; i
++) {
139 if (*tsp
++ == port
) {
140 /* checksum the packet */
141 ip_stripoptions(ti
, NULL
); /* get rid of anything we don't need */
142 /* deliver packet to rx */
143 taddr
.sin_family
= AF_INET
; /* compute source address */
144 taddr
.sin_port
= tu
->uh_sport
;
145 taddr
.sin_addr
.s_addr
= ti
->ip_src
.s_addr
;
147 /* handle the checksum. Note that this code damages the actual ip
148 * header (replacing it with the virtual one, which is the same
149 * size), so we must ensure we get everything out we need, first */
150 tvu
= (struct udpiphdr
*)ti
; /* virtual udp structure, for ck
152 if (tu
->uh_sum
!= 0) {
153 /* if the checksum is there, always check it. It's crazy not
154 * to, unless you can really be sure that your
155 * underlying network (and interfaces and drivers and
156 * DMA hardware, etc!) is error-free. First, fill
157 * in entire virtual ip header. */
161 tvu
->ui_len
= tvu
->ui_ulen
;
162 tlen
= ntohs((unsigned short)(tvu
->ui_ulen
));
163 /* HP: checksum assist for cksum offloading drivers */
164 if (am
->m_flags
& MF_CKO_IN
) {
165 CKO_PSEUDO(comp_sum
, am
, tvu
);
169 comp_sum
= in_cksum(am
, sizeof(struct ip
) + tlen
);
170 for (m1
= am
; m1
; m1
= m1
->m_next
)
171 m1
->m_flags
&= ~MF_NOACC
;
174 /* checksum, including cksum field, doesn't come out 0, so
175 * this packet is bad */
182 * 28 is IP (20) + UDP (8) header. ulen includes
183 * udp header, and we *don't* tell RX about udp
184 * header either. So, we remove those 8 as well.
186 data_len
= ntohs(tu
->uh_ulen
);
189 if (!(*rxk_GetPacketProc
) (&phandle
, data_len
)) {
190 if (rx_mb_to_packet(am
, m_freem
, 28, data_len
, phandle
)) {
191 /* XXX should just increment counter here.. */
192 printf("rx: truncated UDP packet\n");
193 rxi_FreePacket(phandle
);
195 (*rxk_PacketArrivalProc
) (phandle
, &taddr
,
196 portRocks
[i
], data_len
);
205 /* if we get here, try to deliver packet to udp */
206 if (tproc
= parent_proto
.pr_input
) {
207 code
= (*tproc
) (am
, aif
);
214 #endif /* ! RXK_LISTENER_ENV */
216 /* steal decl from sgi_65 */
218 osi_NetSend(struct socket
*asocket
, struct sockaddr_in
*addr
,
219 struct iovec
*dvec
, int nvec
, afs_int32 asize
,
224 struct iovec temp
[RX_MAXWVECS
];
226 int size
= sizeof(struct sockaddr_in
);
228 memset(&uio
, 0, sizeof(uio
));
229 memset(&temp
, 0, sizeof(temp
));
231 /* Guess based on rxk_NewSocket */
232 bp
= allocb((size
+ SO_MSGOFFSET
+ 1), BPRI_MED
);
235 memcpy((caddr_t
) bp
->b_rptr
+ SO_MSGOFFSET
, (caddr_t
) addr
, size
);
236 bp
->b_wptr
= bp
->b_rptr
+ (size
+ SO_MSGOFFSET
+ 1);
238 memcpy((caddr_t
) temp
, (caddr_t
) dvec
, nvec
* sizeof(struct iovec
));
240 /* devresource.hp.com/Drivers/Docs/Refs/11i/ddRef/Chap02R.pdf has details
242 memset((caddr_t
) & uio
, 0, sizeof(uio
));
243 uio
.uio_resid
= asize
;
245 uio
.uio_iovcnt
= nvec
;
246 uio
.uio_seg
= UIOSEG_KERNEL
;
248 code
= sosend(asocket
, bp
, &uio
, 0, 0, 0, size
);
252 /* pattern from IRIX */
253 #if defined(RXK_LISTENER_ENV)
255 osi_NetReceive(osi_socket so
, struct sockaddr_in
*addr
, struct iovec
*dvec
,
256 int nvecs
, int *alength
)
260 struct iovec tmpvec
[RX_MAXWVECS
+ 2];
264 memset(&tuio
, 0, sizeof(tuio
));
265 memset(&tmpvec
, 0, sizeof(tempvec
));
267 if (nvecs
> RX_MAXWVECS
+ 2) {
268 osi_Panic("Too many (%d) iovecs passed to osi_NetReceive\n", nvecs
);
270 memcpy(tmpvec
, (char *)dvec
,
271 nvecs
/*(RX_MAXWVECS+1) */ * sizeof(struct iovec
));
272 tuio
.uio_iov
= tmpvec
;
273 tuio
.uio_iovcnt
= nvecs
;
274 tuio
.uio_fpflags
= 0;
276 tuio
.uio_seg
= UIOSEG_KERNEL
;
277 tuio
.uio_resid
= *alength
;
279 code
= soreceive(so
, &bp
, &tuio
, &flags
, &sp
, (MBLKPP
) NULL
);
281 *alength
= *alength
- tuio
.uio_resid
;
283 memcpy((char *)addr
, (char *)bp
->b_rptr
,
284 sizeof(struct sockaddr_in
));