[insert project logo here (125x200px max)] Navigator Mailinglists Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums. Copyright and Licensing Information Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL). All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License. All sourcecode is made publicly available. Acknowledgement Splash and the Splash website are hosted by SourceForge.net |
Splash - DocumentationSNMP Plus a Lightweight API for SNAP Handlingsnap-1.1-wjdb/src/snap_sendandreceive.cGo to the documentation of this file.00001 /* 00002 * snap_sendandreceive.c : SNAP user-space node daemon. 00003 * Sends a package and waits for a return packet 00004 * It prints the stack output of the return packet 00005 * 00006 * $Id: snap_sendandreceive.c,v 1.7 2003/01/11 13:15:00 wdebruij Exp $ 00007 */ 00008 00009 #include <time.h> 00010 #include <sys/time.h> 00011 #include "../lib/libsnap.h" 00012 #include <arpa/inet.h> 00013 #include <assert.h> 00014 #include <fcntl.h> 00015 #include <netinet/ip.h> 00016 #include <netdb.h> 00017 #include <netinet/in.h> 00018 #include <unistd.h> 00019 #include <stdio.h> 00020 #include <string.h> 00021 #include <sys/socket.h> 00022 #include <sys/un.h> 00023 #include <sys/stat.h> 00024 #include <sys/types.h> 00025 #include "../lib/snap.h" 00026 #include "../lib/bytecode.h" 00027 #include "../lib/packet.h" 00028 #include "../lib/d_printf.h" 00029 #include "../lib/memalloc.h" 00030 #include "../lib/io.h" 00031 #include <pthread.h> 00032 00033 #include "snap_demux_handler.h" 00034 00035 #define NIPQUAD(addr) \ 00036 ((unsigned char *)&addr)[0], \ 00037 ((unsigned char *)&addr)[1], \ 00038 ((unsigned char *)&addr)[2], \ 00039 ((unsigned char *)&addr)[3] 00040 00041 #define IPPROTO_SNAP 130 00042 #define NO_RUNS 101 00043 00044 /* settable options */ 00045 unsigned char out_ttl = 32; 00046 short int receiveport = 7777; 00047 struct sockaddr_in destaddr; 00048 struct sockaddr_in srcaddr; 00049 struct sockaddr_in localaddr; 00050 00051 extern char *basename(const char *); 00052 void parse_cmdline(int argc,char **argv); 00053 00054 int infd; 00055 buffer_t inbuf; 00056 int sd; 00057 00058 int compare_longints(const void* a, const void* b){ 00059 const long int *da = (const long int *) a; 00060 const long int *db = (const long int *) b; 00061 00062 return (*da > *db) - (*da < *db); 00063 } 00064 00065 int init_request(int argc,char **argv) { 00066 int packet_lenb; 00067 struct snaphdr *hdr; 00068 char ra_space[4]; 00069 00070 parse_cmdline(argc,argv); 00071 00072 /* first suck in the binary packet */ 00073 packet_lenb = file_to_str(infd,&inbuf); 00074 if (packet_lenb < inbuf.lenb) 00075 inbuf.lenb = packet_lenb; 00076 d_printf(50,"read in %d bytes\n",inbuf.lenb); 00077 00078 /* touch up certain SNAP header entries */ 00079 hdr = (struct snaphdr *)inbuf.s; 00080 hdr->saddr = srcaddr.sin_addr.s_addr; 00081 hdr->daddr = destaddr.sin_addr.s_addr; 00082 hdr->version = 1; 00083 hdr->flags = 0; 00084 hdr->sport = htons(receiveport); 00085 00086 /* open up raw socket */ 00087 if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_SNAP)) < 0) { 00088 perror("inject: socket"); 00089 exit(1); 00090 } 00091 00092 /* set socket options : first, router alert */ 00093 bzero(ra_space,4); 00094 ra_space[IPOPT_OPTVAL] = IPOPT_RA; 00095 ra_space[IPOPT_OLEN] = 4; 00096 if (setsockopt(sd, IPPROTO_IP, IP_OPTIONS, ra_space, 00097 sizeof(ra_space)) < 0) { 00098 perror("inject: setsockopt: router alert"); 00099 exit(1); 00100 } 00101 00102 /* now set resource bound as requested */ 00103 if (setsockopt(sd, IPPROTO_IP, IP_TTL, 00104 (char *)&out_ttl, sizeof(out_ttl)) < 0) { 00105 perror("inject: setsockopt: ttl"); 00106 exit(1); 00107 } 00108 00109 return(0); 00110 } 00111 00112 void sendpkt(){ 00113 /* send to the local interpreter */ 00114 /* replace localaddr with destaddr in the sendto(..) to send directly */ 00115 localaddr.sin_addr.s_addr = htonl( (127 << 24) + 1 ); /* == 127.0.0.1 */ 00116 localaddr.sin_family = AF_INET; 00117 00118 if (sendto(sd, inbuf.s, inbuf.lenb, 0, (struct sockaddr *)&localaddr, 00119 sizeof(localaddr)) < 0) { 00120 perror("snap_sendandreceive : sendto"); 00121 } 00122 } 00123 00124 void usage(int argc, char **argv) { 00125 printf("usage: %s [-?] [-t ttl] [-p receiveport] src dest infile\n",basename(argv[0])); 00126 printf("\t-t : set the outgoing TTL (resource bound) (default=16)\n"); 00127 printf("\t-p : set the source port number (default=7777)\n"); 00128 printf("\t-? : print this help\n"); 00129 } 00130 00131 void parse_cmdline(int argc, char **argv) { 00132 char *opts = "?t:p:"; 00133 char c; 00134 int args_expected = 3; 00135 int args_processed = 0; 00136 int argidx; 00137 char *infilename; 00138 00139 while((c = getopt(argc,argv,opts)) != EOF) { 00140 switch(c) { 00141 case '?': 00142 usage(argc,argv); 00143 exit(1); 00144 case 't': 00145 out_ttl = atoi(optarg); 00146 if (out_ttl <= 0) { 00147 fprintf(stderr,"%s: invalid TTL: %d\n",basename(argv[0]),out_ttl); 00148 fflush(stderr); 00149 usage(argc,argv); 00150 exit(1); 00151 } 00152 fprintf(stderr,"%s: setting TTL to %d\n",basename(argv[0]),out_ttl); 00153 break; 00154 case 'p': 00155 receiveport = atoi(optarg); 00156 if (receiveport <= 0) { 00157 fprintf(stderr,"%s: invalid source port: %d\n", 00158 basename(argv[0]),receiveport); 00159 fflush(stderr); 00160 usage(argc,argv); 00161 exit(1); 00162 } 00163 break; 00164 default: 00165 fprintf(stderr,"%s: unrecognized option -%c\n", 00166 basename(argv[0]),c); 00167 fflush(stderr); 00168 usage(argc,argv); 00169 exit(1); 00170 } 00171 } 00172 argidx = optind; 00173 00174 bzero(&destaddr,sizeof(destaddr)); 00175 00176 while(args_processed < args_expected) { 00177 if (argidx >= argc) { 00178 /* missing arguments */ 00179 printf("%s: missing argument(s)\n",basename(argv[0])); 00180 usage(argc,argv); 00181 exit(1); 00182 } 00183 switch(args_processed) { 00184 case 0: { /* source address */ 00185 struct hostent *srchostp = NULL; 00186 srchostp = gethostbyname(argv[argidx]); 00187 if (srchostp == NULL) { 00188 fprintf(stderr,"%s: unknown dest host %s\n", 00189 basename(argv[0]),argv[argidx]); 00190 fflush(stderr); 00191 usage(argc,argv); 00192 exit(1); 00193 } 00194 assert(srchostp->h_addrtype == AF_INET); 00195 assert(srchostp->h_length == sizeof(unsigned int)); 00196 memcpy(&srcaddr.sin_addr.s_addr,srchostp->h_addr,srchostp->h_length); 00197 srcaddr.sin_family = AF_INET; 00198 break; 00199 } 00200 case 1: { /* destination address */ 00201 struct hostent *desthostp = NULL; 00202 desthostp = gethostbyname(argv[argidx]); 00203 if (desthostp == NULL) { 00204 fprintf(stderr,"%s: unknown dest host %s\n", 00205 basename(argv[0]),argv[argidx]); 00206 fflush(stderr); 00207 usage(argc,argv); 00208 exit(1); 00209 } 00210 assert(desthostp->h_addrtype == AF_INET); 00211 assert(desthostp->h_length == sizeof(unsigned int)); 00212 memcpy(&destaddr.sin_addr.s_addr,desthostp->h_addr,desthostp->h_length); 00213 destaddr.sin_family = AF_INET; 00214 break; 00215 } 00216 case 2: /* packet file name */ 00217 infilename = argv[argidx]; 00218 if (strcmp(infilename,"-") == 0) { 00219 infd = 0; /* stdin */ 00220 } else { 00221 infd = open(infilename,O_RDONLY); 00222 if (infd == -1) { 00223 fprintf(stderr,"%s: unable to open file \"%s\" for input\n", 00224 basename(argv[0]),infilename); 00225 fflush(stderr); 00226 exit(1); 00227 } 00228 } 00229 break; 00230 } 00231 argidx++; 00232 args_processed++; 00233 } 00234 if (argidx < argc) { 00235 /* extra arguments */ 00236 printf("%s: extra argument(s)\n",basename(argv[0])); 00237 usage(argc,argv); 00238 exit(1); 00239 } 00240 return; 00241 } 00242 00243 int main(int argc, char** argv){ 00244 struct timeval tStart; 00245 struct timeval tEnd; 00246 long int tDiff, tAvg; 00247 int received=0, received_prev=-1; 00248 int timeouts=0, sent=0; 00249 char* env_val; 00250 int protocols; 00251 /*pthread_t snap_thread;*/ 00252 00253 struct timeval tSaves[NO_RUNS][2]; 00254 long int tDiffs[NO_RUNS]; 00255 int runCount = 0; 00256 00257 /* get starting time */ 00258 gettimeofday(&tStart,NULL); 00259 00260 /* initialize the request */ 00261 init_request (argc, argv); 00262 00263 /* initialize the recv protocol(s) */ 00264 env_val = getenv("SNAP_DEMUX_HANDLER"); 00265 if (env_val != NULL) 00266 protocols = atoi(env_val); 00267 else 00268 protocols = SNAP_UNIX; 00269 snap_demux_init(protocols); 00270 00271 /* execute the requests */ 00272 while (received < NO_RUNS){ 00273 if (received_prev == received) 00274 timeouts++; 00275 gettimeofday(&tSaves[received][0], NULL); 00276 received_prev = received; 00277 sendpkt(); 00278 sent++; 00279 if (snap_demux_handler((buffer_handler) &snap_demux_buffer_print_unsafe)) 00280 received++; 00281 00282 gettimeofday(&tSaves[received_prev][1], NULL); 00283 } 00284 00285 snap_demux_close(); 00286 00287 /* get the end time*/ 00288 gettimeofday(&tEnd, NULL); 00289 00290 /* write out the processing time per run */ 00291 tAvg = 0; 00292 00293 printf("\n"); 00294 for (runCount = 0; runCount < NO_RUNS; runCount++){ 00295 tDiff = ((tSaves[runCount][1].tv_sec - tSaves[runCount][0].tv_sec) * 1000000) + (tSaves[runCount][1].tv_usec - tSaves[runCount][0].tv_usec); 00296 tDiffs[runCount] = tDiff; 00297 printf("%.05ld : time to complete run %d \n",tDiff,runCount); 00298 tAvg += tDiff; 00299 } 00300 00301 printf("\n"); 00302 /* write out the total processing time */ 00303 tDiff = ((tEnd.tv_sec - tStart.tv_sec) * 1000000) + (tEnd.tv_usec - tStart.tv_usec); 00304 printf("the total execution took %ld milliseconds for %d runs.\n",tDiff,NO_RUNS); 00305 00306 /* write out the preprocessing time */ 00307 tDiff = ((tSaves[0][0].tv_sec - tStart.tv_sec) * 1000000) + (tSaves[0][0].tv_usec - tStart.tv_usec); 00308 printf("preprocessing took %ld microseconds.\n",tDiff); 00309 00310 /* write out the average processing time per run*/ 00311 printf("On average, a communication run took %ld microseconds\n", tAvg / NO_RUNS ); 00312 00313 /* write out the median of the processing time */ 00314 qsort(tDiffs, NO_RUNS, sizeof (long int), compare_longints); 00315 printf("the median of a communication run is %ld microseconds\n", tDiffs[(NO_RUNS / 2) + 1]); 00316 00317 /* write out the postprocessing time */ 00318 tDiff = ((tEnd.tv_sec - tSaves[NO_RUNS - 1][1].tv_sec) * 1000000) + (tEnd.tv_usec - tSaves[NO_RUNS - 1][1].tv_usec); 00319 printf("postprocessing took %ld microseconds.\n",tDiff); 00320 00321 /* write out the number of timeouts */ 00322 printf("there were %d TIMEOUT errors on %d sends. This gives and errorpercentage of %.2g\n",timeouts,sent,(double) (timeouts*100) / (double) sent); 00323 00324 /* write out the average processing time including pre and postprocessing */ 00325 tDiff = ((tEnd.tv_sec - tStart.tv_sec) * 1000000) + (tEnd.tv_usec - tStart.tv_usec); 00326 printf("On average, a complete request took %ld microseconds\n", tDiff / NO_RUNS ); 00327 00328 return 0; 00329 } |