udp_test_proxy.c 5.4 KB

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