00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 #include <errno.h>
00033 #include <string.h>
00034 #include <ctype.h>
00035 #include <netdb.h>
00036 #include <unistd.h>
00037 #include <sys/types.h>
00038 #include <sys/socket.h>
00039 #include <netinet/in.h>
00040 #include <arpa/inet.h>
00041
00042
00043
00044 static char *id="$Id$";
00045 static char *version="udp_test_proxy 0.1";
00046 static char* help_msg="\
00047 Usage: udp_test_proxy -l address -s port -d address -p port [-n no] [-v]\n\
00048 Options:\n\
00049 -l address listen address\n\
00050 -s port listen(source) port\n\
00051 -d address destination address\n\
00052 -p port destination port\n\
00053 -n no number of processes\n\
00054 -2 use a different socket for sending\n\
00055 -v increase verbosity level\n\
00056 -V version number\n\
00057 -h this help message\n\
00058 ";
00059 #define BUF_SIZE 65535
00060 static char buf[BUF_SIZE];
00061
00062 int main(int argc, char** argv)
00063 {
00064 int sock;
00065 int s_sock;
00066 pid_t pid;
00067 struct sockaddr_in addr;
00068 struct sockaddr_in to;
00069 int r, n, len;
00070 char c;
00071 struct hostent* he;
00072 int verbose;
00073 int sport, dport;
00074 char *dst;
00075 char *src;
00076 char* tmp;
00077 int use_diff_ssock;
00078
00079
00080
00081 verbose=0;
00082 dst=0;
00083 sport=dport=0;
00084 src=dst=0;
00085 n=0;
00086 use_diff_ssock=0;
00087
00088 opterr=0;
00089 while ((c=getopt(argc,argv, "l:p:d:s:n:2vhV"))!=-1){
00090 switch(c){
00091 case '2':
00092 use_diff_ssock=1;
00093 break;
00094 case 'v':
00095 verbose++;
00096 break;
00097 case 'd':
00098 dst=optarg;
00099 break;
00100 case 'l':
00101 src=optarg;
00102 break;
00103 case 'p':
00104 dport=strtol(optarg, &tmp, 10);
00105 if ((tmp==0)||(*tmp)){
00106 fprintf(stderr, "bad port number: -p %s\n", optarg);
00107 goto error;
00108 }
00109 break;
00110 case 's':
00111 sport=strtol(optarg, &tmp, 10);
00112 if ((tmp==0)||(*tmp)){
00113 fprintf(stderr, "bad port number: -s %s\n", optarg);
00114 goto error;
00115 }
00116 break;
00117 case 'n':
00118 n=strtol(optarg, &tmp, 10);
00119 if ((tmp==0)||(*tmp)){
00120 fprintf(stderr, "bad process number: -n %s\n", optarg);
00121 goto error;
00122 }
00123 break;
00124 case 'V':
00125 printf("version: %s\n", version);
00126 printf("%s\n",id);
00127 exit(0);
00128 break;
00129 case 'h':
00130 printf("version: %s\n", version);
00131 printf("%s", help_msg);
00132 exit(0);
00133 break;
00134 case '?':
00135 if (isprint(optopt))
00136 fprintf(stderr, "Unknown option `-%c´\n", optopt);
00137 else
00138 fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
00139 goto error;
00140 case ':':
00141 fprintf(stderr, "Option `-%c´ requires an argument.\n",
00142 optopt);
00143 goto error;
00144 break;
00145 default:
00146 abort();
00147 }
00148 }
00149
00150
00151 if (dst==0){
00152 fprintf(stderr, "Missing destination (-d ...)\n");
00153 exit(-1);
00154 }
00155 if (src==0){
00156 fprintf(stderr, "Missing listen address (-l ...)\n");
00157 exit(-1);
00158 }
00159 if(sport==0){
00160 fprintf(stderr, "Missing source port number (-s port)\n");
00161 exit(-1);
00162 }else if(sport<0){
00163 fprintf(stderr, "Invalid source port number (-s %d)\n", sport);
00164 exit(-1);
00165 }
00166 if(dport==0){
00167 fprintf(stderr, "Missing destination port number (-p port)\n");
00168 exit(-1);
00169 }else if(dport<0){
00170 fprintf(stderr, "Invalid destination port number (-p %d)\n", dport);
00171 exit(-1);
00172 }
00173 if(n<0){
00174 fprintf(stderr, "Invalid process no (-n %d)\n", n);
00175 exit(-1);
00176 }
00177
00178
00179
00180 he=gethostbyname(dst);
00181 if (he==0){
00182 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
00183 goto error;
00184 }
00185
00186
00187 to.sin_family=he->h_addrtype;
00188 to.sin_port=htons(dport);
00189 memcpy(&to.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
00190
00191
00192 he=gethostbyname(src);
00193 if (he==0){
00194 fprintf(stderr, "ERROR: could not resolve %s\n", dst);
00195 goto error;
00196 }
00197
00198 addr.sin_family=he->h_addrtype;
00199 addr.sin_port=htons(sport);
00200 memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
00201
00202 s_sock=-1;
00203 sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
00204 if (use_diff_ssock && (sock!=-1))
00205 s_sock = socket(he->h_addrtype, SOCK_DGRAM, 0);
00206 else
00207 s_sock=sock;
00208
00209 if ((sock==-1)||(s_sock==-1)){
00210 fprintf(stderr, "ERROR: socket: %s\n", strerror(errno));
00211 goto error;
00212 }
00213 if (bind(sock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in))==-1){
00214 fprintf(stderr, "ERROR: bind: %s\n", strerror(errno));
00215 goto error;
00216 }
00217 if (use_diff_ssock){
00218 if (connect(s_sock, (struct sockaddr*) &to,
00219 sizeof(struct sockaddr_in))==-1){
00220 fprintf(stderr, "ERROR: connect: %s\n", strerror(errno));
00221 goto error;
00222 }
00223 }
00224
00225 for(r=1; r<n; r++){
00226 if ((pid=fork())==-1){
00227 fprintf(stderr, "ERROR: fork: %s\n", strerror(errno));
00228 goto error;
00229 }
00230 if (pid==0) break;
00231 }
00232
00233 if (verbose>3) printf("process starting\n");
00234 for(;;){
00235 len=read(sock, buf, BUF_SIZE);
00236 if (len==-1){
00237 fprintf(stderr, "ERROR: read: %s\n", strerror(errno));
00238 continue;
00239 }
00240 if (verbose>2) putchar('r');
00241
00242 if (use_diff_ssock)
00243 len=send(s_sock, buf, len, 0);
00244 else
00245 len=sendto(s_sock, buf, len, 0,
00246 (struct sockaddr*) &to, sizeof(struct sockaddr_in));
00247 if (len==-1){
00248 fprintf(stderr, "ERROR: send: %s\n", strerror(errno));
00249 continue;
00250 }
00251 if (verbose>1) putchar('.');
00252 }
00253 error:
00254 exit(-1);
00255 }