[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/lib/libsnap.cGo to the documentation of this file.00001 /* snap2snmp connection library */ 00002 /* (c) Willem de Bruijn, 2002 */ 00003 /* snaplibrary sourcefile */ 00004 00005 #include <stdarg.h> 00006 #include <pthread.h> 00007 00008 #define _GNU_SOURCE 00009 #include <assert.h> 00010 #include <features.h> 00011 #include <getopt.h> 00012 #include <net/if_arp.h> 00013 #include <netinet/in.h> 00014 #include <netinet/ip.h> 00015 #include <stdio.h> 00016 #include <stdlib.h> 00017 #include <string.h> 00018 #include <sys/socket.h> 00019 #include <sys/time.h> 00020 #include <sys/types.h> 00021 #include <unistd.h> 00022 #include <libgen.h> 00023 00024 #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 00025 #include <netpacket/packet.h> 00026 #include <net/ethernet.h> /* the L2 protocols */ 00027 #else 00028 #include <asm/types.h> 00029 #include <linux/if_packet.h> 00030 #include <linux/if_ether.h> /* The L2 protocols */ 00031 #endif 00032 00033 #include "d_printf.h" 00034 #include "snapnet.h" 00035 #include "packet.h" 00036 #include "snap.h" 00037 #include "version.h" 00038 #include "interp.h" 00039 #include "snap_kern_iface.h" 00040 #include "snap_svc_handler.h" 00041 00042 #define NIPQUAD(addr) \ 00043 ((unsigned char *)&(addr))[0], \ 00044 ((unsigned char *)&(addr))[1], \ 00045 ((unsigned char *)&(addr))[2], \ 00046 ((unsigned char *)&(addr))[3] 00047 00048 #ifndef UDPPORT 00049 #define UDPPORT 7777 00050 #endif 00051 00052 /* declaration of function. Definition can be found below.*/ 00053 int snap_receive(); 00054 00055 struct glob_conf { 00056 struct sockaddr_in herehint; 00057 } gc; 00058 00059 struct cmdline_args { 00060 int argc; 00061 char** argv; 00062 }; 00063 00064 void usage(char *myname); 00065 void parse_cmdline_snap(int argc, char *argv[]); 00066 00067 int ethsock = -1; 00068 int losock = -1; 00069 /* int udpsock = -1; 00070 */ int rawiprecvsock = -1; 00071 int maxfd; 00072 packet_t *p; 00073 /* struct sockaddr_ll bindhwaddr; */ 00074 fd_set rfds; 00075 unsigned char ra_space[4]; 00076 struct sockaddr_in bindaddr; 00077 struct sockaddr_in udpaddr; 00078 00079 int snap(struct cmdline_args *cargs) { 00080 00081 00082 #ifndef NDEBUG 00083 set_debug_level(); 00084 #endif 00085 00086 memset(&gc, 0, sizeof(gc)); 00087 if (cargs->argc > 0) /* we can call this function without arguments */ 00088 parse_cmdline_snap((*cargs).argc,(*cargs).argv); 00089 init_kern_iface(&gc.herehint); 00090 #ifdef CONFIG_IP_SNAP_SVCS 00091 snap_svc_handler_init(); 00092 #endif 00093 00094 /* set up raw IP socket to avoid "protocol 130" ICMP msgs */ 00095 if ((rawiprecvsock = socket(AF_INET, SOCK_RAW, IPPROTO_SNAP)) < 0) { 00096 perror("rawiprecvsock: socket()"); 00097 exit(EXIT_FAILURE); 00098 } 00099 ra_space[IPOPT_OPTVAL] = IPOPT_RA; 00100 ra_space[IPOPT_OLEN] = 4; 00101 ra_space[2] = ra_space[3] = 0; 00102 if (setsockopt(rawiprecvsock, IPPROTO_IP, IP_OPTIONS, ra_space, 00103 sizeof(ra_space)) < 0) { 00104 perror("rawiprecvsock: setsockopt()"); 00105 exit(EXIT_FAILURE); 00106 } 00107 memset(&bindaddr, 0, sizeof(bindaddr)); 00108 bindaddr.sin_family = AF_INET; 00109 bindaddr.sin_addr.s_addr = htonl(INADDR_ANY); 00110 if (bind(rawiprecvsock, (struct sockaddr *)&bindaddr, 00111 sizeof(bindaddr)) < 0) { 00112 perror("rawiprecvsock: bind()"); 00113 exit(EXIT_FAILURE); 00114 } 00115 00116 /* set up ethernet socket */ 00117 if ((ethsock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { 00118 perror("ethsock socket()"); 00119 exit(EXIT_FAILURE); 00120 } 00121 #if 0 00122 memset(&bindhwaddr, 0, sizeof(bindhwaddr)); 00123 bindhwaddr.sll_family = PF_PACKET; 00124 bindhwaddr.sll_protocol = ETH_P_IP; 00125 bindhwaddr.sll_ifindex = 2; /* all ifs */ 00126 bindhwaddr.sll_hatype = ARPHRD_ETHER; 00127 bindhwaddr.sll_halen = 6; 00128 if (bind(ethsock, (struct sockaddr *)&bindhwaddr, 00129 sizeof(bindhwaddr)) < 0) { 00130 perror("bind"); 00131 exit(EXIT_FAILURE); 00132 } 00133 00134 /* set up loopback socket */ 00135 if ((losock = socket(PF_PACKET, SOCK_RAW, ETH_P_ALL)) < 0) { 00136 perror("losock socket()"); 00137 exit(EXIT_FAILURE); 00138 } 00139 memset(&bindhwaddr, 0, sizeof(bindhwaddr)); 00140 bindhwaddr.sll_family = PF_PACKET; 00141 bindhwaddr.sll_protocol = ETH_P_IP; 00142 bindhwaddr.sll_ifindex = 1; /* all ifs */ 00143 bindhwaddr.sll_hatype = ARPHRD_LOOPBACK; 00144 bindhwaddr.sll_halen = 6; 00145 if (bind(losock, (struct sockaddr *)&bindhwaddr, 00146 sizeof(bindhwaddr)) < 0) { 00147 perror("bind"); 00148 exit(EXIT_FAILURE); 00149 } 00150 #endif 00151 00152 if (losock > ethsock) 00153 maxfd = losock + 1; 00154 else 00155 maxfd = ethsock + 1; 00156 00157 /* set up the datagram socket */ 00158 /* if ((udpsock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 00159 perror("udpsock socket()"); 00160 exit(EXIT_FAILURE); 00161 } 00162 00163 bzero((char *) &udpaddr, sizeof(udpaddr)); 00164 udpaddr.sin_family = AF_INET; 00165 udpaddr.sin_addr.s_addr = htonl(INADDR_ANY); 00166 udpaddr.sin_port = htons(UDPPORT); 00167 00168 if (bind(udpsock, (struct sockaddr *) &udpaddr, sizeof(udpaddr)) < 0){ 00169 perror("udpsock bind()"); 00170 exit(EXIT_FAILURE); 00171 } 00172 00173 if (udpsock >= maxfd) 00174 maxfd = udpsock + 1; 00175 */ 00176 d_printf(5, "SNAP (wjdb tree) version %s : ready\n",VERSION); 00177 00178 return 0; 00179 } 00180 00181 int add_snap_handler(fd_set* activeset){ 00182 FD_SET(ethsock,activeset); 00183 FD_SET(rawiprecvsock,activeset); 00184 00185 return ethsock > rawiprecvsock ? ethsock : rawiprecvsock; 00186 } 00187 00188 int isset_snap_handler(fd_set* activeset){ 00189 00190 return /*FD_ISSET(ethsock, activeset) && */FD_ISSET(rawiprecvsock, activeset); 00191 00192 } 00193 00194 void clear_snap_handler(fd_set* activeset){ 00195 /* if (FD_ISSET(ethsock, activeset)) 00196 FD_CLR (ethsock, activeset); 00197 */ 00198 if (FD_ISSET(rawiprecvsock, activeset)) 00199 FD_CLR (rawiprecvsock, activeset); 00200 } 00201 00202 int handle_snap_request(){ 00203 /* if (!snap_recv_pkt (ethsock, &p)){ 00204 d_printf(50,"handle_snap_request : received SNAP message over ETHERNET ... parsing\n"); 00205 snap_interp_packet(p); 00206 d_printf(50,"handle_snap_request : ... finished parsing\n"); 00207 return 0; 00208 } 00209 00210 */ if (!snap_recv_pkt (rawiprecvsock, &p)){ 00211 d_printf_timed(10,"handle_snap_request : received SNAP message over RAWIP ... parsing\n"); 00212 snap_interp_packet(p); 00213 d_printf_timed(10,"handle_snap_request : ... finished parsing\n"); 00214 return 0; 00215 } 00216 00217 /* d_printf(50,"handle_snap_request : received non SNAP message... discarding\n"); 00218 */ return 1; 00219 00220 } 00221 00222 int snap_receive(){ 00223 00224 /* initialize the select() vars */ 00225 d_printf(50,"snap_receive : waiting for message\n"); 00226 FD_ZERO(&rfds); 00227 /* FD_SET(ethsock, &rfds);*/ 00228 /* FD_SET(udpsock, &rfds);*/ 00229 FD_SET(rawiprecvsock, &rfds); 00230 00231 /* wait for messages */ 00232 if (select(maxfd, &rfds, NULL, NULL, NULL) < 0) { 00233 perror("select"); 00234 exit(EXIT_FAILURE); 00235 } 00236 00237 /* handle messages received through ethernet */ 00238 /* if (FD_ISSET(ethsock,&rfds)) { 00239 if (snap_recv_pkt(ethsock,&p) == 0) { 00240 d_printf(50,"snap_receive : received SNAP message over ethernet ... parsing\n"); 00241 (void)snap_interp_packet(p); 00242 d_printf(50,"snap_receive : ... finished parsing\n"); 00243 } 00244 d_printf(50,"snap_receive : received non SNAP message over ethernet ... discarding\n"); 00245 } 00246 */ 00247 /* handle messages received through UDP */ 00248 /* if (FD_ISSET(udpsock,&rfds)) { 00249 if (snap_recv_pkt(udpsock,&p, 0) == 0) { 00250 d_printf(50,"snap_receive : received SNAP message over UDP ... parsing\n"); 00251 (void)snap_interp_packet(p); 00252 d_printf(50,"snap_receive : ... finished parsing\n"); 00253 } 00254 fprintf(stderr,"snap_receive : received non SNAP message over UDP ... discarding\n"); 00255 } 00256 */ 00257 00258 /* handle messages received through RAWIPSOCK (where this is the destination */ 00259 if (FD_ISSET(rawiprecvsock,&rfds)) { 00260 if (snap_recv_pkt(rawiprecvsock,&p) == 0) { 00261 d_printf_timed(5,"snap_receive : received SNAP message over RAW IP ... parsing\n"); 00262 (void)snap_interp_packet(p); 00263 d_printf_timed(5,"snap_receive : ... finished parsing\n"); 00264 } 00265 else 00266 fprintf(stderr,"snap_receive : received non SNAP message over RAW IP ... discarding\n"); 00267 } 00268 00269 00270 return 0; 00271 } 00272 void usage(char *myname) { 00273 fprintf(stderr,"usage: %s [-?v] [-l localaddr]\n",myname); 00274 fprintf(stderr," -? : this help\n"); 00275 fprintf(stderr," -v : print version and exit\n"); 00276 fprintf(stderr," -l : set return val for HERE\n"); 00277 fprintf(stderr," -d : set debug level (-1 .. 100)\n"); 00278 fflush(stderr); 00279 } 00280 00281 void parse_cmdline_snap(int argc, char **argv) { 00282 /* 00283 char *optstring = "?vsl:"; 00284 struct option longopts[] = { 00285 { "help", 0, NULL, '?' }, 00286 { "version", 0, NULL, 'v' }, 00287 { "localaddr", 1, NULL, 'l' }, 00288 { "shared" , 0, NULL, 's' }, 00289 { NULL, 0, NULL, 0 } 00290 }; 00291 */ int args_in = 0; 00292 int args_expected = 0; 00293 int ret; 00294 char c = 0; 00295 00296 /* establish defaults */ 00297 /* No defaults yet. */ 00298 00299 for (ret=0; ret < argc; ret++){ 00300 d_printf(90," argument %d: %s\n",ret, argv[ret]); 00301 if (strlen(argv[ret]) > 1) 00302 c = argv[ret][1]; 00303 if (strlen(argv[ret]) > 1 && argv[ret][0] == '-') 00304 switch(c) { 00305 case '?': 00306 usage(basename(argv[0])); 00307 exit(EXIT_SUCCESS); 00308 break; 00309 case 'v': 00310 printf("%s version %s\n",PACKAGE,VERSION); 00311 printf("%s: SNAP virtual machine daemon\n", 00312 basename(argv[0])); 00313 printf("Copyright (C) 2002,2001 by Jonathan T. Moore and Michael Hicks\n"); 00314 printf(" wjdb hack (c) Willem J. de Bruijn, 2002\n"); 00315 exit(EXIT_SUCCESS); 00316 break; 00317 case 'l': 00318 { 00319 unsigned int c1,c2,c3,c4; 00320 unsigned int haddr; 00321 if (sscanf(optarg,"%d.%d.%d.%d",&c1,&c2,&c3,&c4) != 4) { 00322 fprintf(stderr,"%s: bad local address %s\n", 00323 basename(argv[0]),optarg); 00324 fflush(stderr); 00325 usage(basename(argv[0])); 00326 exit(EXIT_FAILURE); 00327 } 00328 haddr = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; 00329 gc.herehint.sin_addr.s_addr = htonl(haddr); 00330 d_printf(5,"%s:%d: local address set to %d.%d.%d.%d\n", 00331 __FILE__,__LINE__, 00332 NIPQUAD(gc.herehint.sin_addr.s_addr)); 00333 } 00334 break; 00335 case 'd': 00336 { 00337 int newdebuglvl = atoi(argv[ret+1]); 00338 if (newdebuglvl >= -1 && newdebuglvl <= 100) 00339 set_debug_level_int(newdebuglvl); 00340 d_printf(50,"%s:%d: debug level set to %d\n",__FILE__,__LINE__,sysctl_snap_debug_level); 00341 } 00342 break; 00343 default: 00344 printf("%s: unknown option '-%c'\n",basename(argv[0]),c); 00345 usage(basename(argv[0])); 00346 exit(EXIT_FAILURE); 00347 } 00348 } 00349 /* 00350 while(optind < argc) { 00351 switch(args_in) { 00352 default: 00353 printf("%s: extra argument(s)\n",basename(argv[0])); 00354 usage(basename(argv[0])); 00355 exit(EXIT_FAILURE); 00356 } 00357 args_in++; 00358 optind++; 00359 }*/ 00360 if (args_in < args_expected) { 00361 printf("%s: missing argument(s)\n",basename(argv[0])); 00362 usage(basename(argv[0])); 00363 exit(EXIT_FAILURE); 00364 } 00365 00366 assert(args_in == args_expected); 00367 } 00368 00369 /* call the interpreter directly */ 00370 int init_snap(int argc, char** argv){ 00371 struct cmdline_args cargs; 00372 00373 cargs.argc = argc; 00374 cargs.argv = argv; 00375 00376 return snap(&cargs); 00377 } |