ipsock.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:3k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. #include "global.h"
  2. #include "mbuf.h"
  3. #include "ip.h"
  4. #include "usock.h"
  5. #include "socket.h"
  6. char Inet_eol[] = "rn";
  7. static void rip_recv(struct raw_ip *rp);
  8. static void autobind(struct usock *up);
  9. int
  10. so_ip_sock(up,protocol)
  11. struct usock *up;
  12. int protocol;
  13. {
  14. int s;
  15. s = up->index;
  16. up->cb.rip = raw_ip(protocol,rip_recv);
  17. up->cb.rip->user = s;
  18. return 0;
  19. }
  20. int
  21. so_ip_conn(up)
  22. struct usock *up;
  23. {
  24. if(up->name == NULL)
  25. autobind(up);
  26. return 0;
  27. }
  28. int
  29. so_ip_recv(up,bpp,from,fromlen)
  30. struct usock *up;
  31. struct mbuf **bpp;
  32. struct sockaddr *from;
  33. int *fromlen;
  34. {
  35. struct raw_ip *rip;
  36. struct sockaddr_in *remote;
  37. struct ip ip;
  38. int cnt;
  39. while((rip = up->cb.rip) != NULL && rip->rcvq == NULL){
  40. if(up->noblock){
  41. errno = EWOULDBLOCK;
  42. return -1;
  43. } else if((errno = kwait(up)) != 0){
  44. return -1;
  45. }
  46. }
  47. if(rip == NULL){
  48. /* Connection went away */
  49. errno = ENOTCONN;
  50. return -1;
  51. }
  52. *bpp = dequeue(&rip->rcvq);
  53. ntohip(&ip,bpp);
  54. cnt = len_p(*bpp);
  55. if(from != NULL && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  56. remote = (struct sockaddr_in *)from;
  57. remote->sin_family = AF_INET;
  58. remote->sin_addr.s_addr = ip.source;
  59. remote->sin_port = 0;
  60. *fromlen = SOCKSIZE;
  61. }
  62. return cnt;
  63. }
  64. int
  65. so_ip_send(
  66. struct usock *up,
  67. struct mbuf **bpp,
  68. struct sockaddr *to
  69. ){
  70. struct sockaddr_in *local,*remote;
  71. if(up->name == NULL)
  72. autobind(up);
  73. local = (struct sockaddr_in *)up->name;
  74. if(to != NULL){
  75. remote = (struct sockaddr_in *)to;
  76. } else if(up->peername != NULL) {
  77. remote = (struct sockaddr_in *)up->peername;
  78. } else {
  79. free_p(bpp);
  80. errno = ENOTCONN;
  81. return -1;
  82. }
  83. ip_send(local->sin_addr.s_addr,remote->sin_addr.s_addr,
  84. (char)up->cb.rip->protocol,0,0,bpp,0,0,0);
  85. return 0;
  86. }
  87. int
  88. so_ip_qlen(up,rtx)
  89. struct usock *up;
  90. int rtx;
  91. {
  92. int len;
  93. switch(rtx){
  94. case 0:
  95. len = len_q(up->cb.rip->rcvq);
  96. break;
  97. case 1:
  98. len = 0;
  99. break;
  100. }
  101. return len;
  102. }
  103. int
  104. so_ip_close(up)
  105. struct usock *up;
  106. {
  107. del_ip(up->cb.rip);
  108. return 0;
  109. }
  110. int
  111. checkipaddr(name,namelen)
  112. struct sockaddr *name;
  113. int namelen;
  114. {
  115. struct sockaddr_in *sock;
  116. sock = (struct sockaddr_in *)name;
  117. if(sock->sin_family != AF_INET || namelen != sizeof(struct sockaddr_in))
  118. return -1;
  119. return 0;
  120. }
  121. /* Raw IP receive upcall routine */
  122. static void
  123. rip_recv(rp)
  124. struct raw_ip *rp;
  125. {
  126. ksignal(itop(rp->user),1);
  127. kwait(NULL);
  128. }
  129. /* Issue an automatic bind of a local address */
  130. static void
  131. autobind(up)
  132. struct usock *up;
  133. {
  134. struct sockaddr_in local;
  135. int s;
  136. s = up->index;
  137. local.sin_family = AF_INET;
  138. local.sin_addr.s_addr = INADDR_ANY;
  139. local.sin_port = Lport++;
  140. bind(s,(struct sockaddr *)&local,sizeof(struct sockaddr_in));
  141. }
  142. char *
  143. ippsocket(p)
  144. struct sockaddr *p;
  145. {
  146. struct sockaddr_in *sp;
  147. struct socket socket;
  148. static char buf[30];
  149. sp = (struct sockaddr_in *)p;
  150. socket.address = sp->sin_addr.s_addr;
  151. socket.port = sp->sin_port;
  152. strcpy(buf,pinet(&socket));
  153. return buf;
  154. }