📄 snap_sendandreceive.c
字号:
/* * snap_sendandreceive.c : SNAP user-space node daemon. * Sends a package and waits for a return packet * It prints the stack output of the return packet * * $Id: snap_sendandreceive.c,v 1.2 2003/09/17 11:26:10 tmoerlan Exp $ */#include <time.h>#include <sys/time.h>#include "../lib/libsnap.h"#include <arpa/inet.h>#include <assert.h>#include <fcntl.h>//#include <sys/types>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netdb.h>//#include <netinet/in.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/stat.h>#include <sys/types.h>#include "../lib/snap.h"#include "../lib/bytecode.h"#include "../lib/packet.h"#include "../lib/d_printf.h"#include "../lib/memalloc.h"#include "../lib/io.h"#include <pthread.h>#include "snap_demux_handler.h"#define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3]#define IPPROTO_SNAP 130#define NO_RUNS 101/* settable options */unsigned char out_ttl = 32;short int receiveport = 7777;struct sockaddr_in destaddr;struct sockaddr_in srcaddr;struct sockaddr_in localaddr;extern char *basename(const char *);void parse_cmdline(int argc,char **argv);int infd;buffer_t inbuf;int sd;int compare_longints(const void* a, const void* b){ const long int *da = (const long int *) a; const long int *db = (const long int *) b; return (*da > *db) - (*da < *db);}int init_request(int argc,char **argv) { int packet_lenb; struct snaphdr *hdr; char ra_space[4]; parse_cmdline(argc,argv); /* first suck in the binary packet */ packet_lenb = file_to_str(infd,&inbuf); if (packet_lenb < inbuf.lenb) inbuf.lenb = packet_lenb; d_printf(50,"read in %d bytes\n",inbuf.lenb); /* touch up certain SNAP header entries */ hdr = (struct snaphdr *)inbuf.s; hdr->saddr = srcaddr.sin_addr.s_addr; hdr->daddr = destaddr.sin_addr.s_addr; hdr->version = 1; hdr->flags = 0; hdr->sport = htons(receiveport); /* open up raw socket */ if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_SNAP)) < 0) { perror("inject: socket"); exit(1); } /* set socket options : first, router alert */ bzero(ra_space,4); ra_space[IPOPT_OPTVAL] = IPOPT_RA; ra_space[IPOPT_OLEN] = 4; if (setsockopt(sd, IPPROTO_IP, IP_OPTIONS, ra_space, sizeof(ra_space)) < 0) { perror("inject: setsockopt: router alert"); exit(1); } /* now set resource bound as requested */#ifdef LINUX if (setsockopt(sd, IPPROTO_IP, IP_TTL, (char *)&out_ttl, sizeof(out_ttl)) < 0) { perror("inject: setsockopt: ttl"); exit(1); }#else//freeBSD int ttl_int = (int) out_ttl; if (setsockopt(sd, IPPROTO_IP, IP_TTL, (void *)&ttl_int, sizeof(ttl_int)) < 0) { perror("inject: setsockopt: ttl"); exit(1); }#endif return(0);}void sendpkt(){ /* send to the local interpreter */ /* replace localaddr with destaddr in the sendto(..) to send directly */ localaddr.sin_addr.s_addr = htonl( (127 << 24) + 1 ); /* == 127.0.0.1 */ localaddr.sin_family = AF_INET; if (sendto(sd, inbuf.s, inbuf.lenb, 0, (struct sockaddr *)&localaddr, sizeof(localaddr)) < 0) { perror("snap_sendandreceive : sendto"); }}void usage(int argc, char **argv) { printf("usage: %s [-?] [-t ttl] [-p receiveport] src dest infile\n",basename(argv[0])); printf("\t-t : set the outgoing TTL (resource bound) (default=16)\n"); printf("\t-p : set the source port number (default=7777)\n"); printf("\t-? : print this help\n");}void parse_cmdline(int argc, char **argv) { char *opts = "?t:p:"; char c; int args_expected = 3; int args_processed = 0; int argidx; char *infilename; while((c = getopt(argc,argv,opts)) != EOF) { switch(c) { case '?': usage(argc,argv); exit(1); case 't': out_ttl = atoi(optarg); if (out_ttl <= 0) { fprintf(stderr,"%s: invalid TTL: %d\n",basename(argv[0]),out_ttl); fflush(stderr); usage(argc,argv); exit(1); } fprintf(stderr,"%s: setting TTL to %d\n",basename(argv[0]),out_ttl); break; case 'p': receiveport = atoi(optarg); if (receiveport <= 0) { fprintf(stderr,"%s: invalid source port: %d\n", basename(argv[0]),receiveport); fflush(stderr); usage(argc,argv); exit(1); } break; default: fprintf(stderr,"%s: unrecognized option -%c\n", basename(argv[0]),c); fflush(stderr); usage(argc,argv); exit(1); } } argidx = optind; bzero(&destaddr,sizeof(destaddr)); while(args_processed < args_expected) { if (argidx >= argc) { /* missing arguments */ printf("%s: missing argument(s)\n",basename(argv[0])); usage(argc,argv); exit(1); } switch(args_processed) { case 0: { /* source address */ struct hostent *srchostp = NULL; srchostp = gethostbyname(argv[argidx]); if (srchostp == NULL) { fprintf(stderr,"%s: unknown dest host %s\n", basename(argv[0]),argv[argidx]); fflush(stderr); usage(argc,argv); exit(1); } assert(srchostp->h_addrtype == AF_INET); assert(srchostp->h_length == sizeof(unsigned int)); memcpy(&srcaddr.sin_addr.s_addr,srchostp->h_addr,srchostp->h_length); srcaddr.sin_family = AF_INET; break; } case 1: { /* destination address */ struct hostent *desthostp = NULL; desthostp = gethostbyname(argv[argidx]); if (desthostp == NULL) { fprintf(stderr,"%s: unknown dest host %s\n", basename(argv[0]),argv[argidx]); fflush(stderr); usage(argc,argv); exit(1); } assert(desthostp->h_addrtype == AF_INET); assert(desthostp->h_length == sizeof(unsigned int)); memcpy(&destaddr.sin_addr.s_addr,desthostp->h_addr,desthostp->h_length); destaddr.sin_family = AF_INET; break; } case 2: /* packet file name */ infilename = argv[argidx]; if (strcmp(infilename,"-") == 0) { infd = 0; /* stdin */ } else { infd = open(infilename,O_RDONLY); if (infd == -1) { fprintf(stderr,"%s: unable to open file \"%s\" for input\n", basename(argv[0]),infilename); fflush(stderr); exit(1); } } break; } argidx++; args_processed++; } if (argidx < argc) { /* extra arguments */ printf("%s: extra argument(s)\n",basename(argv[0])); usage(argc,argv); exit(1); } return;}int main(int argc, char** argv){ struct timeval tStart; struct timeval tEnd; long int tDiff, tAvg; int received=0, received_prev=-1; int timeouts=0, sent=0; char* env_val; int protocols; /*pthread_t snap_thread;*/ struct timeval tSaves[NO_RUNS][2]; long int tDiffs[NO_RUNS]; int runCount = 0; /* get starting time */ gettimeofday(&tStart,NULL); /* initialize the request */ init_request (argc, argv); /* initialize the recv protocol(s) */ env_val = getenv("SNAP_DEMUX_HANDLER"); if (env_val != NULL) protocols = atoi(env_val); else protocols = SNAP_UNIX; snap_demux_init(protocols); /* execute the requests */ while (received < NO_RUNS){ if (received_prev == received) timeouts++; gettimeofday(&tSaves[received][0], NULL); received_prev = received; sendpkt(); sent++; if (snap_demux_handler((buffer_handler) &snap_demux_buffer_print_unsafe)) received++; gettimeofday(&tSaves[received_prev][1], NULL); } snap_demux_close(); /* get the end time*/ gettimeofday(&tEnd, NULL); /* write out the processing time per run */ tAvg = 0; printf("\n"); for (runCount = 0; runCount < NO_RUNS; runCount++){ tDiff = ((tSaves[runCount][1].tv_sec - tSaves[runCount][0].tv_sec) * 1000000) + (tSaves[runCount][1].tv_usec - tSaves[runCount][0].tv_usec); tDiffs[runCount] = tDiff; printf("%.05ld : time to complete run %d \n",tDiff,runCount); tAvg += tDiff; } printf("\n"); /* write out the total processing time */ tDiff = ((tEnd.tv_sec - tStart.tv_sec) * 1000000) + (tEnd.tv_usec - tStart.tv_usec); printf("the total execution took %ld milliseconds for %d runs.\n",tDiff,NO_RUNS); /* write out the preprocessing time */ tDiff = ((tSaves[0][0].tv_sec - tStart.tv_sec) * 1000000) + (tSaves[0][0].tv_usec - tStart.tv_usec); printf("preprocessing took %ld microseconds.\n",tDiff); /* write out the average processing time per run*/ printf("On average, a communication run took %ld microseconds\n", tAvg / NO_RUNS ); /* write out the median of the processing time */ qsort(tDiffs, NO_RUNS, sizeof (long int), compare_longints); printf("the median of a communication run is %ld microseconds\n", tDiffs[(NO_RUNS / 2) + 1]); /* write out the postprocessing time */ tDiff = ((tEnd.tv_sec - tSaves[NO_RUNS - 1][1].tv_sec) * 1000000) + (tEnd.tv_usec - tSaves[NO_RUNS - 1][1].tv_usec); printf("postprocessing took %ld microseconds.\n",tDiff); /* write out the number of timeouts */ printf("there were %d TIMEOUT errors on %d sends. This gives and errorpercentage of %.2g\n",timeouts,sent,(double) (timeouts*100) / (double) sent); /* write out the average processing time including pre and postprocessing */ tDiff = ((tEnd.tv_sec - tStart.tv_sec) * 1000000) + (tEnd.tv_usec - tStart.tv_usec); printf("On average, a complete request took %ld microseconds\n", tDiff / NO_RUNS ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -