[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

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap-1.1-wjdb/lib/libsnap.c

Go 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 }