00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <sys/types.h>
00019 #include <sys/time.h>
00020 #include <string.h>
00021 #include <ctype.h>
00022 #include <time.h>
00023 #include <unistd.h>
00024 #include <netdb.h>
00025 #include <sys/socket.h>
00026
00027 #include <regex.h>
00028 regex_t* regexp;
00029
00030 #define RESIZE 1024
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 long getaddress(char *host)
00046 {
00047 int i, dotcount=0;
00048 char *p = host;
00049 struct hostent* pent;
00050 long l, *lp;
00051
00052
00053
00054
00055 while (*p)
00056 {
00057 for (i = 0; i < 3; i++, p++)
00058 if (!isdigit(*p))
00059 break;
00060 if (*p != '.')
00061 break;
00062 p++;
00063 dotcount++;
00064 }
00065
00066
00067 if (dotcount == 3 && i > 0 && i <= 3)
00068 return inet_addr(host);
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 pent = gethostbyname(host);
00083 if (!pent) {
00084 perror("no gethostbyname");
00085 exit(2);
00086 }
00087
00088 lp = (long *) (pent->h_addr);
00089 l = *lp;
00090 return l;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 void shoot(char *buff, long address, int lport, int rport )
00110 {
00111 struct sockaddr_in addr;
00112
00113 struct sockaddr_in sockname;
00114 int ssock;
00115
00116
00117
00118
00119 int retryAfter = 500, i, len, ret;
00120 int nretries = 10;
00121 int sock;
00122 struct timeval tv;
00123 fd_set fd;
00124 char reply[1600];
00125
00126
00127 sock = (int)socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00128 if (sock==-1) {
00129 perror("no client socket");
00130 exit(2);
00131 }
00132
00133
00134 ssock = (int)socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00135 if (sock==-1) {
00136 perror("no server socket");
00137 exit(2);
00138 }
00139
00140 sockname.sin_family=AF_INET;
00141 sockname.sin_addr.s_addr = htonl( INADDR_ANY );
00142 sockname.sin_port = htons((short)lport);
00143 if (bind( ssock, (struct sockaddr *) &sockname, sizeof(sockname) )==-1) {
00144 perror("no bind");
00145 exit(2);
00146 }
00147
00148
00149
00150 regexp=(regex_t*)malloc(sizeof(regex_t));
00151 regcomp(regexp, "^SIP/[0-9]\\.[0-9] 1[0-9][0-9] ", REG_EXTENDED|REG_NOSUB|REG_ICASE);
00152
00153
00154
00155
00156 addr.sin_addr.s_addr = address;
00157 addr.sin_port = htons((short)rport);
00158 addr.sin_family = AF_INET;
00159
00160
00161
00162
00163 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
00164 if (ret==-1) {
00165 perror("no connect");
00166 exit(2);
00167 }
00168
00169
00170 for (i = 0; i < nretries; i++)
00171 {
00172 puts("/* request */");
00173 puts(buff);
00174 putchar('\n');
00175
00176 ret = send(sock, buff, strlen(buff), 0);
00177 if (ret==-1) {
00178 perror("send failure");
00179 exit( 1 );
00180 }
00181
00182
00183 tv.tv_sec = retryAfter/1000;
00184 tv.tv_usec = (retryAfter % 1000) * 1000;
00185
00186 FD_ZERO(&fd);
00187 FD_SET(ssock, &fd);
00188
00189
00190
00191
00192
00193 ret = select(6, &fd, NULL, NULL, &tv);
00194 if (ret == 0)
00195 {
00196 puts("\n/* timeout */\n");
00197 retryAfter = retryAfter * 2;
00198 if (retryAfter > 5000)
00199 retryAfter = 5000;
00200
00201
00202
00203
00204 continue;
00205 } else if ( ret == -1 ) {
00206 perror("select error");
00207 exit(2);
00208 }
00209 else if (FD_ISSET(ssock, &fd)) {
00210 puts ("\nmessage received\n");
00211 } else {
00212 puts("\nselect returned successfully, nothing received\n");
00213 continue;
00214 }
00215
00216
00217 len = sizeof(addr);
00218 ret = recv(ssock, reply, 1500, 0);
00219 if(ret > 0)
00220 {
00221 reply[ret] = 0;
00222 puts("/* reply */");
00223 puts(reply);
00224 putchar('\n');
00225
00226 if (regexec((regex_t*)regexp, reply, 0, 0, 0)==0) {
00227 puts(" provisional received; still waiting for a final response\n ");
00228 continue;
00229 } else {
00230 puts(" final received; congratulations!\n ");
00231 exit(0);
00232 }
00233
00234 }
00235 else {
00236 perror("recv error");
00237 exit(2);
00238 }
00239 }
00240
00241 puts("/* I give up retransmission....");
00242 exit(1);
00243 }
00244
00245 int main(int argc, char *argv[])
00246 {
00247 long address;
00248 FILE *pf;
00249 char buff[1600];
00250 int length;
00251 int lport=0;
00252 int rport=5060;
00253
00254 if (! (argc >= 3 && argc <= 5))
00255 {
00256 puts("usage: shoot file host [rport] [lport]");
00257 exit(2);
00258 }
00259
00260 address = getaddress(argv[2]);
00261 if (!address)
00262 {
00263 puts("error:unable to determine the remote host address.");
00264 exit(2);
00265 }
00266
00267
00268 if (argc >= 4)
00269 {
00270 rport = atoi(argv[3]);
00271 if (!rport) {
00272 puts("error: non-numerical remote port number");
00273 exit(1);
00274 }
00275 if (argc==5) {
00276 lport=atoi(argv[4]);
00277 if (!lport) {
00278 puts("error: non-numerical local port number");
00279 exit(1);
00280 }
00281 }
00282 }
00283
00284
00285 pf = fopen(argv[1], "rb");
00286 if (!pf)
00287 {
00288 puts("unable to open the file.\n");
00289 return 1;
00290 }
00291 length = fread(buff, 1, sizeof(buff), pf);
00292 if (length >= sizeof(buff))
00293 {
00294 puts("error:the file is too big. try files of less than 1500 bytes.");
00295 return 1;
00296 }
00297 fclose(pf);
00298 buff[length] = 0;
00299
00300 shoot(buff, address, lport, rport );
00301
00302
00303
00304
00305
00306
00307
00308 return 0;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325