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