📄 libsnap.c
字号:
/* snap2snmp connection library *//* (c) Willem de Bruijn, 2002 *//* snaplibrary sourcefile *//* defines are stolen from /usr/include/linux/socket.h */#define AF_PACKET 17 /* Packet family */#define PF_PACKET AF_PACKET#include </usr/include/stdarg.h>#include </usr/include/pthread.h>#define _GNU_SOURCE#include <assert.h>#include <features.h>#include <getopt.h>#include <sys/socket.h>#include <net/if_arp.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <libgen.h>#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1#include <netpacket/packet.h>#include <net/ethernet.h> /* the L2 protocols */#else#include <asm/types.h>#include <linux/if_packet.h>#include <linux/if_ether.h> /* The L2 protocols */#endif#include "d_printf.h"#include "snapnet.h"#include "packet.h"#include "snap.h"#include "version.h"#include "interp.h"#include "snap_kern_iface.h"#include "snap_svc_handler.h"#define NIPQUAD(addr) \ ((unsigned char *)&(addr))[0], \ ((unsigned char *)&(addr))[1], \ ((unsigned char *)&(addr))[2], \ ((unsigned char *)&(addr))[3]#ifndef UDPPORT#define UDPPORT 7777#endif/* declaration of function. Definition can be found below.*/int snap_receive();struct glob_conf { struct sockaddr_in herehint;} gc;struct cmdline_args { int argc; char** argv;};void usage(char *myname);void parse_cmdline_snap(int argc, char *argv[]); int ethsock = -1; int losock = -1;/* int udpsock = -1;*/ int rawiprecvsock = -1; int maxfd; packet_t *p;/* struct sockaddr_ll bindhwaddr; */ fd_set rfds; unsigned char ra_space[4]; struct sockaddr_in bindaddr; struct sockaddr_in udpaddr;int snap(struct cmdline_args *cargs) {#ifndef NDEBUG set_debug_level();#endif memset(&gc, 0, sizeof(gc)); if (cargs->argc > 0) /* we can call this function without arguments */ parse_cmdline_snap((*cargs).argc,(*cargs).argv); init_kern_iface(&gc.herehint);#ifdef CONFIG_IP_SNAP_SVCS snap_svc_handler_init();#endif /* set up raw IP socket to avoid "protocol 130" ICMP msgs */ if ((rawiprecvsock = socket(AF_INET, SOCK_RAW, IPPROTO_SNAP)) < 0) { perror("rawiprecvsock: socket()"); exit(EXIT_FAILURE); } ra_space[IPOPT_OPTVAL] = IPOPT_RA; ra_space[IPOPT_OLEN] = 4; ra_space[2] = ra_space[3] = 0; if (setsockopt(rawiprecvsock, IPPROTO_IP, IP_OPTIONS, ra_space, sizeof(ra_space)) < 0) { perror("rawiprecvsock: setsockopt()"); exit(EXIT_FAILURE); } memset(&bindaddr, 0, sizeof(bindaddr)); bindaddr.sin_family = AF_INET; bindaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(rawiprecvsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { perror("rawiprecvsock: bind()"); exit(EXIT_FAILURE); } /* set up ethernet socket */ if ((ethsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { //htons(ETH_P_IP))) < 0) { perror("ethsock socket()"); exit(EXIT_FAILURE); }#if 0 memset(&bindhwaddr, 0, sizeof(bindhwaddr)); bindhwaddr.sll_family = PF_PACKET; bindhwaddr.sll_protocol = ETH_P_IP; bindhwaddr.sll_ifindex = 2; /* all ifs */ bindhwaddr.sll_hatype = ARPHRD_ETHER; bindhwaddr.sll_halen = 6; if (bind(ethsock, (struct sockaddr *)&bindhwaddr, sizeof(bindhwaddr)) < 0) { perror("bind"); exit(EXIT_FAILURE); } /* set up loopback socket */ if ((losock = socket(PF_PACKET, SOCK_RAW, ETH_P_ALL)) < 0) { perror("losock socket()"); exit(EXIT_FAILURE); } memset(&bindhwaddr, 0, sizeof(bindhwaddr)); bindhwaddr.sll_family = PF_PACKET; bindhwaddr.sll_protocol = ETH_P_IP; bindhwaddr.sll_ifindex = 1; /* all ifs */ bindhwaddr.sll_hatype = ARPHRD_LOOPBACK; bindhwaddr.sll_halen = 6; if (bind(losock, (struct sockaddr *)&bindhwaddr, sizeof(bindhwaddr)) < 0) { perror("bind"); exit(EXIT_FAILURE); }#endif if (losock > ethsock) maxfd = losock + 1; else maxfd = ethsock + 1; /* set up the datagram socket *//* if ((udpsock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("udpsock socket()"); exit(EXIT_FAILURE); } bzero((char *) &udpaddr, sizeof(udpaddr)); udpaddr.sin_family = AF_INET; udpaddr.sin_addr.s_addr = htonl(INADDR_ANY); udpaddr.sin_port = htons(UDPPORT); if (bind(udpsock, (struct sockaddr *) &udpaddr, sizeof(udpaddr)) < 0){ perror("udpsock bind()"); exit(EXIT_FAILURE); } if (udpsock >= maxfd) maxfd = udpsock + 1;*/ d_printf(5, "SNAP (wjdb tree) version %s : ready\n",VERSION); return 0;}int add_snap_handler(fd_set* activeset){ FD_SET(ethsock,activeset); FD_SET(rawiprecvsock,activeset); return ethsock > rawiprecvsock ? ethsock : rawiprecvsock;}int isset_snap_handler(fd_set* activeset){ return /*FD_ISSET(ethsock, activeset) && */FD_ISSET(rawiprecvsock, activeset);}void clear_snap_handler(fd_set* activeset){/* if (FD_ISSET(ethsock, activeset)) FD_CLR (ethsock, activeset);*/ if (FD_ISSET(rawiprecvsock, activeset)) FD_CLR (rawiprecvsock, activeset);}int handle_snap_request(){/* if (!snap_recv_pkt (ethsock, &p)){ d_printf(50,"handle_snap_request : received SNAP message over ETHERNET ... parsing\n"); snap_interp_packet(p); d_printf(50,"handle_snap_request : ... finished parsing\n"); return 0; }*/ if (!snap_recv_pkt (rawiprecvsock, &p)){ d_printf_timed(10,"handle_snap_request : received SNAP message over RAWIP ... parsing\n"); snap_interp_packet(p); d_printf_timed(10,"handle_snap_request : ... finished parsing\n"); return 0; }/* d_printf(50,"handle_snap_request : received non SNAP message... discarding\n");*/ return 1;}int snap_receive(){ /* initialize the select() vars */ d_printf(50,"snap_receive : waiting for message\n"); FD_ZERO(&rfds);/* FD_SET(ethsock, &rfds);*//* FD_SET(udpsock, &rfds);*/ FD_SET(rawiprecvsock, &rfds); /* wait for messages */ if (select(maxfd, &rfds, NULL, NULL, NULL) < 0) { perror("select"); exit(EXIT_FAILURE); } /* handle messages received through ethernet *//* if (FD_ISSET(ethsock,&rfds)) { if (snap_recv_pkt(ethsock,&p) == 0) { d_printf(50,"snap_receive : received SNAP message over ethernet ... parsing\n"); (void)snap_interp_packet(p); d_printf(50,"snap_receive : ... finished parsing\n"); } d_printf(50,"snap_receive : received non SNAP message over ethernet ... discarding\n"); }*/ /* handle messages received through UDP *//* if (FD_ISSET(udpsock,&rfds)) { if (snap_recv_pkt(udpsock,&p, 0) == 0) { d_printf(50,"snap_receive : received SNAP message over UDP ... parsing\n"); (void)snap_interp_packet(p); d_printf(50,"snap_receive : ... finished parsing\n"); } fprintf(stderr,"snap_receive : received non SNAP message over UDP ... discarding\n"); }*/ /* handle messages received through RAWIPSOCK (where this is the destination */ if (FD_ISSET(rawiprecvsock,&rfds)) { if (snap_recv_pkt(rawiprecvsock,&p) == 0) { d_printf_timed(5,"snap_receive : received SNAP message over RAW IP ... parsing\n"); (void)snap_interp_packet(p); d_printf_timed(5,"snap_receive : ... finished parsing\n"); } else fprintf(stderr,"snap_receive : received non SNAP message over RAW IP ... discarding\n"); } return 0;}void usage(char *myname) { fprintf(stderr,"usage: %s [-?v] [-l localaddr]\n",myname); fprintf(stderr," -? : this help\n"); fprintf(stderr," -v : print version and exit\n"); fprintf(stderr," -l : set return val for HERE\n"); fprintf(stderr," -d : set debug level (-1 .. 100)\n"); fflush(stderr);}void parse_cmdline_snap(int argc, char **argv) {/* char *optstring = "?vsl:"; struct option longopts[] = { { "help", 0, NULL, '?' }, { "version", 0, NULL, 'v' }, { "localaddr", 1, NULL, 'l' }, { "shared" , 0, NULL, 's' }, { NULL, 0, NULL, 0 } };*/ int args_in = 0; int args_expected = 0; int ret; char c = 0; /* establish defaults */ /* No defaults yet. */ for (ret=0; ret < argc; ret++){ d_printf(90," argument %d: %s\n",ret, argv[ret]); if (strlen(argv[ret]) > 1) c = argv[ret][1]; if (strlen(argv[ret]) > 1 && argv[ret][0] == '-') switch(c) { case '?': usage(basename(argv[0])); exit(EXIT_SUCCESS); break; case 'v': printf("%s version %s\n",PACKAGE,VERSION); printf("%s: SNAP virtual machine daemon\n", basename(argv[0])); printf("Copyright (C) 2002,2001 by Jonathan T. Moore and Michael Hicks\n"); printf(" wjdb hack (c) Willem J. de Bruijn, 2002\n"); exit(EXIT_SUCCESS); break; case 'l': { unsigned int c1,c2,c3,c4; unsigned int haddr; if (sscanf(optarg,"%d.%d.%d.%d",&c1,&c2,&c3,&c4) != 4) { fprintf(stderr,"%s: bad local address %s\n", basename(argv[0]),optarg); fflush(stderr); usage(basename(argv[0])); exit(EXIT_FAILURE); } haddr = (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; gc.herehint.sin_addr.s_addr = htonl(haddr); d_printf(5,"%s:%d: local address set to %d.%d.%d.%d\n", __FILE__,__LINE__, NIPQUAD(gc.herehint.sin_addr.s_addr)); } break; case 'd': { int newdebuglvl = atoi(argv[ret+1]); if (newdebuglvl >= -1 && newdebuglvl <= 100) set_debug_level_int(newdebuglvl); d_printf(50,"%s:%d: debug level set to %d\n",__FILE__,__LINE__,sysctl_snap_debug_level); } break; default: printf("%s: unknown option '-%c'\n",basename(argv[0]),c); usage(basename(argv[0])); exit(EXIT_FAILURE); } }/* while(optind < argc) { switch(args_in) { default: printf("%s: extra argument(s)\n",basename(argv[0])); usage(basename(argv[0])); exit(EXIT_FAILURE); } args_in++; optind++; }*/ if (args_in < args_expected) { printf("%s: missing argument(s)\n",basename(argv[0])); usage(basename(argv[0])); exit(EXIT_FAILURE); } assert(args_in == args_expected);}/* call the interpreter directly */int init_snap(int argc, char** argv){ struct cmdline_args cargs; cargs.argc = argc; cargs.argv = argv; return snap(&cargs);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -