netsend-proto-and-obsd-includes-20021010
[openafs.git] / src / rx / SOLARIS / rx_knet.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include "../afs/param.h"
12
13 RCSID("$Header$");
14
15 #ifdef AFS_SUN5_ENV
16 #include "../rx/rx_kcommon.h"
17
18
19 #ifdef AFS_SUN56_ENV
20
21 #include "../inet/common.h"
22 #include "../sys/tiuser.h"
23 #include "../sys/t_kuser.h"
24 #include "../sys/stropts.h"
25 #include "../sys/stream.h"
26 #include "../sys/tihdr.h"
27 #include "../sys/fcntl.h"
28 #ifdef AFS_SUN58_ENV
29 #include "../netinet/ip6.h"
30 #define ipif_local_addr ipif_lcl_addr
31 #ifndef V4_PART_OF_V6
32 #define V4_PART_OF_V6(v6)       v6.s6_addr32[3]
33 #endif
34 #endif
35 #include "../inet/ip.h"
36 #include "../inet/ip_if.h"
37 #include "../netinet/udp.h"
38
39 /*
40  * Function pointers for kernel socket routines
41  */
42 struct sonode *(*sockfs_socreate)
43     (vnode_t *, int, int, int, int, struct sonode *, int *) = NULL;
44 struct vnode *(*sockfs_solookup)
45     (int, int, int, char *, int *) = NULL;
46 int (*sockfs_sobind)
47     (struct sonode *, struct sockaddr *, int, int, int) = NULL;
48 int (*sockfs_sorecvmsg)
49     (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
50 int (*sockfs_sosendmsg)
51     (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
52 int (*sockfs_sosetsockopt)
53     (struct sonode *, int, int, void *, int) = NULL;
54 int (*sockfs_sounbind)
55     (struct sonode *, int);
56 void (*sockfs_sockfree)
57     (struct sonode *);
58
59 static afs_uint32 myNetAddrs[ADDRSPERSITE];
60 static int myNetMTUs[ADDRSPERSITE];
61 static int numMyNetAddrs = 0;
62
63 int
64 rxi_GetIFInfo()
65 {
66     int i = 0;
67     int different = 0;
68
69     ill_t *ill;
70     ipif_t *ipif;
71     int rxmtu, maxmtu;
72
73     int mtus[ADDRSPERSITE];
74     afs_uint32 addrs[ADDRSPERSITE];
75     afs_uint32 ifinaddr;
76
77     memset(mtus, 0, sizeof(mtus));
78     memset(addrs, 0, sizeof(addrs));
79
80     for (ill = ill_g_head; ill; ill = ill->ill_next) {
81 #ifdef AFS_SUN58_ENV
82         /* Make sure this is an IPv4 ILL */
83         if (ill->ill_isv6) continue;
84 #endif
85
86         /* Iterate over all the addresses on this ILL */
87         for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
88             if (i >= ADDRSPERSITE) break;
89
90             /* Ignore addresses which are down.. */
91             if (!(ipif->ipif_flags & IFF_UP)) continue;
92
93             /* Compute the Rx interface MTU */
94             rxmtu = (ipif->ipif_mtu - RX_IPUDP_SIZE);
95
96             ifinaddr = ntohl(ipif->ipif_local_addr);
97             if (myNetAddrs[i] != ifinaddr)
98                 different++;
99
100             /* Copy interface MTU and address; adjust maxmtu */
101             mtus[i] = rxmtu;
102             rxmtu = rxi_AdjustIfMTU(rxmtu);
103             maxmtu = rxmtu * rxi_nRecvFrags + ((rxi_nRecvFrags-1) *
104                                                UDP_HDR_SIZE);
105             maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu);
106             addrs[i] = ifinaddr;
107             i++;
108
109             if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) {
110                 rx_maxReceiveSize = MIN( RX_MAX_PACKET_SIZE, maxmtu);
111                 rx_maxReceiveSize = MIN( rx_maxReceiveSize,
112                                          rx_maxReceiveSizeUser);
113             }
114         }
115     }
116
117     rx_maxJumboRecvSize = RX_HEADER_SIZE +
118                           rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
119                           (rxi_nDgramPackets-1) * RX_JUMBOHEADERSIZE;
120     rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize);
121
122     if (different) {
123         int j;
124
125         for (j = 0; j < i; j++) {
126             myNetMTUs[j] = mtus[j];
127             myNetAddrs[j] = addrs[j];
128         }
129     }
130
131     return different;
132 }
133
134 int rxi_FindIfMTU(afs_uint32 addr)
135 {
136     ill_t *ill;
137     ipif_t *ipif;
138     afs_uint32 myAddr, netMask;
139     int match_value = 0;
140     int mtu = -1;
141
142     if (numMyNetAddrs == 0)
143         rxi_GetIFInfo();
144     myAddr = ntohl(addr);
145
146     if      (IN_CLASSA(myAddr)) netMask = IN_CLASSA_NET;
147     else if (IN_CLASSB(myAddr)) netMask = IN_CLASSB_NET;
148     else if (IN_CLASSC(myAddr)) netMask = IN_CLASSC_NET;
149     else                       netMask = 0;
150
151     for (ill = ill_g_head; ill; ill = ill->ill_next) {
152 #ifdef AFS_SUN58_ENV
153         /* Make sure this is an IPv4 ILL */
154         if (ill->ill_isv6) continue;
155 #endif
156
157         /* Iterate over all the addresses on this ILL */
158         for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
159             afs_uint32 thisAddr, subnetMask;
160             int thisMtu;
161
162             thisAddr   = ipif->ipif_local_addr;
163             subnetMask = ipif->ipif_net_mask;
164             thisMtu    = ipif->ipif_mtu;
165
166             if ((myAddr & netMask) == (thisAddr & netMask)) {
167                 if ((myAddr & subnetMask) == (thisAddr & subnetMask)) {
168                     if (myAddr == thisAddr) {
169                         match_value = 4;
170                         mtu = thisMtu;
171                     }
172
173                     if (match_value < 3) {
174                         match_value = 3;
175                         mtu = thisMtu;
176                     }
177                 }
178
179                 if (match_value < 2) {
180                     match_value = 2;
181                     mtu = thisMtu;
182                 }
183             }
184         }
185     }
186
187     return mtu;
188 }
189
190 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
191  * afs_osinet.c. 
192  */
193
194 struct sockaddr_in rx_sockaddr;
195
196 /* Allocate a new socket at specified port in network byte order. */
197 struct osi_socket *rxk_NewSocket(short aport)
198 {
199     vnode_t *accessvp;
200     struct sonode *so;
201     struct sockaddr_in addr;
202     int error;
203     int len;
204
205     AFS_STATCNT(osi_NewSocket);
206
207     if (sockfs_solookup == NULL) {
208         sockfs_solookup = (struct vnode *(*)())modlookup("sockfs", "solookup");
209         if (sockfs_solookup == NULL) {
210             return NULL;
211         }
212     }
213     if (sockfs_socreate == NULL) {
214         sockfs_socreate = (struct sonode *(*)())modlookup("sockfs", "socreate");
215         if (sockfs_socreate == NULL) {
216             return NULL;
217         }
218     }
219     if (sockfs_sobind == NULL) {
220         sockfs_sobind = (int (*)())modlookup("sockfs", "sobind");
221         if (sockfs_sobind == NULL) {
222             return NULL;
223         }
224     }
225     if (sockfs_sosetsockopt == NULL) {
226         sockfs_sosetsockopt = (int (*)())modlookup("sockfs", "sosetsockopt");
227         if (sockfs_sosetsockopt == NULL) {
228             return NULL;
229         }
230     }
231     if (sockfs_sosendmsg == NULL) {
232         sockfs_sosendmsg = (int (*)())modlookup("sockfs", "sosendmsg");
233         if (sockfs_sosendmsg == NULL) {
234             return NULL;
235         }
236     }
237     if (sockfs_sorecvmsg == NULL) {
238         sockfs_sorecvmsg = (int (*)())modlookup("sockfs", "sorecvmsg");
239         if (sockfs_sorecvmsg == NULL) {
240             return NULL;
241         }
242     }
243     if (sockfs_sounbind == NULL) {
244         sockfs_sounbind = (int (*)())modlookup("sockfs", "sounbind");
245         if (sockfs_sounbind == NULL)
246             return NULL;
247     }
248     if (sockfs_sockfree == NULL) {
249         sockfs_sockfree = (void (*)())modlookup("sockfs", "sockfree");
250         if (sockfs_sockfree == NULL)
251             return NULL;
252     }
253
254     accessvp = sockfs_solookup(AF_INET, SOCK_DGRAM, 0, "/dev/udp", &error);
255     if (accessvp == NULL) {
256         return NULL;
257     }
258
259     so = sockfs_socreate(accessvp, AF_INET, SOCK_DGRAM, 0,
260                          SOV_STREAM, NULL, &error);
261     if (so == NULL) {
262         return NULL;
263     }
264
265     addr.sin_family = AF_INET;
266     addr.sin_port = aport;
267     addr.sin_addr.s_addr = INADDR_ANY;
268     error = sockfs_sobind(so, (struct sockaddr *)&addr, sizeof(addr), 0, 0);
269     if (error != 0) {
270         return NULL;
271     }
272
273     len = rx_UdpBufSize;
274     error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len));
275     if (error != 0) {
276         return NULL;
277     }
278
279     len = rx_UdpBufSize;
280     error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
281     if (error != 0) {
282         return NULL;
283     }
284
285     return (struct osi_socket *)so;
286 }
287
288 int osi_FreeSocket(register struct osi_socket *asocket)
289 {
290     extern int rxk_ListenerPid;
291     struct sonode *so = (struct sonode *)asocket;
292     struct sockaddr_in taddr;
293     struct iovec dvec;
294     char c;
295
296     AFS_STATCNT(osi_FreeSocket);
297
298     taddr.sin_family = AF_INET;
299     taddr.sin_port = htons(rx_port);
300     taddr.sin_addr.s_addr = htonl(0x7f000001);
301
302     dvec.iov_base = &c;
303     dvec.iov_len = 1;
304
305     while (rxk_ListenerPid) {
306         osi_NetSend(rx_socket, &taddr, &dvec, 1, 1, 0);
307         afs_osi_Sleep(&rxk_ListenerPid);
308     }
309
310     sockfs_sounbind(so, 0);
311     sockfs_sockfree(so);
312     return 0;
313 }
314
315 int osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, 
316         struct iovec *dvec, int nvecs, afs_int32 asize, int istack) 
317 {
318     struct sonode *so = (struct sonode *)asocket;
319     struct nmsghdr msg;
320     struct uio uio;
321     struct iovec iov[RX_MAXIOVECS];
322     int error;
323     int i;
324  
325     if (nvecs > RX_MAXIOVECS) {
326         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
327     }
328
329     msg.msg_name = (struct sockaddr *)addr;
330     msg.msg_namelen = sizeof(struct sockaddr_in);
331     msg.msg_iov = dvec;
332     msg.msg_iovlen = nvecs;
333     msg.msg_control = NULL;
334     msg.msg_controllen = 0;
335     msg.msg_flags = 0;
336
337     for (i = 0 ; i < nvecs ; i++) {
338         iov[i].iov_base = dvec[i].iov_base;
339         iov[i].iov_len = dvec[i].iov_len;
340     }
341     uio.uio_iov = &iov[0];
342     uio.uio_iovcnt = nvecs;
343     uio.uio_loffset = 0;
344     uio.uio_segflg = UIO_SYSSPACE;
345     uio.uio_fmode = FREAD|FWRITE;
346     uio.uio_limit = 0;
347     uio.uio_resid = asize;
348
349     error = sockfs_sosendmsg(so, &msg, &uio);
350
351     return error;
352 }
353
354 int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
355         int nvecs, int *alength)
356 {  
357     struct sonode *asocket = (struct sonode *)so;
358     struct nmsghdr msg;
359     struct uio uio;
360     struct iovec iov[RX_MAXIOVECS];
361     int error;
362     int i;
363  
364     if (nvecs > RX_MAXIOVECS) {
365         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
366     }
367
368     msg.msg_name = NULL;
369     msg.msg_namelen = sizeof(struct sockaddr_in);
370     msg.msg_iov = NULL;
371     msg.msg_iovlen = 0;
372     msg.msg_control = NULL;
373     msg.msg_controllen = 0;
374     msg.msg_flags = 0;
375
376     for (i = 0 ; i < nvecs ; i++) {
377         iov[i].iov_base = dvec[i].iov_base;
378         iov[i].iov_len = dvec[i].iov_len;
379     }
380     uio.uio_iov = &iov[0];
381     uio.uio_iovcnt = nvecs;
382     uio.uio_loffset = 0;
383     uio.uio_segflg = UIO_SYSSPACE;
384     uio.uio_fmode = 0;
385     uio.uio_limit = 0;
386     uio.uio_resid = *alength;
387
388     error = sockfs_sorecvmsg(asocket, &msg, &uio);
389     if (error == 0) {
390         if (msg.msg_name == NULL) {
391             error = -1;
392         } else {
393             memcpy(addr, msg.msg_name, msg.msg_namelen);
394             kmem_free(msg.msg_name, msg.msg_namelen);
395             *alength = *alength - uio.uio_resid;
396         }
397     }
398
399     if (error == EINTR && ISSIG(curthread, FORREAL)) {
400         klwp_t *lwp = ttolwp(curthread);
401         proc_t *p = ttoproc(curthread);
402         int sig = lwp->lwp_cursig;
403
404         if (sig == SIGKILL) {
405             mutex_enter(&p->p_lock);
406             p->p_flag &= ~SKILLED;
407             mutex_exit(&p->p_lock);
408         }
409         lwp->lwp_cursig = 0;
410         if (lwp->lwp_curinfo) {
411             siginfofree(lwp->lwp_curinfo);
412             lwp->lwp_curinfo = NULL;
413         }
414     }
415
416     return error;
417 }
418
419 void shutdown_rxkernel(void)
420 {
421 }
422
423 void osi_StopListener(void)
424 {
425     osi_FreeSocket(rx_socket);
426 }
427
428 #else /* AFS_SUN56_ENV */
429
430 #include "../inet/common.h"
431 #include "../sys/tiuser.h"
432 #include "../sys/t_kuser.h"
433 #include "../sys/ioctl.h"
434 #include "../sys/stropts.h"
435 #include "../sys/stream.h"
436 #include "../sys/strsubr.h"
437 #include "../sys/vnode.h"
438 #include "../sys/stropts.h"
439 #include "../sys/tihdr.h"
440 #include "../sys/timod.h"
441 #include "../sys/fcntl.h"
442 #include "../sys/debug.h"
443 #include "../inet/common.h"
444 #include "../inet/mi.h"
445 #include "../netinet/udp.h"
446
447 extern dev_t afs_udp_rdev;
448
449
450 int rxi_GetIFInfo()
451 {
452     return 0;
453 }
454
455
456 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
457  * afs_osinet.c. 
458  */
459
460 dev_t afs_udp_rdev = (dev_t)0;
461
462 /* Allocate a new socket at specified port in network byte order. */
463 struct osi_socket *rxk_NewSocket(short aport)
464 {
465     TIUSER *udp_tiptr;
466     struct t_bind *reqp, *rspp;
467     afs_int32 code;
468     struct sockaddr_in *myaddrp;
469     struct stdata *stp;
470     struct queue *q;
471
472     AFS_STATCNT(osi_NewSocket);
473     afs_udp_rdev = makedevice(11 /*CLONE*/, ddi_name_to_major("udp"));
474     code = t_kopen(NULL, afs_udp_rdev, FREAD|FWRITE, &udp_tiptr, CRED());
475     if (code) {
476         return (struct osi_socket *)0;
477     }
478
479     code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&reqp);
480     if (code) {
481         t_kclose(udp_tiptr, 0);
482     }
483     code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&rspp);
484     if (code) {
485         t_kfree(udp_tiptr, (char *)reqp, T_BIND);
486         t_kclose(udp_tiptr, 0);
487         return (struct osi_socket *)0;
488     }
489
490     reqp->addr.len = sizeof(struct sockaddr_in);
491     myaddrp = (struct sockaddr_in *) reqp->addr.buf;
492     myaddrp->sin_family = AF_INET;
493     myaddrp->sin_port = aport;
494     myaddrp->sin_addr.s_addr = INADDR_ANY;      /* XXX Was 0 XXX */
495
496     code = t_kbind(udp_tiptr, reqp, rspp);
497     if (code) {
498         t_kfree(udp_tiptr, (char *)reqp, T_BIND);
499         t_kfree(udp_tiptr, (char *)rspp, T_BIND);
500         t_kclose(udp_tiptr, 0);
501         return (struct osi_socket *)0;
502     }
503     if (memcmp(reqp->addr.buf, rspp->addr.buf, rspp->addr.len)) {
504         t_kfree(udp_tiptr, (char *)reqp, T_BIND);
505         t_kfree(udp_tiptr, (char *)rspp, T_BIND);
506         t_kclose(udp_tiptr, 0);
507         return (struct osi_socket *)0;
508     }
509     t_kfree(udp_tiptr, (char *)reqp, T_BIND);
510     t_kfree(udp_tiptr, (char *)rspp, T_BIND);
511
512     /*
513      * Set the send and receive buffer sizes.
514      */
515     stp = udp_tiptr->fp->f_vnode->v_stream;
516     q = stp->sd_wrq;
517     q->q_hiwat = rx_UdpBufSize;
518     q->q_next->q_hiwat = rx_UdpBufSize;
519     RD(q)->q_hiwat = rx_UdpBufSize;
520
521     return (struct osi_socket *) udp_tiptr;
522 }
523
524
525 int osi_FreeSocket(register struct osi_socket *asocket)
526 {
527     extern int rxk_ListenerPid;
528     TIUSER *udp_tiptr = (TIUSER *) asocket;    
529     AFS_STATCNT(osi_FreeSocket);
530
531     if (rxk_ListenerPid) {
532         kill(rxk_ListenerPid, SIGUSR1);
533         afs_osi_Sleep(&rxk_ListenerPid);
534     }
535     return 0;
536 }
537
538
539 int osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, 
540                 struct iovec *dvec, int nvecs, afs_int32 asize, int istack) 
541 {
542     int i;
543     int code;
544     TIUSER *udp_tiptr = (TIUSER *) asocket;    
545     struct t_kunitdata *udreq;
546     struct sockaddr_in sin;
547     mblk_t *bp;
548     mblk_t *dbp;
549
550     /*
551      * XXX We don't do any checking on the family since it's assumed to be
552      * AF_INET XXX
553      */
554     sin.sin_family = AF_INET;
555     sin.sin_addr.s_addr = addr->sin_addr.s_addr;
556     sin.sin_port = addr->sin_port;
557
558     /*
559      * Get a buffer for the RX header
560      */
561     if (nvecs < 1) {
562         osi_Panic("osi_NetSend, nvecs=%d\n", nvecs);
563     }
564     while (!(bp = allocb(dvec[0].iov_len, BPRI_LO))) {
565         if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
566             return (ENOSR);
567         }
568     }
569
570     /* Copy the data into the buffer */
571     memcpy((char *)bp->b_wptr, (char *)dvec[0].iov_base, dvec[0].iov_len);
572     bp->b_datap->db_type = M_DATA;
573     bp->b_wptr += dvec[0].iov_len;
574
575     /*
576      * Append each element in the iovec to the buffer
577      */
578     for (i = 1 ; i < nvecs ; i++) {
579         /* Get a buffer for the next chunk */
580         while (!(dbp = allocb(dvec[i].iov_len, BPRI_LO))) {
581             if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
582                 freeb(bp);
583                 return (ENOSR);
584             }
585         }
586
587         /* Copy the data into the buffer */
588         memcpy((char *)dbp->b_wptr, (char *)dvec[i].iov_base, dvec[i].iov_len);
589         dbp->b_datap->db_type = M_DATA;
590         dbp->b_wptr += dvec[i].iov_len;
591
592         /* Append it to the message buffer */
593         linkb(bp, dbp);
594     }
595
596     /*
597      * Allocate and format the unitdata structure.
598      */
599     code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
600     if (code) {
601         freeb(bp);
602         printf("osi_NetSend: t_kalloc failed %d\n", code);
603         return code;
604     }
605     udreq->addr.len = sizeof(struct sockaddr_in);
606     udreq->addr.maxlen = sizeof(struct sockaddr_in);
607     udreq->addr.buf = (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
608     udreq->opt.len = 0;
609     udreq->opt.maxlen = 0;
610     memcpy(udreq->addr.buf, (char *)&sin, sizeof(struct sockaddr_in));
611     udreq->udata.udata_mp = bp;
612     udreq->udata.len = asize;
613
614     code = t_ksndudata(udp_tiptr, udreq, NULL);
615     if (code) {
616         printf("osi_NetSend: t_ksndudata failed %d\n", code);
617     }
618
619     t_kfree(udp_tiptr, (caddr_t)udreq, T_UNITDATA);
620     return code;
621 }
622
623
624 int osi_NetReceive(struct osi_socket *asocket, struct sockaddr_in *addr, 
625         struct iovec *dvec, int nvecs, int *alength)
626 {
627     int i;
628     TIUSER *udp_tiptr = (TIUSER *) asocket;    
629     struct t_kunitdata *udreq;
630     mblk_t *dbp;
631     char *phandle;
632     short sport;
633     int code = 0;
634     int length;
635     int tlen;
636     int blen;
637     char *tbase;
638     int type;
639     int error;
640     int events;
641
642     /*
643      * Allocate the unitdata structure.
644      */
645     code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
646     if (code) {
647         printf("osi_NetReceive: t_kalloc failed %d\n", code);
648         return code;
649     }
650     udreq->addr.len = sizeof(struct sockaddr_in);
651     udreq->addr.maxlen = sizeof(struct sockaddr_in);
652     udreq->addr.buf = (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
653     udreq->opt.len = 0;
654     udreq->opt.maxlen = 0;
655
656     /*
657      * Loop until we get an error or receive some data.
658      */
659     while(1) {
660         /*
661          * Wait until there is something to do
662          */
663         code = t_kspoll(udp_tiptr, -1, READWAIT, &events);
664         if (events == 0) {
665             osi_Panic("osi_NetReceive, infinite t_kspoll timed out\n");
666         }
667         /*
668          * If there is a message then read it in
669          */
670         if (code == 0) {
671             code = t_krcvudata(udp_tiptr, udreq, &type, &error);
672         }
673
674         /*
675          * Block attempts to kill this thread
676          */
677         if (code == EINTR && ISSIG(curthread, FORREAL)) {
678             klwp_t *lwp = ttolwp(curthread);
679             proc_t *p = ttoproc(curthread);
680             int sig = lwp->lwp_cursig;
681
682             if (sig == SIGKILL) {
683                 mutex_enter(&p->p_lock);
684                 p->p_flag &= ~SKILLED;
685                 mutex_exit(&p->p_lock);
686             }
687             lwp->lwp_cursig = 0;
688             if (lwp->lwp_curinfo) {
689                 kmem_free((caddr_t)lwp->lwp_curinfo, sizeof(*lwp->lwp_curinfo));
690                 lwp->lwp_curinfo = NULL;
691             }
692         }
693
694         if (code) {
695             break;
696         }
697
698         /*
699          * Ignore non-data message types
700          */
701         if (type != T_DATA) {
702             continue;
703         }
704
705         /*
706          * Save the source address
707          */
708         memcpy((char *)addr, udreq->addr.buf, sizeof(struct sockaddr_in));
709
710         /*
711          * Copy out the message buffers, take care not to overflow
712          * the I/O vector.
713          */
714         dbp = udreq->udata.udata_mp;
715         length = *alength;
716         for (i = 0 ; dbp != NULL && length > 0 && i < nvecs ; i++) {
717             tlen = dvec[i].iov_len;
718             tbase = dvec[i].iov_base;
719             if (tlen > length) {
720                 tlen = length;
721             }
722             while (dbp != NULL && tlen > 0) {
723                 blen = dbp->b_wptr - dbp->b_rptr;
724                 if (blen > tlen) {
725                     memcpy(tbase, (char *)dbp->b_rptr, tlen);
726                     length -= tlen;
727                     dbp->b_rptr += tlen;
728                     tlen = 0;
729                 } else {
730                     memcpy(tbase, (char *)dbp->b_rptr, blen);
731                     length -= blen;
732                     tlen -= blen;
733                     tbase += blen;
734                     dbp = dbp->b_cont;
735                 }
736             }
737         }
738         *alength = *alength - length;
739         break;
740     }
741
742     t_kfree(udp_tiptr, (caddr_t)udreq, T_UNITDATA);
743     return code;
744 }
745
746
747 void osi_StopListener(void)
748 {
749     osi_FreeSocket(rx_socket);
750 }
751
752
753 void shutdown_rxkernel(void)
754 {
755 }
756
757
758 #endif /* AFS_SUN56_ENV */
759 #endif /* AFS_SUN5_ENV */