2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
17 #include "rx/rx_kcommon.h"
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"
30 #include "netinet/ip6.h"
31 #define ipif_local_addr ipif_lcl_addr
33 #define V4_PART_OF_V6(v6) v6.s6_addr32[3]
37 #include "inet/ip_if.h"
38 #include "netinet/udp.h"
45 #include "h/cmn_err.h"
47 #include "netinet/in.h"
51 * Function pointers for kernel socket routines
53 struct sonode *(*sockfs_socreate)
54 (vnode_t *, int, int, int, int, struct sonode *, int *) = NULL;
55 struct vnode *(*sockfs_solookup)
56 (int, int, int, char *, int *) = NULL;
58 (struct sonode *, struct sockaddr *, int, int, int) = NULL;
59 int (*sockfs_sorecvmsg)
60 (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
61 int (*sockfs_sosendmsg)
62 (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
63 int (*sockfs_sosetsockopt)
64 (struct sonode *, int, int, void *, int) = NULL;
65 #ifndef AFS_SUN510_ENV
66 int (*sockfs_sounbind)
67 (struct sonode *, int);
68 void (*sockfs_sockfree)
73 #define UDP_MOD_NAME "udp"
76 static afs_uint32 myNetAddrs[ADDRSPERSITE];
77 static int myNetMTUs[ADDRSPERSITE];
78 static int numMyNetAddrs = 0;
85 #ifndef AFS_SUN510_ENV
90 int mtus[ADDRSPERSITE];
91 afs_uint32 addrs[ADDRSPERSITE];
94 memset(mtus, 0, sizeof(mtus));
95 memset(addrs, 0, sizeof(addrs));
98 (void) rw_enter(&afsifinfo_lock, RW_READER);
100 for (i = 0; (afsifinfo[i].ipaddr != NULL) && (i < ADDRSPERSITE); i++) {
102 /* Ignore addresses which are down.. */
103 if (!(afsifinfo[i].flags & IFF_UP))
106 /* Compute the Rx interface MTU */
107 rxmtu = (afsifinfo[i].mtu - RX_IPUDP_SIZE);
109 ifinaddr = afsifinfo[i].ipaddr;
110 if (myNetAddrs[i] != ifinaddr)
113 /* Copy interface MTU and address; adjust maxmtu */
115 rxmtu = rxi_AdjustIfMTU(rxmtu);
116 maxmtu = rxmtu * rxi_nRecvFrags +
117 ((rxi_nRecvFrags - 1) * UDP_HDR_SIZE);
118 maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu);
121 if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) {
122 rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxmtu);
124 MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser);
129 (void) rw_exit(&afsifinfo_lock);
131 rx_maxJumboRecvSize =
132 RX_HEADER_SIZE + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
133 (rxi_nDgramPackets - 1) * RX_JUMBOHEADERSIZE;
134 rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize);
139 for (j = 0; j < i; j++) {
140 myNetMTUs[j] = mtus[j];
141 myNetAddrs[j] = addrs[j];
149 for (ill = ill_g_head; ill; ill = ill->ill_next) {
151 /* Make sure this is an IPv4 ILL */
156 /* Iterate over all the addresses on this ILL */
157 for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
158 if (i >= ADDRSPERSITE)
161 /* Ignore addresses which are down.. */
162 if (!(ipif->ipif_flags & IFF_UP))
165 /* Compute the Rx interface MTU */
166 rxmtu = (ipif->ipif_mtu - RX_IPUDP_SIZE);
168 ifinaddr = ntohl(ipif->ipif_local_addr);
169 if (myNetAddrs[i] != ifinaddr)
172 /* Copy interface MTU and address; adjust maxmtu */
174 rxmtu = rxi_AdjustIfMTU(rxmtu);
176 rxmtu * rxi_nRecvFrags +
177 ((rxi_nRecvFrags - 1) * UDP_HDR_SIZE);
178 maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu);
182 if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) {
183 rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxmtu);
185 MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser);
190 rx_maxJumboRecvSize =
191 RX_HEADER_SIZE + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
192 (rxi_nDgramPackets - 1) * RX_JUMBOHEADERSIZE;
193 rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize);
198 for (j = 0; j < i; j++) {
199 myNetMTUs[j] = mtus[j];
200 myNetAddrs[j] = addrs[j];
209 rxi_FindIfMTU(afs_uint32 addr)
211 afs_uint32 myAddr, netMask;
214 #ifdef AFS_SUN510_ENV
221 if (numMyNetAddrs == 0)
223 myAddr = ntohl(addr);
225 if (IN_CLASSA(myAddr))
226 netMask = IN_CLASSA_NET;
227 else if (IN_CLASSB(myAddr))
228 netMask = IN_CLASSB_NET;
229 else if (IN_CLASSC(myAddr))
230 netMask = IN_CLASSC_NET;
234 #ifdef AFS_SUN510_ENV
235 (void) rw_enter(&afsifinfo_lock, RW_READER);
237 for (i = 0; (afsifinfo[i].ipaddr != NULL) && (i < ADDRSPERSITE); i++) {
238 afs_uint32 thisAddr, subnetMask;
241 /* Ignore addresses which are down.. */
242 if ((afsifinfo[i].flags & IFF_UP) == 0)
245 thisAddr = afsifinfo[i].ipaddr;
246 subnetMask = afsifinfo[i].netmask;
247 thisMtu = afsifinfo[i].mtu;
249 if ((myAddr & netMask) == (thisAddr & netMask)) {
250 if ((myAddr & subnetMask) == (thisAddr & subnetMask)) {
251 if (myAddr == thisAddr) {
256 if (match_value < 3) {
262 if (match_value < 2) {
269 (void) rw_exit(&afsifinfo_lock);
274 for (ill = ill_g_head; ill; ill = ill->ill_next) {
276 /* Make sure this is an IPv4 ILL */
281 /* Iterate over all the addresses on this ILL */
282 for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
283 afs_uint32 thisAddr, subnetMask;
286 thisAddr = ipif->ipif_local_addr;
287 subnetMask = ipif->ipif_net_mask;
288 thisMtu = ipif->ipif_mtu;
290 if ((myAddr & netMask) == (thisAddr & netMask)) {
291 if ((myAddr & subnetMask) == (thisAddr & subnetMask)) {
292 if (myAddr == thisAddr) {
297 if (match_value < 3) {
303 if (match_value < 2) {
315 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
319 struct sockaddr_in rx_sockaddr;
321 /* Allocate a new socket at specified port in network byte order. */
323 rxk_NewSocketHost(afs_uint32 ahost, short aport)
327 struct sockaddr_in addr;
331 AFS_STATCNT(osi_NewSocket);
333 if (sockfs_solookup == NULL) {
335 (struct vnode * (*)())modlookup("sockfs", "solookup");
336 if (sockfs_solookup == NULL) {
340 if (sockfs_socreate == NULL) {
342 (struct sonode * (*)())modlookup("sockfs", "socreate");
343 if (sockfs_socreate == NULL) {
347 if (sockfs_sobind == NULL) {
348 sockfs_sobind = (int (*)())modlookup("sockfs", "sobind");
349 if (sockfs_sobind == NULL) {
353 if (sockfs_sosetsockopt == NULL) {
354 sockfs_sosetsockopt = (int (*)())modlookup("sockfs", "sosetsockopt");
355 if (sockfs_sosetsockopt == NULL) {
359 if (sockfs_sosendmsg == NULL) {
360 sockfs_sosendmsg = (int (*)())modlookup("sockfs", "sosendmsg");
361 if (sockfs_sosendmsg == NULL) {
365 if (sockfs_sorecvmsg == NULL) {
366 sockfs_sorecvmsg = (int (*)())modlookup("sockfs", "sorecvmsg");
367 if (sockfs_sorecvmsg == NULL) {
371 #ifndef AFS_SUN510_ENV
372 if (sockfs_sounbind == NULL) {
373 sockfs_sounbind = (int (*)())modlookup("sockfs", "sounbind");
374 if (sockfs_sounbind == NULL)
377 if (sockfs_sockfree == NULL) {
378 sockfs_sockfree = (void (*)())modlookup("sockfs", "sockfree");
379 if (sockfs_sockfree == NULL)
384 accessvp = sockfs_solookup(AF_INET, SOCK_DGRAM, 0, "/dev/udp", &error);
385 if (accessvp == NULL) {
389 so = sockfs_socreate(accessvp, AF_INET, SOCK_DGRAM, 0, SOV_STREAM, NULL,
395 addr.sin_family = AF_INET;
396 addr.sin_port = aport;
397 addr.sin_addr.s_addr = ahost; /* I wonder what the odds are on
398 needing to unbyteswap this */
399 error = sockfs_sobind(so, (struct sockaddr *)&addr, sizeof(addr), 0, 0);
405 error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len));
411 error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
416 return (osi_socket *)so;
420 rxk_NewSocket(short aport)
422 return rxk_NewSocketHost(htonl(INADDR_ANY), aport);
426 osi_FreeSocket(register osi_socket *asocket)
428 extern int rxk_ListenerPid;
429 struct sonode *so = (struct sonode *)asocket;
430 struct sockaddr_in taddr;
435 AFS_STATCNT(osi_FreeSocket);
437 taddr.sin_family = AF_INET;
438 taddr.sin_port = rx_port;
439 taddr.sin_addr.s_addr = htonl(0x7f000001);
444 while (rxk_ListenerPid) {
445 osi_NetSend(rx_socket, &taddr, &dvec, 1, 1, 0);
446 afs_osi_Sleep(&rxk_ListenerPid);
449 /* Was sockfs_sounbind(so, 0); sockfs_sockfree(so); That's wrong */
451 #ifdef AFS_SUN511_ENV
452 VOP_CLOSE(vp, FREAD|FWRITE, 1, (offset_t)0, CRED(), NULL);
454 VOP_CLOSE(vp, FREAD|FWRITE, 1, (offset_t)0, CRED());
462 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
463 int nvecs, afs_int32 asize, int istack)
465 struct sonode *so = (struct sonode *)asocket;
468 struct iovec iov[RX_MAXIOVECS];
472 if (nvecs > RX_MAXIOVECS) {
473 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
476 msg.msg_name = (struct sockaddr *)addr;
477 msg.msg_namelen = sizeof(struct sockaddr_in);
479 msg.msg_iovlen = nvecs;
480 msg.msg_control = NULL;
481 msg.msg_controllen = 0;
484 for (i = 0; i < nvecs; i++) {
485 iov[i].iov_base = dvec[i].iov_base;
486 iov[i].iov_len = dvec[i].iov_len;
488 uio.uio_iov = &iov[0];
489 uio.uio_iovcnt = nvecs;
491 uio.uio_segflg = UIO_SYSSPACE;
492 uio.uio_fmode = FREAD | FWRITE;
494 uio.uio_resid = asize;
496 error = sockfs_sosendmsg(so, &msg, &uio);
502 osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
503 int nvecs, int *alength)
505 struct sonode *asocket = (struct sonode *)so;
508 struct iovec iov[RX_MAXIOVECS];
512 if (nvecs > RX_MAXIOVECS) {
513 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
517 msg.msg_namelen = sizeof(struct sockaddr_in);
520 msg.msg_control = NULL;
521 msg.msg_controllen = 0;
524 for (i = 0; i < nvecs; i++) {
525 iov[i].iov_base = dvec[i].iov_base;
526 iov[i].iov_len = dvec[i].iov_len;
528 uio.uio_iov = &iov[0];
529 uio.uio_iovcnt = nvecs;
531 uio.uio_segflg = UIO_SYSSPACE;
534 uio.uio_resid = *alength;
536 error = sockfs_sorecvmsg(asocket, &msg, &uio);
538 if (msg.msg_name == NULL) {
541 memcpy(addr, msg.msg_name, msg.msg_namelen);
542 kmem_free(msg.msg_name, msg.msg_namelen);
543 *alength = *alength - uio.uio_resid;
547 if (error == EINTR && ISSIG(curthread, FORREAL)) {
548 klwp_t *lwp = ttolwp(curthread);
549 proc_t *p = ttoproc(curthread);
550 int sig = lwp->lwp_cursig;
552 if (sig == SIGKILL) {
553 mutex_enter(&p->p_lock);
554 p->p_flag &= ~SKILLED;
555 mutex_exit(&p->p_lock);
558 if (lwp->lwp_curinfo) {
559 siginfofree(lwp->lwp_curinfo);
560 lwp->lwp_curinfo = NULL;
567 #if defined(AFS_SUN510_ENV)
568 /* How often afs collects interface info. Tunable via /etc/system: */
569 /* set afs:afs_if_poll_interval = integer (value is in seconds) */
570 static int afs_if_poll_interval = 30;
572 /* Global array which holds the interface info for consumers */
573 struct afs_ifinfo afsifinfo[ADDRSPERSITE];
576 osi_StartNetIfPoller()
578 (void) ddi_taskq_dispatch(afs_taskq, (void(*) (void*)) osi_NetIfPoller,
591 struct lifreq *lifrp;
592 struct sockaddr_in *sin4_local;
593 struct sockaddr_in *sin4_dst;
596 int i, count, error, rv;
603 if (afs_termState == AFSOP_STOP_NETIF) {
604 afs_warn("NetIfPoller... ");
605 rw_destroy(&afsifinfo_lock);
606 ddi_taskq_destroy(afs_taskq);
607 afs_termState = AFSOP_STOP_COMPLETE;
608 osi_rxWakeup(&afs_termState);
611 /* Get our permissions */
614 /* Initialize and open /dev/udp for receiving ioctls */
615 udpmajor = ddi_name_to_major(UDP_MOD_NAME);
617 error = ldi_ident_from_major(udpmajor, &li);
619 cmn_err(CE_PANIC, "osi_NetIfPoller: ldi_ident_from_major failed: %d",
622 error = ldi_open_by_name(UDP_DEV_NAME, FREAD, cr, &lh, li);
625 "osi_NetIfPoller: ldi_open_by_name failed: %d", error);
628 /* First, how many interfaces do we have? */
629 (void) bzero((void *)&lifn, sizeof(struct lifnum));
630 lifn.lifn_family = AF_INET;
632 error = ldi_ioctl(lh, SIOCGLIFNUM, (intptr_t)&lifn,
636 "osi_NetIfPoller: ldi_ioctl: SIOCGLIFNUM failed: %d", error);
638 ifcount = lifn.lifn_count;
640 /* Set up some stuff for storing the results of SIOCGLIFCONF */
641 (void) bzero((void *)&lifc, sizeof(struct lifconf));
643 lifcbuf = kmem_zalloc(ifcount * sizeof(struct lifreq), KM_SLEEP);
645 lifc.lifc_family = AF_INET;
646 lifc.lifc_flags = IFF_UP;
647 lifc.lifc_len = ifcount * sizeof(struct lifreq);
648 lifc.lifc_buf = lifcbuf;
650 /* Get info on each of our available interfaces. */
651 error = ldi_ioctl(lh, SIOCGLIFCONF, (intptr_t)&lifc,
655 "osi_NetIfPoller: ldi_ioctl: SIOCGLIFCONF failed: %d", error);
657 lifrp = lifc.lifc_req;
661 /* Loop through our interfaces and pick out the info we want */
662 for (i = lifc.lifc_len / sizeof(struct lifreq);
663 i > 0; i--, lifrp++) {
665 if (count >= ADDRSPERSITE)
668 (void) bzero((void *)&lifr, sizeof(struct lifreq));
670 (void) strncpy(lifr.lifr_name, lifrp->lifr_name,
671 sizeof(lifr.lifr_name));
673 /* Get this interface's Flags */
674 error = ldi_ioctl(lh, SIOCGLIFFLAGS, (intptr_t)&lifr,
678 "osi_NetIfPoller: ldi_ioctl: SIOCGLIFFLAGS failed: %d",
681 /* Ignore plumbed but down interfaces. */
682 if ((lifr.lifr_flags & IFF_UP) == 0)
685 flags = lifr.lifr_flags;
687 /* Get this interface's MTU */
688 error = ldi_ioctl(lh, SIOCGLIFMTU, (intptr_t)&lifr,
694 mtu = lifr.lifr_metric;
697 /* Get this interface's Metric */
698 error = ldi_ioctl(lh, SIOCGLIFMETRIC, (intptr_t)&lifr,
704 metric = lifr.lifr_metric;
707 sin4_local = (struct sockaddr_in *) &lifrp->lifr_addr;
708 sin4_dst = (struct sockaddr_in *) &lifrp->lifr_dstaddr;
710 /* Acquire global array write lock */
711 (void) rw_enter(&afsifinfo_lock, RW_WRITER);
713 /* Copy our collected data into the global array */
714 (void) strncpy(afsifinfo[count].ifname, lifrp->lifr_name,
715 sizeof(afsifinfo[count].ifname));
716 afsifinfo[count].ipaddr = ntohl(sin4_local->sin_addr.s_addr);
717 afsifinfo[count].mtu = mtu;
718 afsifinfo[count].netmask = lifrp->lifr_addrlen;
719 afsifinfo[count].flags = flags;
720 afsifinfo[count].metric = metric;
721 afsifinfo[count].dstaddr = ntohl(sin4_dst->sin_addr.s_addr);
723 /* Release global array write lock */
724 (void) rw_exit(&afsifinfo_lock);
728 } /* Bottom of loop: for each interface ... */
730 kmem_free(lifcbuf, ifcount * sizeof(struct lifreq));
732 /* End of thread. Time to clean up */
733 (void) ldi_close(lh, FREAD, cr);
734 (void) ldi_ident_release(li);
736 /* Schedule this to run again after afs_if_poll_interval seconds */
737 (void) timeout((void(*) (void *)) osi_StartNetIfPoller, NULL,
738 drv_usectohz((clock_t)afs_if_poll_interval * MICROSEC));
741 #endif /* AFS_SUN510_ENV */
744 shutdown_rxkernel(void)
749 osi_StopListener(void)
751 osi_FreeSocket(rx_socket);
754 #else /* AFS_SUN56_ENV */
756 #include "inet/common.h"
757 #include "sys/tiuser.h"
758 #include "sys/t_kuser.h"
759 #include "sys/ioctl.h"
760 #include "sys/stropts.h"
761 #include "sys/stream.h"
762 #include "sys/strsubr.h"
763 #include "sys/vnode.h"
764 #include "sys/stropts.h"
765 #include "sys/tihdr.h"
766 #include "sys/timod.h"
767 #include "sys/fcntl.h"
768 #include "sys/debug.h"
769 #include "inet/common.h"
771 #include "netinet/udp.h"
773 extern dev_t afs_udp_rdev;
783 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
787 dev_t afs_udp_rdev = (dev_t) 0;
789 /* Allocate a new socket at specified port in network byte order. */
791 rxk_NewSocketHost(afs_uint32 ahost, short aport)
794 struct t_bind *reqp, *rspp;
796 struct sockaddr_in *myaddrp;
800 AFS_STATCNT(osi_NewSocket);
801 afs_udp_rdev = makedevice(11 /*CLONE*/, ddi_name_to_major("udp"));
802 code = t_kopen(NULL, afs_udp_rdev, FREAD | FWRITE, &udp_tiptr, CRED());
804 return (osi_socket *)0;
807 code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&reqp);
809 t_kclose(udp_tiptr, 0);
811 code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&rspp);
813 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
814 t_kclose(udp_tiptr, 0);
815 return (osi_socket *)0;
818 reqp->addr.len = sizeof(struct sockaddr_in);
819 myaddrp = (struct sockaddr_in *)reqp->addr.buf;
820 myaddrp->sin_family = AF_INET;
821 myaddrp->sin_port = aport;
822 myaddrp->sin_addr.s_addr = ahost; /* byteswap? */
824 code = t_kbind(udp_tiptr, reqp, rspp);
826 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
827 t_kfree(udp_tiptr, (char *)rspp, T_BIND);
828 t_kclose(udp_tiptr, 0);
829 return (osi_socket *)0;
831 if (memcmp(reqp->addr.buf, rspp->addr.buf, rspp->addr.len)) {
832 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
833 t_kfree(udp_tiptr, (char *)rspp, T_BIND);
834 t_kclose(udp_tiptr, 0);
835 return (osi_socket *)0;
837 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
838 t_kfree(udp_tiptr, (char *)rspp, T_BIND);
841 * Set the send and receive buffer sizes.
843 stp = udp_tiptr->fp->f_vnode->v_stream;
845 q->q_hiwat = rx_UdpBufSize;
846 q->q_next->q_hiwat = rx_UdpBufSize;
847 RD(q)->q_hiwat = rx_UdpBufSize;
849 return (osi_socket *)udp_tiptr;
853 rxk_NewSocket(short aport)
855 return rxk_NewSocketHost(htonl(INADDR_ANY), aport);
859 osi_FreeSocket(register osi_socket *asocket)
861 extern int rxk_ListenerPid;
862 TIUSER *udp_tiptr = (TIUSER *) asocket;
863 AFS_STATCNT(osi_FreeSocket);
865 if (rxk_ListenerPid) {
866 kill(rxk_ListenerPid, SIGUSR1);
867 afs_osi_Sleep(&rxk_ListenerPid);
874 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
875 int nvecs, afs_int32 asize, int istack)
879 TIUSER *udp_tiptr = (TIUSER *) asocket;
880 struct t_kunitdata *udreq;
881 struct sockaddr_in sin;
886 * XXX We don't do any checking on the family since it's assumed to be
889 sin.sin_family = AF_INET;
890 sin.sin_addr.s_addr = addr->sin_addr.s_addr;
891 sin.sin_port = addr->sin_port;
894 * Get a buffer for the RX header
897 osi_Panic("osi_NetSend, nvecs=%d\n", nvecs);
899 while (!(bp = allocb(dvec[0].iov_len, BPRI_LO))) {
900 if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
905 /* Copy the data into the buffer */
906 memcpy((char *)bp->b_wptr, (char *)dvec[0].iov_base, dvec[0].iov_len);
907 bp->b_datap->db_type = M_DATA;
908 bp->b_wptr += dvec[0].iov_len;
911 * Append each element in the iovec to the buffer
913 for (i = 1; i < nvecs; i++) {
914 /* Get a buffer for the next chunk */
915 while (!(dbp = allocb(dvec[i].iov_len, BPRI_LO))) {
916 if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
922 /* Copy the data into the buffer */
923 memcpy((char *)dbp->b_wptr, (char *)dvec[i].iov_base,
925 dbp->b_datap->db_type = M_DATA;
926 dbp->b_wptr += dvec[i].iov_len;
928 /* Append it to the message buffer */
933 * Allocate and format the unitdata structure.
935 code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
938 printf("osi_NetSend: t_kalloc failed %d\n", code);
941 udreq->addr.len = sizeof(struct sockaddr_in);
942 udreq->addr.maxlen = sizeof(struct sockaddr_in);
944 (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
946 udreq->opt.maxlen = 0;
947 memcpy(udreq->addr.buf, (char *)&sin, sizeof(struct sockaddr_in));
948 udreq->udata.udata_mp = bp;
949 udreq->udata.len = asize;
951 code = t_ksndudata(udp_tiptr, udreq, NULL);
953 printf("osi_NetSend: t_ksndudata failed %d\n", code);
956 t_kfree(udp_tiptr, (caddr_t) udreq, T_UNITDATA);
962 osi_NetReceive(osi_socket *asocket, struct sockaddr_in *addr,
963 struct iovec *dvec, int nvecs, int *alength)
966 TIUSER *udp_tiptr = (TIUSER *) asocket;
967 struct t_kunitdata *udreq;
981 * Allocate the unitdata structure.
983 code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
985 printf("osi_NetReceive: t_kalloc failed %d\n", code);
988 udreq->addr.len = sizeof(struct sockaddr_in);
989 udreq->addr.maxlen = sizeof(struct sockaddr_in);
991 (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
993 udreq->opt.maxlen = 0;
996 * Loop until we get an error or receive some data.
1000 * Wait until there is something to do
1002 code = t_kspoll(udp_tiptr, -1, READWAIT, &events);
1004 osi_Panic("osi_NetReceive, infinite t_kspoll timed out\n");
1007 * If there is a message then read it in
1010 code = t_krcvudata(udp_tiptr, udreq, &type, &error);
1014 * Block attempts to kill this thread
1016 if (code == EINTR && ISSIG(curthread, FORREAL)) {
1017 klwp_t *lwp = ttolwp(curthread);
1018 proc_t *p = ttoproc(curthread);
1019 int sig = lwp->lwp_cursig;
1021 if (sig == SIGKILL) {
1022 mutex_enter(&p->p_lock);
1023 p->p_flag &= ~SKILLED;
1024 mutex_exit(&p->p_lock);
1026 lwp->lwp_cursig = 0;
1027 if (lwp->lwp_curinfo) {
1028 kmem_free((caddr_t) lwp->lwp_curinfo,
1029 sizeof(*lwp->lwp_curinfo));
1030 lwp->lwp_curinfo = NULL;
1039 * Ignore non-data message types
1041 if (type != T_DATA) {
1046 * Save the source address
1048 memcpy((char *)addr, udreq->addr.buf, sizeof(struct sockaddr_in));
1051 * Copy out the message buffers, take care not to overflow
1054 dbp = udreq->udata.udata_mp;
1056 for (i = 0; dbp != NULL && length > 0 && i < nvecs; i++) {
1057 tlen = dvec[i].iov_len;
1058 tbase = dvec[i].iov_base;
1059 if (tlen > length) {
1062 while (dbp != NULL && tlen > 0) {
1063 blen = dbp->b_wptr - dbp->b_rptr;
1065 memcpy(tbase, (char *)dbp->b_rptr, tlen);
1067 dbp->b_rptr += tlen;
1070 memcpy(tbase, (char *)dbp->b_rptr, blen);
1078 *alength = *alength - length;
1082 t_kfree(udp_tiptr, (caddr_t) udreq, T_UNITDATA);
1088 osi_StopListener(void)
1090 osi_FreeSocket(rx_socket);
1095 shutdown_rxkernel(void)
1100 #endif /* AFS_SUN56_ENV */
1101 #endif /* AFS_SUN5_ENV */