socks4.c
上传用户:qunlip
上传日期:2007-01-04
资源大小:203k
文件大小:4k
源码类别:

代理服务器

开发平台:

Visual C++

  1. char *socks4_rcs = "$Id: socks4.c,v 1.10 1997/09/11 18:35:41 ACJC Exp $";
  2. /* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
  3.  * Distributed under the GNU General Public License; see the README file.
  4.  * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
  5.  */
  6. #include <stdio.h>
  7. #include <sys/types.h>
  8. #include <errno.h>
  9. #ifdef _WIN32
  10. #include <io.h>
  11. #include <windows.h>
  12. #else
  13. #include <unistd.h>
  14. #include <netinet/in.h>
  15. #endif
  16. #ifdef REGEX
  17. #include <gnu_regex.h>
  18. #endif
  19. #include "jcc.h"
  20. #define SOCKS_REQUEST_GRANTED 90
  21. #define SOCKS_REQUEST_REJECT 91
  22. #define SOCKS_REQUEST_IDENT_FAILED 92
  23. #define SOCKS_REQUEST_IDENT_CONFLICT 93
  24. /* structure of a socks client operation */
  25. struct socks_op {
  26. unsigned char vn; /* socks version number */
  27. unsigned char cd; /* command code */
  28. unsigned char dstport[2]; /* destination port */
  29. unsigned char dstip[4]; /* destination address */
  30. unsigned char userid; /* first byte of userid */
  31. /* more bytes of the userid follow, terminated by a NULL */
  32. };
  33. /* structure of a socks server reply */
  34. struct socks_reply {
  35. unsigned char vn; /* socks version number */
  36. unsigned char cd; /* command code */
  37. unsigned char dstport[2]; /* destination port */
  38. unsigned char dstip[4]; /* destination address */
  39. };
  40. static char socks_userid[] = "anonymous";
  41. int
  42. socks4_connect(struct gateway *gw, struct http_request *http, struct client_state *csp)
  43. {
  44. unsigned char cbuf[BUFSIZ];
  45. unsigned char sbuf[BUFSIZ];
  46. struct socks_op    *c = (struct socks_op    *)cbuf;
  47. struct socks_reply *s = (struct socks_reply *)sbuf;
  48. int web_server_addr;
  49. int n, csiz, sfd, target_port;
  50. int err = 0;
  51. char *errstr, *target_host;
  52. if((gw->gateway_host == NULL) || (*gw->gateway_host == '')) {
  53. if(DEBUG(CON)) fprintf(logfp,
  54. " socks4_connect: NULL gateway host specifiedn");
  55. err = 1;
  56. }
  57. if(gw->gateway_port <= 0) {
  58. if(DEBUG(CON)) fprintf(logfp,
  59. " socks4_connect: invalid gateway port specifiedn");
  60. err = 1;
  61. }
  62. if(err) {
  63. errno = EINVAL;
  64. return(-1);
  65. }
  66. if(gw->forward_host) {
  67. target_host = gw->forward_host;
  68. target_port = gw->forward_port;
  69. } else {
  70. target_host = http->host;
  71. target_port = http->port;
  72. }
  73. /* build a socks request for connection to the web server */
  74. strcpy((char *)&(c->userid), socks_userid);
  75. csiz = sizeof(*c) + sizeof(socks_userid) - 1;
  76. switch(gw->type) {
  77. case SOCKS_4:
  78. web_server_addr = htonl(atoip(target_host));
  79. break;
  80. case SOCKS_4A:
  81. web_server_addr = 0x00000001;
  82. n = csiz + strlen(target_host) + 1;
  83. if(n > sizeof(cbuf)) {
  84. errno = EINVAL;
  85. return(-1);
  86. }
  87. strcpy(((char *)cbuf) + csiz, http->host);
  88. csiz = n;
  89. break;
  90. }
  91. c->vn         = 4;
  92. c->cd         = 1;
  93. c->dstport[0] = (target_port      >> 8) & 0xff;
  94. c->dstport[1] = (target_port          ) & 0xff;
  95. c->dstip[0]   = (web_server_addr >> 24) & 0xff;
  96. c->dstip[1]   = (web_server_addr >> 16) & 0xff;
  97. c->dstip[2]   = (web_server_addr >>  8) & 0xff;
  98. c->dstip[3]   = (web_server_addr      ) & 0xff;
  99. /* pass the request to the socks server */
  100. sfd = connect_to(gw->gateway_host, gw->gateway_port, csp);
  101. if(sfd < 0) {
  102. return(-1);
  103. }
  104. if((n = write_socket(sfd, c, csiz)) != csiz) {
  105. if(DEBUG(CON)) {
  106. fprintf(logfp, "SOCKS4 negotiation write failed...");
  107. }
  108. close_socket(sfd);
  109. return(-1);
  110. }
  111. if((n = read_socket(sfd, sbuf, sizeof(sbuf))) != sizeof(*s)) {
  112. if(DEBUG(CON)) {
  113. fprintf(logfp, "SOCKS4 negotiation read failed...");
  114. }
  115. close_socket(sfd);
  116. return(-1);
  117. }
  118. switch(s->cd) {
  119. case SOCKS_REQUEST_GRANTED:
  120. return(sfd);
  121. break;
  122. case SOCKS_REQUEST_REJECT:
  123. errstr = "SOCKS request rejected or failed";
  124. errno = EINVAL;
  125. break;
  126. case SOCKS_REQUEST_IDENT_FAILED:
  127. errstr = "SOCKS request rejected because "
  128.  "SOCKS server cannot connect to identd on the client";
  129. errno = EACCES;
  130. break;
  131. case SOCKS_REQUEST_IDENT_CONFLICT:
  132. errstr = "SOCKS request rejected because "
  133.  "the client program and identd report "
  134.  "different user-ids";
  135. errno = EACCES;
  136. break;
  137. default:
  138. errstr = (char *) cbuf;
  139. errno = ENOENT;
  140. sprintf(errstr,
  141. "SOCKS request rejected for reason code %dn", s->cd);
  142. }
  143. if(DEBUG(CON)) {
  144. fprintf(logfp, " socks4_connect: %s ...", errstr);
  145. }
  146. close_socket(sfd);
  147. return(-1);
  148. }