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