ss.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * ss.c
  3. * Standard structure processing.
  4. *
  5. * Matej Pfajfar <mp292@cam.ac.uk>
  6. */
  7. /*
  8. * Changes :
  9. * $Log$
  10. * Revision 1.1 2002/06/26 22:45:50 arma
  11. * Initial revision
  12. *
  13. * Revision 1.1 2002/04/02 14:28:01 badbytes
  14. * Final finishes.
  15. *
  16. */
  17. #include <malloc.h>
  18. #include <unistd.h>
  19. #include "../common/log.h"
  20. #include "../common/version.h"
  21. #include "../common/utils.h"
  22. #include "ss.h"
  23. /* read the standard structure, check if it's acceptable and send an appropriate error code
  24. * Returns :
  25. * -1 processing error
  26. * 0 OK
  27. * 1 no error, but standard structure rejected
  28. */
  29. int process_ss(int s, struct timeval *conn_toutp, ss_t **ssp, char **addrp, int *addrlenp, char **portp, int *portlenp)
  30. {
  31. int retval = 0;
  32. int len = 0; /* number of bytes read */
  33. ss_t *ss; /* standard structure */
  34. char errcode = SS_ERROR_SUCCESS; /* error code which we send back to the client */
  35. char inbuf;
  36. char *addr = NULL; /* destination address */
  37. int addrlen = 0;
  38. char *port = NULL; /* destination port */
  39. int portlen = 0;
  40. char *tmp = NULL; /* temporary storage */
  41. if ((!ssp) || (!addrp) || (!addrlenp) || (!portp) || (!portlenp)) /* invalid parameters */
  42. return -1;
  43. /* allocate memory for SS */
  44. ss = malloc(sizeof(ss_t));
  45. if (!ss)
  46. {
  47. log(LOG_ERR,"Error allocating memory.");
  48. return -1;
  49. }
  50. log(LOG_DEBUG,"Allocated memory for ss.");
  51. len = 0;
  52. while (len < sizeof(ss_t)) /* need to make sure the entire ss is read */
  53. {
  54. retval = read_tout(s,(char *)ss+len,sizeof(ss_t)-len,0, conn_toutp);
  55. if (retval <= 0)
  56. {
  57. free(ss);
  58. log(LOG_ERR,"Could not receive standard structure.");
  59. return -1;
  60. }
  61. len +=retval;
  62. }
  63. if ((ss->version == 0) || (ss->version != VERSION)) /* unsupported version */
  64. {
  65. log(LOG_DEBUG,"Unsupported version.");
  66. free(ss);
  67. errcode = SS_ERROR_VERSION_UNSUPPORTED;
  68. write_tout(s,&errcode,1,conn_toutp);
  69. return -1;
  70. }
  71. if (ss->addr_fmt != SS_ADDR_FMT_ASCII_HOST_PORT) /* unrecognized address format */
  72. {
  73. log(LOG_DEBUG,"Unrecognized address format.");
  74. free(ss);
  75. errcode = SS_ERROR_ADDR_FMT_UNSUPPORTED;
  76. write_tout(s,&errcode,1,conn_toutp);
  77. return -1;
  78. }
  79. /* allocate memory for the destination address - 512 bytes maximum */
  80. addrlen=512;
  81. addr = malloc(addrlen);
  82. if (!addr)
  83. {
  84. free(ss);
  85. log(LOG_ERR,"Error allocating memory.");
  86. return -1;
  87. }
  88. /* now read the destination address */
  89. len = 0;
  90. do /* need to keep going until the entire string is read in */
  91. {
  92. if (len == addrlen) /* we've run out of space, abort */
  93. {
  94. free(ss);
  95. free(addr);
  96. log(LOG_ERR,"Client tried to send address > 512 characters.");
  97. errcode = SS_ERROR_INVALID_ADDRESS;
  98. write_tout(s,&errcode,1,conn_toutp);
  99. return -1;
  100. }
  101. retval = read_tout(s,(void *)&inbuf, 1, 0, conn_toutp);
  102. if (retval <= 0)
  103. {
  104. free(ss);
  105. free(addr);
  106. log(LOG_ERR,"Error receiving destination address.");
  107. return -1;
  108. }
  109. *(addr+len) = inbuf;
  110. len++;
  111. } while (inbuf != 0);
  112. /* allocate memory for the destination port - 6 bytes maximum */
  113. portlen = 6;
  114. port = malloc(portlen);
  115. if (!port)
  116. {
  117. free(ss);
  118. log(LOG_ERR,"Error allocating memory.");
  119. free(addr);
  120. return -1;
  121. }
  122. /* now read the destination port */
  123. len = 0;
  124. do /* keep going until the entire string is read in */
  125. {
  126. if (len == portlen) /* no more space, abort */
  127. {
  128. free(ss);
  129. free(addr);
  130. free(port);
  131. log(LOG_ERR,"Client tried to send port > 6 characters.");
  132. errcode = SS_ERROR_INVALID_PORT;
  133. write_tout(s,&errcode,1,conn_toutp);
  134. return -1;
  135. }
  136. retval = read_tout(s,(void *)&inbuf, 1, 0, conn_toutp);
  137. if (retval <= 0)
  138. {
  139. free(ss);
  140. free(addr);
  141. free(port);
  142. log(LOG_ERR,"Error receiving destination port.");
  143. return -1;
  144. }
  145. *(port+len)=inbuf;
  146. len++;
  147. } while (inbuf != 0);
  148. /* send a success error code back to the client */
  149. errcode = SS_ERROR_SUCCESS;
  150. write_tout(s,&errcode,1,conn_toutp);
  151. /* done, now save */
  152. addrlen = strlen(addr)+1;
  153. tmp = addr;
  154. addr = realloc(addr,addrlen);
  155. /* if realloc() fails, we just ignore it and use the previously allocated memory, although this may be wasteful */
  156. if (!addr)
  157. addr=tmp; /* restore previous state */
  158. else
  159. addr[addrlen-1]=0;
  160. portlen = strlen(port)+1;
  161. tmp=port;
  162. port = realloc(port,portlen);
  163. if (!port)
  164. port=tmp;
  165. else
  166. port[portlen-1]=0;
  167. *ssp = ss;
  168. *addrp = addr;
  169. *addrlenp = addrlen;
  170. *portp = port;
  171. *portlenp = portlen;
  172. return 0;
  173. }