udp_test_proxy.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Copyright (C) 2001-2003 FhG Fokus
  3. *
  4. * This file is part of Kamailio, a free SIP server.
  5. *
  6. * Kamailio is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * Kamailio is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <errno.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <netdb.h>
  26. #include <unistd.h>
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. static char *id="$Id$";
  32. static char *version="udp_test_proxy 0.1";
  33. static char* help_msg="\
  34. Usage: udp_test_proxy -l address -s port -d address -p port [-n no] [-v]\n\
  35. Options:\n\
  36. -l address listen address\n\
  37. -s port listen(source) port\n\
  38. -d address destination address\n\
  39. -p port destination port\n\
  40. -n no number of processes\n\
  41. -2 use a different socket for sending\n\
  42. -v increase verbosity level\n\
  43. -V version number\n\
  44. -h this help message\n\
  45. ";
  46. #define BUF_SIZE 65535
  47. static char buf[BUF_SIZE];
  48. int main(int argc, char** argv)
  49. {
  50. int sock;
  51. int s_sock;
  52. pid_t pid;
  53. struct sockaddr_in addr;
  54. struct sockaddr_in to;
  55. int r, n, len;
  56. char c;
  57. struct hostent* he;
  58. int verbose;
  59. int sport, dport;
  60. char *dst;
  61. char *src;
  62. char* tmp;
  63. int use_diff_ssock;
  64. /* init */
  65. verbose=0;
  66. dst=0;
  67. sport=dport=0;
  68. src=dst=0;
  69. n=0;
  70. use_diff_ssock=0;
  71. opterr=0;
  72. while ((c=getopt(argc,argv, "l:p:d:s:n:2vhV"))!=-1){
  73. switch(c){
  74. case '2':
  75. use_diff_ssock=1;
  76. break;
  77. case 'v':
  78. verbose++;
  79. break;
  80. case 'd':
  81. dst=optarg;
  82. break;
  83. case 'l':
  84. src=optarg;
  85. break;
  86. case 'p':
  87. dport=strtol(optarg, &tmp, 10);
  88. if ((tmp==0)||(*tmp)){
  89. fprintf(stderr, "bad port number: -p %s\n", optarg);
  90. goto error;
  91. }
  92. break;
  93. case 's':
  94. sport=strtol(optarg, &tmp, 10);
  95. if ((tmp==0)||(*tmp)){
  96. fprintf(stderr, "bad port number: -s %s\n", optarg);
  97. goto error;
  98. }
  99. break;
  100. case 'n':
  101. n=strtol(optarg, &tmp, 10);
  102. if ((tmp==0)||(*tmp)){
  103. fprintf(stderr, "bad process number: -n %s\n", optarg);
  104. goto error;
  105. }
  106. break;
  107. case 'V':
  108. printf("version: %s\n", version);
  109. printf("%s\n",id);
  110. exit(0);
  111. break;
  112. case 'h':
  113. printf("version: %s\n", version);
  114. printf("%s", help_msg);
  115. exit(0);
  116. break;
  117. case '?':
  118. if (isprint(optopt))
  119. fprintf(stderr, "Unknown option `-%c´\n", optopt);
  120. else
  121. fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
  122. goto error;
  123. case ':':
  124. fprintf(stderr, "Option `-%c´ requires an argument.\n",
  125. optopt);
  126. goto error;
  127. break;
  128. default:
  129. abort();
  130. }
  131. }
  132. /* check if all the required params are present */
  133. if (dst==0){
  134. fprintf(stderr, "Missing destination (-d ...)\n");
  135. exit(-1);
  136. }
  137. if (src==0){
  138. fprintf(stderr, "Missing listen address (-l ...)\n");
  139. exit(-1);
  140. }
  141. if(sport==0){
  142. fprintf(stderr, "Missing source port number (-s port)\n");
  143. exit(-1);
  144. }else if(sport<0){
  145. fprintf(stderr, "Invalid source port number (-s %d)\n", sport);
  146. exit(-1);
  147. }
  148. if(dport==0){
  149. fprintf(stderr, "Missing destination port number (-p port)\n");
  150. exit(-1);
  151. }else if(dport<0){
  152. fprintf(stderr, "Invalid destination port number (-p %d)\n", dport);
  153. exit(-1);
  154. }
  155. if(n<0){
  156. fprintf(stderr, "Invalid process no (-n %d)\n", n);
  157. exit(-1);
  158. }
  159. /* resolve destination */
  160. he=gethostbyname(dst);
  161. if (he==0){
  162. fprintf(stderr, "ERROR: could not resolve %s\n", dst);
  163. goto error;
  164. }
  165. /* set to*/
  166. to.sin_family=he->h_addrtype;
  167. to.sin_port=htons(dport);
  168. memcpy(&to.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
  169. /* resolve source/listen */
  170. he=gethostbyname(src);
  171. if (he==0){
  172. fprintf(stderr, "ERROR: could not resolve %s\n", dst);
  173. goto error;
  174. }
  175. /* open socket*/
  176. addr.sin_family=he->h_addrtype;
  177. addr.sin_port=htons(sport);
  178. memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
  179. s_sock=-1;
  180. sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
  181. if (use_diff_ssock && (sock!=-1))
  182. s_sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
  183. else
  184. s_sock=sock;
  185. if ((sock==-1)||(s_sock==-1)){
  186. fprintf(stderr, "ERROR: socket: %s\n", strerror(errno));
  187. goto error;
  188. }
  189. if (bind(sock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in))==-1){
  190. fprintf(stderr, "ERROR: bind: %s\n", strerror(errno));
  191. goto error;
  192. }
  193. if (use_diff_ssock){
  194. if (connect(s_sock, (struct sockaddr*) &to,
  195. sizeof(struct sockaddr_in))==-1){
  196. fprintf(stderr, "ERROR: connect: %s\n", strerror(errno));
  197. goto error;
  198. }
  199. }
  200. for(r=1; r<n; r++){
  201. if ((pid=fork())==-1){
  202. fprintf(stderr, "ERROR: fork: %s\n", strerror(errno));
  203. goto error;
  204. }
  205. if (pid==0) break; /* child, skip */
  206. }
  207. if (verbose>3) printf("process starting\n");
  208. for(;;){
  209. len=read(sock, buf, BUF_SIZE);
  210. if (len==-1){
  211. fprintf(stderr, "ERROR: read: %s\n", strerror(errno));
  212. continue;
  213. }
  214. if (verbose>2) putchar('r');
  215. /* send it back*/
  216. if (use_diff_ssock)
  217. len=send(s_sock, buf, len, 0);
  218. else
  219. len=sendto(s_sock, buf, len, 0,
  220. (struct sockaddr*) &to, sizeof(struct sockaddr_in));
  221. if (len==-1){
  222. fprintf(stderr, "ERROR: send: %s\n", strerror(errno));
  223. continue;
  224. }
  225. if (verbose>1) putchar('.');
  226. }
  227. error:
  228. exit(-1);
  229. }