home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / UDPSOCK.C < prev    next >
C/C++ Source or Header  |  1992-05-11  |  3KB  |  172 lines

  1. #include "global.h"
  2. #include "udp.h"
  3. #include "socket.h"
  4. #include "usock.h"
  5.  
  6. static void s_urcall __ARGS((struct iface *iface,struct udp_cb *udp,int cnt));
  7. static void autobind __ARGS((struct usock *up));
  8.  
  9. int
  10. so_udp(up,protocol)
  11. struct usock *up;
  12. int protocol;
  13. {
  14.     return 0;
  15. }
  16. int
  17. so_udp_bind(up)
  18. struct usock *up;
  19. {
  20.     int s;
  21.     struct sockaddr_in *sp;
  22.     struct socket lsock;
  23.  
  24.     s = up->index;
  25.     sp = (struct sockaddr_in *)up->name;
  26.     lsock.address = sp->sin_addr.s_addr;
  27.     lsock.port = sp->sin_port;
  28.     up->cb.udp = open_udp(&lsock,s_urcall);
  29.     up->cb.udp->user = s;
  30.     return 0;
  31. }
  32. int
  33. so_udp_conn(up)
  34. struct usock *up;
  35. {
  36.     if(up->name == NULLCHAR){
  37.         autobind(up);
  38.     }
  39.     return 0;
  40. }
  41. int
  42. so_udp_recv(up,bpp,from,fromlen)
  43. struct usock *up;
  44. struct mbuf **bpp;
  45. char *from;
  46. int *fromlen;
  47. {
  48.     int cnt;
  49.     struct udp_cb *udp;
  50.     struct sockaddr_in *remote;
  51.     struct socket fsocket;
  52.  
  53.     while((udp = up->cb.udp) != NULLUDP
  54.     && (cnt = recv_udp(udp,&fsocket,bpp)) == -1){
  55.         if(up->noblock){
  56.             errno = EWOULDBLOCK;
  57.             return -1;
  58.         } else if((errno = pwait(up)) != 0){
  59.             return -1;
  60.         }
  61.     }
  62.     if(udp == NULLUDP){
  63.         /* Connection went away */
  64.         errno = ENOTCONN;
  65.         return -1;
  66.     }
  67.     if(from != NULLCHAR && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  68.         remote = (struct sockaddr_in *)from;
  69.         remote->sin_family = AF_INET;
  70.         remote->sin_addr.s_addr = fsocket.address;
  71.         remote->sin_port = fsocket.port;
  72.         *fromlen = SOCKSIZE;
  73.     }
  74.     return cnt;
  75. }
  76. int
  77. so_udp_send(up,bp,to)
  78. struct usock *up;
  79. struct mbuf *bp;
  80. char *to;
  81. {
  82.     struct sockaddr_in *local,*remote;
  83.     struct socket lsock,fsock;
  84.  
  85.     if(up->name == NULLCHAR)
  86.         autobind(up);
  87.     local = (struct sockaddr_in *)up->name;
  88.     lsock.address = local->sin_addr.s_addr;
  89.     lsock.port = local->sin_port;
  90.     if(to != NULLCHAR) {
  91.         remote = (struct sockaddr_in *)to;
  92.     } else if(up->peername != NULLCHAR){
  93.         remote = (struct sockaddr_in *)up->peername;
  94.     } else {
  95.         free_p(bp);
  96.         errno = ENOTCONN;
  97.         return -1;
  98.     }    
  99.     fsock.address = remote->sin_addr.s_addr;
  100.     fsock.port = remote->sin_port;
  101.     send_udp(&lsock,&fsock,up->tos,0,bp,0,0,0);
  102.     return 0;
  103. }
  104. int
  105. so_udp_qlen(up,rtx)
  106. struct usock *up;
  107. int rtx;
  108. {
  109.     int len;
  110.  
  111.     switch(rtx){
  112.     case 0:
  113.         len = up->cb.udp->rcvcnt;
  114.         break;
  115.     case 1:
  116.         len = 0;
  117.         break;
  118.     }
  119.     return len;
  120. }
  121. int
  122. so_udp_close(up)
  123. struct usock *up;
  124. {
  125.     if(up->cb.udp != NULLUDP){
  126.         del_udp(up->cb.udp);
  127.     }
  128.     return 0;
  129. }
  130. int
  131. so_udp_shut(up,how)
  132. struct usock *up;
  133. int how;
  134. {
  135.     int s;
  136.  
  137.     s = up->index;
  138.     close_s(s);
  139.     return 0;
  140. }
  141. static void
  142. s_urcall(iface,udp,cnt)
  143. struct iface *iface;
  144. struct udp_cb *udp;
  145. int cnt;
  146. {
  147.     psignal(itop(udp->user),1);
  148.     pwait(NULL);
  149. }
  150.  
  151. /* Issue an automatic bind of a local address */
  152. static void
  153. autobind(up)
  154. struct usock *up;
  155. {
  156.     struct sockaddr_in local;
  157.     int s;
  158.  
  159.     s = up->index;
  160.     local.sin_family = AF_INET;
  161.     local.sin_addr.s_addr = INADDR_ANY;
  162.     local.sin_port = Lport++;
  163.     bind(s,(char *)&local,sizeof(struct sockaddr_in));
  164. }
  165. int
  166. so_udp_stat(up)
  167. struct usock *up;
  168. {
  169.     st_udp(up->cb.udp,0);
  170.     return 0;
  171. }
  172.