CVS substitutes introduced
[sip-router] / test / udp_test_proxy.c
1 /* 
2  * $Id$
3  *
4  */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <netdb.h>
12 #include <unistd.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17
18
19
20 static char *id="$Id$";
21 static char *version="udp_test_proxy 0.1";
22 static char* help_msg="\
23 Usage: udp_test_proxy  -l address -s port -d address -p port [-n no] [-v]\n\
24 Options:\n\
25     -l address    listen address\n\
26     -s port       listen(source) port\n\
27     -d address    destination address\n\
28     -p port       destination port\n\
29     -n no         number of processes\n\
30     -v            increase verbosity level\n\
31     -V            version number\n\
32     -h            this help message\n\
33 ";
34 #define BUF_SIZE 65535
35 static char buf[BUF_SIZE];
36
37 int main(int argc, char** argv)
38 {
39         int sock;
40         pid_t pid;
41         struct sockaddr_in addr;
42         struct sockaddr_in to;
43         int r, n, len;
44         char c;
45         struct hostent* he;
46         int verbose;
47         int sport, dport;
48         char *dst;
49         char *src;
50         char* tmp;
51
52
53         /* init */
54         verbose=0;
55         dst=0;
56         sport=dport=0;
57         src=dst=0;
58         n=0;
59         
60         opterr=0;
61         while ((c=getopt(argc,argv, "l:p:d:s:n:vhV"))!=-1){
62                 switch(c){
63                         case 'v':
64                                 verbose++;
65                                 break;
66                         case 'd':
67                                 dst=optarg;
68                                 break;
69                         case 'l':
70                                 src=optarg;
71                                 break;
72                         case 'p':
73                                 dport=strtol(optarg, &tmp, 10);
74                                 if ((tmp==0)||(*tmp)){
75                                         fprintf(stderr, "bad port number: -p %s\n", optarg);
76                                         goto error;
77                                 }
78                                 break;
79                         case 's':
80                                 sport=strtol(optarg, &tmp, 10);
81                                 if ((tmp==0)||(*tmp)){
82                                         fprintf(stderr, "bad port number: -s %s\n", optarg);
83                                         goto error;
84                                 }
85                                 break;
86                         case 'n':
87                                 n=strtol(optarg, &tmp, 10);
88                                 if ((tmp==0)||(*tmp)){
89                                         fprintf(stderr, "bad process number: -n %s\n", optarg);
90                                         goto error;
91                                 }
92                                 break;
93                         case 'V':
94                                 printf("version: %s\n", version);
95                                 printf("%s\n",id);
96                                 exit(0);
97                                 break;
98                         case 'h':
99                                 printf("version: %s\n", version);
100                                 printf("%s", help_msg);
101                                 exit(0);
102                                 break;
103                         case '?':
104                                 if (isprint(optopt))
105                                         fprintf(stderr, "Unknown option `-%c´\n", optopt);
106                                 else
107                                         fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
108                                 goto error;
109                         case ':':
110                                 fprintf(stderr, "Option `-%c´ requires an argument.\n",
111                                                 optopt);
112                                 goto error;
113                                 break;
114                         default:
115                                         abort();
116                 }
117         }
118
119         /* check if all the required params are present */
120         if (dst==0){
121                 fprintf(stderr, "Missing destination (-d ...)\n");
122                 exit(-1);
123         }
124         if (src==0){
125                 fprintf(stderr, "Missing listen address (-l ...)\n");
126                 exit(-1);
127         }
128         if(sport==0){
129                 fprintf(stderr, "Missing source port number (-s port)\n");
130                 exit(-1);
131         }else if(sport<0){
132                 fprintf(stderr, "Invalid source port number (-s %d)\n", sport);
133                 exit(-1);
134         }
135         if(dport==0){
136                 fprintf(stderr, "Missing destination port number (-p port)\n");
137                 exit(-1);
138         }else if(dport<0){
139                 fprintf(stderr, "Invalid destination port number (-p %d)\n", dport);
140                 exit(-1);
141         }
142         if(n<0){
143                 fprintf(stderr, "Invalid process no (-n %d)\n", n);
144                 exit(-1);
145         }
146
147
148         /* resolve destination */
149         he=gethostbyname(dst);
150         if (he==0){
151                 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
152                 goto error;
153         }
154
155         /* set to*/
156         to.sin_family=he->h_addrtype;
157         to.sin_port=htons(dport);
158         memcpy(&to.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
159
160         /* resolve source/listen */
161         he=gethostbyname(src);
162         if (he==0){
163                 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
164                 goto error;
165         }
166         /* open socket*/
167         addr.sin_family=he->h_addrtype;
168         addr.sin_port=htons(sport);
169         memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
170
171         sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
172         if (sock==-1){
173                 fprintf(stderr, "ERROR: socket: %s\n", strerror(errno));
174                 goto error;
175         }
176         if (bind(sock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in))==-1){
177                 fprintf(stderr, "ERROR: bind: %s\n", strerror(errno));
178                 goto error;
179         }
180
181         for(r=1; r<n; r++){
182                 if ((pid=fork())==-1){
183                         fprintf(stderr, "ERROR: fork: %s\n", strerror(errno));
184                         goto error;
185                 }
186                 if (pid==0) break; /* child, skip */
187         }
188
189         if (verbose>3) printf("process starting\n");
190         for(;;){
191                 len=read(sock, buf, BUF_SIZE);
192                 if (len==-1){
193                         fprintf(stderr, "ERROR: read: %s\n", strerror(errno));
194                         continue;
195                 }
196                 if (verbose>2) putchar('r');
197                 /* send it back*/
198                 len=sendto(sock, buf, len, 0, (struct sockaddr*) &to,
199                                 sizeof(struct sockaddr_in));
200                 if (len==-1){
201                         fprintf(stderr, "ERROR: sendto: %s\n", strerror(errno));
202                         continue;
203                 }
204                 if (verbose>1) putchar('.');
205         }
206 error:
207         exit(-1);
208 }