📄 demo_router.c
字号:
/* * This is a demo router.* It is a very simple and dumb on-demand routing daemon.* But it illusrtrates how to use the Adhoc support library : libASL. * * Then it is basically a select loop : * * aslFD is the fd to communicate to the ODRM ad hoc support module * * The select loop implemented here is monitoring only aslFD. * other FDs can be added in the select loop. * Select has been used here to show how aslFD can be added to the select loop *//* include the api file for the Adhoc Support Library */#include <ASL/api.h>#include "demo_router.h"// File descriptors int aslFD; // file descriptor for listening to route_requests // from the ODRM ( On-demand routing module );struct in_addr def;// variables for getopt()extern char *optarg;extern int optind, opterr, optopt;/* * signal handler for SIGINT. * If somebody kills you, do some clean up before you exit. * Is is especially important to do a close_route_request(); */voiddie_gracefully(int signal){ printf("\nOuchhh.... KILL signal caught.\n"); printf("doing close_route_request()....\n"); close_route_request(aslFD); exit(1);}/* * dot_ip() : converts ip address from int to dot.dot notation. * is a wrapper around inet_ntoa so that you do not have * to declare a, in_addr structure * * dot_ip can be called only once in one statement. * this is because dot_ip uses inet_ntoa which returns in a statically * allocated buffer which is overwritten in each call. * hence you have to break up the printfs if there are multiple calls to dot_ip **/char *dot_ip(u_int32_t ipint){ struct in_addr ip; ip.s_addr = ipint ; return inet_ntoa(ip);}/* * * main() * -------- * the main routing daemon loop: * essentially a while loop with a select call **/intmain(int argc, char *argv[]){ char interface[10]; char ch; int res; //0.11 unsigned long idle_time; struct route_info *r_info; /* file descriptor set for select */ fd_set readfds; /* set handler to catch SIGINT * Its important to do a close_route_request() if somebody ^C 's you */ signal(SIGINT, die_gracefully); /* set some parameters in /proc necessary for ad-hoc routing */ /* enable ip forwarding */ system("sysctl -w net/ipv4/ip_forward=1"); /* disable sending and accepting of ICMP redirects */ system("sysctl -w net/ipv4/conf/all/accept_redirects=0"); system("sysctl -w net/ipv4/conf/all/send_redirects=0"); /* In the Linux kernel, a route cache is not flushed immediately after * a route change. There is some delay, which is controlled by three * parameters min_delay, max_delay, and flush in /proc/sys/net/ipv4/route * Read more in Documentation/filesystems/proc.txt of your kernel source. * Here I am changing the min_delay from default value of 2 sec to 0, * so that route changes are immediately reflected in the route cache. * Without this, packets continue to loop on the tun device for 2 seconds * even after the new route is added. Writing to the flush file, also * achieves the same thing, but has to be done everytime a route is changed. * * Thanks to Matt Miller <mjmille2@crhc.uiuc.edu> for pointing out this issue * , investigating it and providing the solution. */ system("sysctl -w net/ipv4/route/min_delay=0"); memset(interface,0,strlen(interface)); if(argc==1) { fprintf(stderr, "Usage : demo_router -i <interface> \n"); exit(1); } // parse the command line arguments while ((ch = getopt(argc, argv, "i:")) != EOF) { if (ch == -1 ) break ; switch (ch) { case 'i': strncpy(interface, optarg, strlen(optarg)); printf("demo_router() : Running on interface : %s \n", interface); break; default: fprintf(stderr, "Invalid arguments\n"); fprintf(stderr, "Usage : demo_router -i <interface> \n"); } if (optind < argc) { printf ("non-option ARGV-elements: "); fprintf(stderr, "Usage : demo_router -i <interface> \n"); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); exit (0); } } /* while */ /* open an fd to get route requests */ aslFD = open_route_request(); if (aslFD < 0) perror("Failed to open route request"); /* add a deffered route for the default destination. * 2nd argument = 0, implies that we are adding a defferred route */ inet_aton("0.0.0.0",&def); if (route_add(def.s_addr, 0, interface) < 0) perror("demo_router : adding deferred route"); /* * --------------------------- * Main program loop: * --------------------------- */ fprintf(stdout,"\nStarting select loop of demo_router().\n"); while(1) { FD_ZERO(&readfds); FD_SET(aslFD, &readfds); /* Wait until packet arrives on routerFD or aslFD ! */ if(select(aslFD + 1, &readfds, NULL, NULL, NULL) >= 0) { if(FD_ISSET(aslFD, &readfds)) { r_info = (struct route_info *)malloc(sizeof(struct route_info)); res = read_route_request(aslFD, r_info); if(res < 0) /* error in read_route_request */ { fprintf(stderr,"read_route_request():returned error code %d\n", res); exit(1); } if ( res== 0) /* duplicate request read, do nothing */ { printf("Duplicate route_request read. Since route disocvery already in progress, do nothing.\n"); continue ; } if ( res > 0 ) /* new route_request, initiate route discovery */ { fprintf(stdout,"demo_router :Read a route_info from the ODRM.\n"); fprintf(stdout,"\t r_info->dest_ip = %s \n", dot_ip(r_info->dest_ip)); fprintf(stdout,"\t r_info->src_ip = %s \n", dot_ip(r_info->src_ip)); fprintf(stdout,"\t r_info->protocol = %d \n", r_info->protocol); /* initiate route disovery()*/ /* for the purpose of the demo, we assume that we can get this * route by say making a phone call. Take 3 secs for this call */ sleep(3); /* add the route you just discovered */ /* Note this is a normal route and not a deferred route, so next_hop is not zero */ route_add(r_info->dest_ip,r_info->dest_ip, interface); /* if route found then return it thru route_discovery done * 2nd argument is ASL_ROUTE_FOUND if you were able to find *a valid route for dest_ip or ASL_NO_ROUTE if unable to do so */ if ( route_discovery_done(r_info->dest_ip, ASL_ROUTE_FOUND) < 0) fprintf(stderr,"demo_router() : error in route discovery done ()\n"); /* Lets wait 4 seconds and then query the idle time of the * route; the flag 1 indicates that this ip was recorded as * the destination of some packet .*/ sleep(4); idle_time = query_route_idle_time(r_info->dest_ip,1); if(idle_time < 0 ) { perror("demo_router(): Error querying idle time"); } else { printf("Idle time for %s is %lu msecs\n",dot_ip(r_info->dest_ip),idle_time); } } } /* add other file descriptors for the routing daemon here. * This could include the main socket on which the routing daemon recieves packets * and a timerFD to get notified of expired timers * and an FD to out put error messages etc.*/ /* else if (FD_ISSET(demoFD, &readfds)) { } */ } /* if select */ } // while(1) die_gracefully(0); } /* end main() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -