From c9cbeced5b3f2bdd7407e29c0811e65954132540 Mon Sep 17 00:00:00 2001 From: Root THC Date: Tue, 24 Feb 2026 12:42:47 +0000 Subject: initial --- other/b-scan/tmp/modules/Makefile | 22 + other/b-scan/tmp/modules/mod_banner.c | 365 ++++++++++++++ other/b-scan/tmp/modules/mod_bind.c | 302 ++++++++++++ other/b-scan/tmp/modules/mod_httpd.c | 188 +++++++ other/b-scan/tmp/modules/mod_ping.c | 205 ++++++++ other/b-scan/tmp/modules/mod_snmp.c | 899 ++++++++++++++++++++++++++++++++++ 6 files changed, 1981 insertions(+) create mode 100644 other/b-scan/tmp/modules/Makefile create mode 100644 other/b-scan/tmp/modules/mod_banner.c create mode 100644 other/b-scan/tmp/modules/mod_bind.c create mode 100644 other/b-scan/tmp/modules/mod_httpd.c create mode 100644 other/b-scan/tmp/modules/mod_ping.c create mode 100644 other/b-scan/tmp/modules/mod_snmp.c (limited to 'other/b-scan/tmp/modules') diff --git a/other/b-scan/tmp/modules/Makefile b/other/b-scan/tmp/modules/Makefile new file mode 100644 index 0000000..ccac359 --- /dev/null +++ b/other/b-scan/tmp/modules/Makefile @@ -0,0 +1,22 @@ +CC=gcc +COPT=-Wall -ggdb -shared -fPIC -I../include +DEFS=`libnet-config --defines` -DUSE_LIBNET #-DDEBUG +LIBS= +TARGETS=mod_snmp mod_banner mod_httpd mod_ping mod_bind + +# HPUX 10.20 +# DEFS=`libnet-config --defines` -DUSE_LIBNET -DHP10 #-DDEBUG + +all: + for trgt in $(TARGETS); do \ + $(CC) $(COPT) $(DEFS) -o $$trgt.so $$trgt.c; \ + done + + +clean: + for trgt in $(TARGETS); do \ + rm -f $$trgt.so; \ + done + rm -f core *~ + + diff --git a/other/b-scan/tmp/modules/mod_banner.c b/other/b-scan/tmp/modules/mod_banner.c new file mode 100644 index 0000000..6f02a39 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_banner.c @@ -0,0 +1,365 @@ +/* + * mod_example.c + * Example module for bscan. + */ + +#include +#include +#include +#include +#include +#include + + +#ifndef MOD_NAME +#define MOD_NAME "mod_banner" +#endif + +#define SCN_NVT 0x00000001 +#define SCN_HALFOPEN 0x00000002 +#define SCN_XMAS 0x00000004 +#define SCN_FIN 0x00000008 +#define SCN_NULL 0x00000010 +#define SCN_PUSH 0x00000020 +#define SCN_LETOPEN 0x00000040 +#define SCN_NOSCAN 0x00000080 +#define SCN_NOICMP 0x00000100 + + +static int isinit=0; +/* + * some variables from the binary-process + */ +extern int dlt_len; +extern u_char *align_buf; +extern unsigned short ip_options; +extern struct ip *ip; +extern struct Ether_header *eth; +extern u_int plen, pcaplen; + + +struct _mopt +{ + u_int scanflags; + uint8_t th_flags; +} static mopt; + + +/* + * static functions prototypes + */ +static int mdo_opt(int, char **, struct _opt *); +static void init_vars(struct _opt *); +static int process_rcv(struct _opt *); +static void handle_icmp (); + + + +/* + * print out usage informations + */ +void +musage() +{ + printf ("\n"MOD_NAME"\n"); + printf (" -o , default 20\n"); + printf (" -p , default 21\n"); + printf (" -a grab all data and let the connecten established\n"); + printf (" -n NVT terminal support (use this for telnetd-scans)\n"); + printf (" -I dont report ICMP-errors\n"); + printf (" -q quite, dont send out any initial packages [first-pkg]\n"); + printf (" "MOD_NAME" only reports ICMP errors and doesn't start\n"); + printf (" scanning. It will still simulate the tcp-stack.\n"); + printf + (" -sS,-sF,-sX,-sN,-sP TCP SYN stealth, Fin, Xmas, Null, !Push scan\n"); + +} + + +/* + * return 0 on success, != 0 on failure + */ +int +init(char **modname, int argc, char *argv[], struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE INIT\n"); +#endif + if (isinit) + return(-1); + + *modname = MOD_NAME; + isinit = 1; + init_vars(opt); + + if (mdo_opt(argc, argv, opt) != 0) + return(-1); + + return(0); +} + +/* + * fini-routine. called on cleanup + */ +int +fini() +{ +#ifdef DEBUG + printf("MODULE FINI\n"); +#endif + return(0); +} + + +/* + * + */ +int +callmdl(int entry, struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE CALLMDL\n"); +#endif + if (entry == MOD_FIRSTPKG) + { + if (mopt.scanflags & SCN_NOSCAN) + return(RMOD_SKIP); + + add_tcphdr(opt->packet + ETH_SIZE + IP_SIZE, &opt->nt, mopt.th_flags, 0, NULL, NULL); + add_iphdr (opt->packet + ETH_SIZE, IPPROTO_TCP, &opt->nt, TCP_SIZE); + opt->pkg_len = TCP_SIZE + IP_SIZE; + return(RMOD_OK); + } + + if (entry == MOD_RCV) + process_rcv(opt); + + return(RMOD_OK); +} + + +/* + *********************************************************** + * Our OWN/static functions for THIS module * + *********************************************************** + */ + +/* + * initialize all local variables. + * We use some 'unused' variables of the masterprogramm + */ +static void +init_vars(struct _opt *opt) +{ + opt->nt.sport = htons(20); /* not used by master programm */ + opt->nt.dport = htons(21); /* not used by master programm */ + + mopt.scanflags = 0; + mopt.th_flags = TH_SYN; +} + + +/* + * LOCAL/STATIC function, only available in the module + * return 0 on success, != 0 on failure + */ +static int +mdo_opt(int argc, char *argv[], struct _opt *opt) +{ + extern char *optarg; + /*extern int optind, opterr, optopt;*/ + int c; + + while ((c = getopt (argc, argv, "Iqans:p:o:")) != -1) + { + switch (c) + { + case 'I': + mopt.scanflags |= SCN_NOICMP; + break; + case 'q': + mopt.scanflags |= SCN_NOSCAN; + break; + case 'p': + opt->nt.dport = htons(strtoul (optarg, (char **) NULL, 10)); + break; + case 'o': + opt->nt.sport = htons(strtoul (optarg, (char **) NULL, 10)); + break; + case 'a': + mopt.scanflags |= SCN_LETOPEN; + break; + case 'n': + mopt.scanflags |= SCN_NVT; /* NVT parsing */ + break; + case 's': + switch (optarg[0]) + { + case 'S': + mopt.scanflags |= SCN_HALFOPEN; + mopt.th_flags = TH_SYN; + break; + case 'X': + mopt.scanflags |= SCN_XMAS; + mopt.th_flags = (TH_FIN | TH_PUSH | TH_URG); + break; + case 'F': + mopt.scanflags |= SCN_FIN; + mopt.th_flags = TH_FIN; + break; + case 'N': + mopt.scanflags |= SCN_NULL; + mopt.th_flags = 0; + break; + case 'P': + mopt.scanflags |= SCN_PUSH; + break; + default: + fprintf(stderr, "unrecognized option -s%c\n", optarg[0]); + return(-1); + } + break; + case ':': + fprintf(stderr, "missing parameter\n"); + return(-1); + default: + return(-1); + } + } + + if ((mopt.scanflags & SCN_NVT) && !(mopt.scanflags & SCN_LETOPEN)) + fprintf(stderr, "WARNING: NVT used without -a. This is probably not what you want!\n"); + + return(0); +} + + +/* + * vrfy the icmp packet and print out 'human readable'-icmp code + * dest-unreachable packages only! + */ +static void +handle_icmp (int offset) +{ + struct icmp *icmp = (struct icmp *) (align_buf + offset); + struct ip *icmpip; + + if (plen < offset + sizeof (*icmp) + dlt_len) + return; + + icmpip = (struct ip *) (align_buf + offset + ICMP_HDRSIZE); + + printf ("%s (%d/%d) %s", int_ntoa (icmpip->ip_dst.s_addr), + icmp->icmp_type, icmp->icmp_code, + icmp_str (icmp->icmp_type, icmp->icmp_code)); + printf ("(from %s)\n", int_ntoa (ip->ip_src.s_addr)); +} + + +/* + * process incoming packets + * IP-packet is verified and variables valid (ip_options, *ip) + */ +static int +process_rcv(struct _opt *opt) +{ + struct tcphdr *tcp; + unsigned short tcp_options = 0; + u_char *data = NULL; + u_char *ans = NULL; /* tcpdata answer */ + u_char prefix[32]; + int data_len = 0; + uint ans_len = 0; + uint res_len = 0; + uint tcphdr_len = 0; + uint iphdr_len = 0; + + + if (ip->ip_p == IPPROTO_ICMP) + { + opt->snarf.icmp_c++; /* for statistics */ + if (!(mopt.scanflags & SCN_NOICMP)) + handle_icmp (sizeof (*ip) + ip_options); + + return(0); + } + + if (ip->ip_p != IPPROTO_TCP) + return(0); + + iphdr_len = sizeof(*ip) + ip_options; + tcp = (struct tcphdr *) (align_buf + iphdr_len); + + if (vrfy_tcp(tcp, plen - dlt_len - iphdr_len , &tcp_options) != 0) + return(0); + + if (tcp->th_flags & TH_RST) + { + opt->snarf.refused_c++; + printf ("%s:%d refused\n", int_ntoa (ip->ip_src.s_addr), + ntohs (tcp->th_sport)); + } + else if (tcp->th_flags & TH_FIN) + { + opt->snarf.close_c++; + answer_tcp (opt->sox, ip, tcp, TH_FIN | TH_ACK, NULL, 0); + printf ("%s:%d connection closed by foreig host\n", + int_ntoa (ip->ip_src.s_addr), ntohs (tcp->th_sport)); + } + else if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) + { + + if (mopt.scanflags & SCN_HALFOPEN) + { + if (!(mopt.scanflags & SCN_LETOPEN)) + answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_RST, NULL, 0); + return(0); + } + else + answer_tcp (opt->sox, ip, tcp, TH_ACK, NULL, 0); + + opt->snarf.open_c++; + printf ("%s:%d open\n", int_ntoa (ip->ip_src.s_addr), + ntohs (tcp->th_sport)); + } + + /* banner scanner output */ + tcphdr_len = sizeof(*tcp) + tcp_options; + if (plen - dlt_len > ntohs(ip->ip_len)) + data_len = ntohs(ip->ip_len) - iphdr_len - tcphdr_len; + else + data_len = plen - dlt_len - iphdr_len - tcphdr_len; + + if (data_len <= 0) + return(0); + + if ( (data = alloca(data_len + 1)) == NULL) + return(-1); + + memcpy(data, align_buf + iphdr_len + tcphdr_len, data_len); + + if (mopt.scanflags & SCN_NVT) + { + if ((ans = alloca(data_len)) == NULL) + return(-1); + + decode_nvt(data, data_len, ans, &ans_len, data, &res_len); + data_len = res_len; /* we wrote everything into data */ + } + + snprintf(prefix, sizeof(prefix) - 1, "%s:%d ", int_ntoa(ip->ip_src), + ntohs (tcp->th_sport)); + save_write(stdout, prefix, data, data_len); + + if (tcp->th_flags & TH_RST) /* data_len != 0 */ + return(0); /* evil peer resetted our connection */ + + /* close after first data package or ack last RST if data_len >0 */ + if (!(mopt.scanflags & SCN_LETOPEN) || (tcp->th_flags & TH_RST)) + answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_RST, ans, ans_len); + else + answer_tcp (opt->sox, ip, tcp, TH_ACK, ans, ans_len); + + + return(0); +} diff --git a/other/b-scan/tmp/modules/mod_bind.c b/other/b-scan/tmp/modules/mod_bind.c new file mode 100644 index 0000000..2a09f49 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_bind.c @@ -0,0 +1,302 @@ +/* + * ping-module for bscan. + * IDEA: add record-route and source-route feature + * and -p pattern [where can we save our time-struct then ? + */ + +#include +#include +#include +#include + + +#ifndef MOD_NAME +#define MOD_NAME "mod_bind" +#endif + +/* + * this is our query. This is a DNS-formated string + * <0> + */ +#define DNSTXTREQ "\007version\004bind" + +static int process_rcv(struct _opt *); +static void add_dnshdr(unsigned char *); +static void add_dnstxthdr(unsigned char *, char *, u_int *); + +static int isinit=0; +/* + * some variables from the binary-process + */ +extern int dlt_len; +extern u_char *align_buf; +extern unsigned short ip_options; +extern struct ip *ip; +extern struct Ether_header *eth; +extern u_int plen, pcaplen; +extern struct timeval *pts; + + +struct _dnshdr +{ + u_short id; /* DNS packet ID */ + u_short flags; /* DNS flags */ + u_short num_q; /* Number of questions */ + u_short num_answ_rr; /* Number of answer resource records */ + u_short num_auth_rr; /* Number of authority resource records */ + u_short num_addi_rr; /* Number of additional resource records */ +}; + +struct _dnsanswr +{ + u_short type; + u_short class; + u_short ttl1; + u_short ttl2; + u_short len; +}; + + + +/* + * static functions prototypes + */ +static int mdo_opt(int, char **, struct _opt *); +static void init_vars(struct _opt *); + +/* + * print out usage informations + */ +void +musage() +{ + printf ("\n"MOD_NAME"\n"); + printf ("verson.bind chaos txt module\n"); + printf (" -p , destination port, default 53\n"); + printf (" -o , source port, default 53\n"); +} + + +/* + * return 0 on success, != 0 on failure + */ +int +init(char **modname, int argc, char *argv[], struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE INIT\n"); +#endif + if (isinit) + return(-1); + + *modname = MOD_NAME; + isinit = 1; + init_vars(opt); + + if (mdo_opt(argc, argv, opt) != 0) + return(-1); + + return(0); +} + +/* + * fini-routine. called on cleanup + */ +int +fini() +{ +#ifdef DEBUG + printf("MODULE FINI\n"); +#endif + return(0); +} + + +/* + * Module entry point [entry] + * RMOD_OK: everything allright. send the packet out [if first] + * or do nothing [MOD_RCV]. + * RMOD_SKIP: proceed with next IP without sending out the packet. + */ +int +callmdl(int entry, struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE CALLMDL\n"); +#endif + if (entry == MOD_FIRSTPKG) + { + add_dnstxthdr (opt->packet + ETH_SIZE + IP_SIZE + UDP_SIZE + sizeof(struct _dnshdr), DNSTXTREQ, &opt->pkg_len); + add_dnshdr (opt->packet + ETH_SIZE + IP_SIZE + UDP_SIZE); + add_udphdr (opt->packet + ETH_SIZE + IP_SIZE, &opt->nt, opt->pkg_len + sizeof(struct _dnshdr)); + add_iphdr (opt->packet + ETH_SIZE, IPPROTO_UDP, &opt->nt, opt->pkg_len + UDP_SIZE + sizeof(struct _dnshdr)); + opt->pkg_len += IP_SIZE + UDP_SIZE + sizeof(struct _dnshdr); + return(RMOD_OK); + } + + if (entry == MOD_RCV) + process_rcv(opt); + + return(RMOD_OK); +} + + +/* + *********************************************************** + * Our OWN/static functions for THIS module * + *********************************************************** + */ + +/* + * initialize all local variables. + * We use some 'unused' variables of the masterprogramm + */ +static void +init_vars(struct _opt *opt) +{ + opt->nt.sport = htons(53); + opt->nt.dport = htons(53); +} + + +/* + * LOCAL/STATIC function, only available in the module + * return 0 on success, != 0 on failure + */ +static int +mdo_opt(int argc, char *argv[], struct _opt *opt) +{ + extern char *optarg; + /*extern int optind, opterr, optopt;*/ + int c; + + while ((c = getopt (argc, argv, "p:o:")) != -1) + { + switch (c) + { + case 'p': + opt->nt.dport = htons(atoi(optarg)); + break; + case 'o': + opt->nt.sport = htons(atoi(optarg)); + break; + case ':': + fprintf(stderr, "missing parameter\n"); + return(-1); + default: + return(-1); + } + } + return(0); +} + + +/* + * add a DNS header + */ +static void +add_dnshdr(unsigned char *pkt) +{ + struct _dnshdr *dnshdr = (struct _dnshdr *)pkt; + + dnshdr->id = htons(6); /* could be random */ + dnshdr->flags = htons(0x0100); /* do query recursivly */ + dnshdr->num_q = htons(1); + dnshdr->num_answ_rr = 0; + dnshdr->num_auth_rr = 0; + dnshdr->num_addi_rr = 0; +/* add request here. class TXT etc */ +} + +/* + * add DNS-TXT header here + * returns length in *len + */ +static void +add_dnstxthdr(unsigned char *pkt, char *name, u_int *len) +{ + u_short *type; + u_short *class; + + if (name == NULL) + return; /* nah! specifiy "". we need \0 termination */ + + memcpy(pkt, name, strlen(name)+1); + type = (u_short *)(pkt + strlen(name) + 1); + class = (u_short *)(pkt + strlen(name) + 1 + sizeof(*class)); + + *type = htons(0x10); /* TEXT string */ + *class = htons(0x03); /* chaos */ + *len = strlen(name) + 1 + sizeof(*type) + sizeof(*class); +} + + +/* + * handle incoming DNS udp answers + */ +static int +process_rcv(struct _opt *opt) +{ + struct _dnshdr *dns; + struct _dnsanswr *dnsanswr; + struct udphdr *udp; + char *ptr; + char buf[128]; + int len, dnstxtlen; + uint iphdr_len = 0; + + if (ip->ip_p != IPPROTO_UDP) + return(0); + + iphdr_len = IP_SIZE + ip_options; + if (plen < dlt_len + iphdr_len + sizeof(*udp) + sizeof(*dns)) + return(-1); /* invalid size */ + + dns = (struct _dnshdr *) (align_buf + iphdr_len + sizeof(*udp)); + if (ntohs(dns->flags) & 0x000F) /* dns-error? query refused ? */ + return(-1); + + ptr = (char *) (align_buf + iphdr_len + sizeof(*udp) + sizeof(*dns)); + len = dlt_len + iphdr_len + sizeof(*udp) + sizeof(*dns); + + while (len++ < plen) + if (*ptr++ == '\0') + break; + + if (len >= plen) + return(-1); + + len += 4; + ptr += 4; + + while (len++ < plen) /* skip VERSION.BIND answer string */ + if (*ptr++ == '\0') + break; + + len += sizeof(*dnsanswr); + if (len >= plen) + return(-1); + + dnsanswr = (struct _dnsanswr *) (ptr); + dnstxtlen = ntohs(dnsanswr->len); + if (len + dnstxtlen > plen) + return(0); + + if ((dnstxtlen == 0) || (dnstxtlen > 128)) + return(-1); + + memcpy(buf, ptr + sizeof(*dnsanswr) +1, dnstxtlen - 1); + buf[dnstxtlen - 1] = '\0'; + + ptr = buf; /* evil hax0rs sending messed up strings ? */ + while (*++ptr != '\0') + if (!isprint((int)*ptr)) + *ptr = '_'; + + printf("%s VERSION.BIND. \"%s\"\n", int_ntoa(ip->ip_src.s_addr), buf); + + return(0); + +} + + diff --git a/other/b-scan/tmp/modules/mod_httpd.c b/other/b-scan/tmp/modules/mod_httpd.c new file mode 100644 index 0000000..275125c --- /dev/null +++ b/other/b-scan/tmp/modules/mod_httpd.c @@ -0,0 +1,188 @@ +/* + * mod_example.c + * Example module for bscan. + */ + +#include +#include +#include + + +#ifndef MOD_NAME +#define MOD_NAME "mod_httpd" +#endif + +#define HEADREQ "HEAD / HTTP/1.0\r\n\r\n" + + +static int isinit=0; +/* + * some variables from the binary-process + */ +extern int dlt_len; +extern u_char *align_buf; +extern unsigned short ip_options; +extern struct ip *ip; +extern struct Ether_header *eth; +extern u_int plen, pcaplen; + +struct _mopt +{ + unsigned short int dport; /* dport in NBO */ + char *request; /* the http-request */ +} static mopt; + +/* + * static functions prototypes + */ +static int mdo_opt(int, char **, struct _opt *); +static void init_vars(struct _opt *); +static int process_rcv(struct _opt *); + +/* + * print out usage informations + */ +void +musage() +{ + printf ("\n"MOD_NAME"\n"); + printf (" -p , default 80\n"); + printf (" -r , default 'HEAD / HTTP/1.0'\n"); +} + + +/* + * return 0 on success, != 0 on failure + */ +int +init(char **modname, int argc, char *argv[], struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE INIT\n"); +#endif + if (isinit) + return(-1); + + *modname = MOD_NAME; + isinit = 1; + init_vars(opt); + + if (mdo_opt(argc, argv, opt) != 0) + return(-1); + + return(0); +} + +/* + * fini-routine. called on cleanup + */ +int +fini() +{ +#ifdef DEBUG + printf("MODULE FINI\n"); +#endif + return(0); +} + + +/* + * + */ +int +callmdl(int entry, struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE CALLMDL\n"); +#endif + if (entry == MOD_FIRSTPKG) + return(RMOD_SKIP); + + if (entry == MOD_RCV) + process_rcv(opt); + + return(RMOD_OK); +} + + +/* + *********************************************************** + * Our OWN/static functions for THIS module * + *********************************************************** + */ + +/* + * initialize all local variables. + * We use some 'unused' variables of the masterprogramm + */ +static void +init_vars(struct _opt *opt) +{ + mopt.dport = htons(80); + mopt.request = HEADREQ; +} + + +/* + * LOCAL/STATIC function, only available in the module + * return 0 on success, != 0 on failure + */ +static int +mdo_opt(int argc, char *argv[], struct _opt *opt) +{ + extern char *optarg; + /*extern int optind, opterr, optopt;*/ + int c; + + while ((c = getopt (argc, argv, "p:r:")) != -1) + { + switch (c) + { + case 'p': + mopt.dport = htons(strtoul (optarg, (char **) NULL, 10)); + break; + case 'r': + mopt.request = optarg; + fprintf(stderr, MOD_NAME ": requesting \"%s\"\n", optarg); + break; + case ':': + fprintf(stderr, "missing parameter\n"); + return(-1); + default: + return(-1); + } + } + return(0); +} + + +/* + * process incoming packets + * IP-packet is verified and variables valid (ip_options, *ip) + */ +static int +process_rcv(struct _opt *opt) +{ + struct tcphdr *tcp; + unsigned short tcp_options = 0; + uint iphdr_len = 0; + + + if (ip->ip_p != IPPROTO_TCP) + return(0); + + iphdr_len = sizeof(*ip) + ip_options; + tcp = (struct tcphdr *) (align_buf + iphdr_len); + + if (vrfy_tcp(tcp, plen - dlt_len - iphdr_len, &tcp_options) != 0) + return(0); + + if (tcp->th_sport != mopt.dport) + return(0); + + if ((tcp->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) + answer_tcp (opt->sox, ip, tcp, TH_ACK | TH_PUSH, mopt.request, strlen(mopt.request)); + + return(0); +} + diff --git a/other/b-scan/tmp/modules/mod_ping.c b/other/b-scan/tmp/modules/mod_ping.c new file mode 100644 index 0000000..73a90a4 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_ping.c @@ -0,0 +1,205 @@ +/* + * ping-module for bscan. + * IDEA: add record-route and source-route feature + * and -p pattern [where can we save our time-struct then ? + */ + +#include +#include +#include +#include + + +#ifndef MOD_NAME +#define MOD_NAME "mod_ping" +#endif + +static int process_rcv(struct _opt *); + +static int isinit=0; +/* + * some variables from the binary-process + */ +extern int dlt_len; +extern u_char *align_buf; +extern unsigned short ip_options; +extern struct ip *ip; +extern struct Ether_header *eth; +extern u_int plen, pcaplen; +extern struct timeval *pts; + +struct _mopt +{ + int type; + int size; +} static mopt; + +/* + * static functions prototypes + */ +static int mdo_opt(int, char **, struct _opt *); +static void init_vars(struct _opt *); + +/* + * print out usage informations + */ +void +musage() +{ + printf ("\n"MOD_NAME"\n"); + printf (" -t (echo|time) -s , size of ping-data [default 56].\n"); +} + + +/* + * return 0 on success, != 0 on failure + */ +int +init(char **modname, int argc, char *argv[], struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE INIT\n"); +#endif + if (isinit) + return(-1); + + *modname = MOD_NAME; + isinit = 1; + init_vars(opt); + + if (mdo_opt(argc, argv, opt) != 0) + return(-1); + + return(0); +} + +/* + * fini-routine. called on cleanup + */ +int +fini() +{ +#ifdef DEBUG + printf("MODULE FINI\n"); +#endif + return(0); +} + + +/* + * Module entry point [entry] + * RMOD_OK: everything allright. send the packet out [if first] + * or do nothing [MOD_RCV]. + * RMOD_SKIP: proceed with next IP without sending out the packet. + */ +int +callmdl(int entry, struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE CALLMDL\n"); +#endif + if (entry == MOD_FIRSTPKG) + { + add_icmpping (opt->packet + ETH_SIZE + IP_SIZE, mopt.size, mopt.type); + add_iphdr (opt->packet + ETH_SIZE, IPPROTO_ICMP, &opt->nt, ICMP_SIZE + mopt.size); + opt->pkg_len = IP_SIZE + ICMP_SIZE + mopt.size; + return(RMOD_OK); + } + + if (entry == MOD_RCV) + process_rcv(opt); + + return(RMOD_OK); +} + + +/* + *********************************************************** + * Our OWN/static functions for THIS module * + *********************************************************** + */ + +/* + * initialize all local variables. + * We use some 'unused' variables of the masterprogramm + */ +static void +init_vars(struct _opt *opt) +{ + mopt.size = ICMP_ECHO; + mopt.size = 56; +} + + +/* + * LOCAL/STATIC function, only available in the module + * return 0 on success, != 0 on failure + */ +static int +mdo_opt(int argc, char *argv[], struct _opt *opt) +{ + extern char *optarg; + /*extern int optind, opterr, optopt;*/ + int c; + + while ((c = getopt (argc, argv, "t:s:")) != -1) + { + switch (c) + { + case 't': + if (strcasecmp (optarg, "echo") == 0) + mopt.type = ICMP_ECHO; + else if (strcasecmp (optarg, "time") == 0) + mopt.type = ICMP_TSTAMP; + else + return (-1); + break; + case 's': + mopt.size = atoi(optarg); + break; + case ':': + fprintf(stderr, "missing parameter\n"); + return(-1); + default: + return(-1); + } + } + return(0); +} + + +/* + * handle incoming icmp ECHO_REPLY packages + */ +static int +process_rcv(struct _opt *opt) +{ + struct icmp *icmp; + struct timeval now; + double rrt; + + if (ip->ip_p != IPPROTO_ICMP) + return(0); + + if (plen < dlt_len + IP_SIZE + ip_options + sizeof(*icmp)) + return(0); /* invalid size */ + + icmp = (struct icmp *) (align_buf + IP_SIZE + ip_options); + +// if ((icmp->icmp_type != 0) || (icmp->icmp_code != 0)) +// return(0); + + memcpy(&now, pts, sizeof(now)); + time_diff((struct timeval *)icmp->icmp_dun.id_data, &now); + rrt = now.tv_sec * 1000.0 + now.tv_usec / 1000.0; + + printf("%d bytes from %s: icmp_seq=%u ttl=%d time=%.3f ms\n", + (int)(plen - dlt_len - IP_SIZE - ip_options), + int_ntoa(ip->ip_src.s_addr), icmp->icmp_hun.ih_idseq.icd_seq, + ip->ip_ttl, rrt); + + return(0); + +} + + diff --git a/other/b-scan/tmp/modules/mod_snmp.c b/other/b-scan/tmp/modules/mod_snmp.c new file mode 100644 index 0000000..db56455 --- /dev/null +++ b/other/b-scan/tmp/modules/mod_snmp.c @@ -0,0 +1,899 @@ +/* + * SimpleNetworkManagementProtocol module for bscan. + * RFC 1157 + * + * + * ###fixme todo: port to sparc + */ + +#include +#include +#include +#include + + +#ifndef MOD_NAME +#define MOD_NAME "mod_snmp" +#endif + +#define SNMP_DFLT_REQOBJ "1.3.6.1.2.1.1" + +#define MAX_VALSTRLEN 512 + +#define MOPT_NOOBJ 0x01 +#define MOPT_STRIP 0x02 + +#define SNMP_GET 0xa0 +#define SNMP_GET_NEXT 0xa1 +#define SNMP_SET 0xa3 +#define ASN_SUBCAT 0x30 /* BER encoding, sub-categorie */ + +#ifndef ASN_INTEGER +#define ASN_INTEGER ((u_char)0x02) +#endif +#define ASN_INTEGERSTR "INTEGER" +#ifndef ASN_BIT_STR +#define ASN_BIT_STR ((u_char)0x03) +#endif +#define ASN_BIT_STRSTR "BITSTRING" +#ifndef ASN_OCTET_STR +#define ASN_OCTET_STR ((u_char)0x04) +#endif +#define ASN_OCTET_STRSTR "STRING" +#ifndef ASN_NULL +#define ASN_NULL ((u_char)0x05) +#endif +#define ASN_NULLSTR "NULL" +#ifndef ASN_OBJECT_ID +#define ASN_OBJECT_ID ((u_char)0x06) +#endif +#define ASN_OBJECT_IDSTR "OBJ" +#ifndef ASN_APPLICATION +#define ASN_APPLICATION ((u_char)0x40) +#endif +#ifndef ASN_LONG_LEN +#define ASN_LONG_LEN ((u_char)0x80) +#endif +#define ASN_APPLICATIONSTR "APPLICATION" +#ifndef ASN_IPADDRESS +#define ASN_IPADDRESS (ASN_APPLICATION | 0) +#endif +#define ASN_IPADDRESSSTR "IPADDR" +#ifndef ASN_UNSIGNED +#define ASN_UNSIGNED (ASN_APPLICATION | 2) +#endif +#define ASN_UNSIGNEDSTR ASN_INTEGERSTR +#ifndef ASN_TIMETICKS +#define ASN_TIMETICKS (ASN_APPLICATION | 3) +#endif +#define ASN_TIMETICKSSTR "TIMETICKS" +#ifndef ASN_COUNTER +#define ASN_COUNTER (ASN_APPLICATION | 1) +#endif +#define ASN_COUNTERSTR "COUNTER" + +#define SNMP_ERR_WRONGTYPE (7) +#define SNMP_ERR_WRONGLENGTH (8) +#define SNMP_ERR_WRONGENCODING (9) +#define SNMP_ERR_WRONGVALUE (10) +#define SNMP_ERR_NOCREATION (11) +#define SNMP_ERR_INCONSISTENTVALUE (12) +#define SNMP_ERR_RESOURCEUNAVAILABLE (13) +#define SNMP_ERR_COMMITFAILED (14) +#define SNMP_ERR_UNDOFAILED (15) +#define SNMP_ERR_AUTHORIZATIONERROR (16) +#define SNMP_ERR_NOTWRITABLE (17) + +char *snmp_error[] = { + "NO ERROR", + "TOO BIG", + "NO SUCH NAME", + "BAD VALUE", + "READONLY", + "GENERELL ERROR", + "NO ACCESS", + "WRONG TYPE", + "WRONG LENGTH", + "WRONG ENCODING", + "WRONG VALUE", + "NO CREATION", + "INCONSISTENT VALUE", + "RESOURCE UNAVAILABLE", + "COMMIT FAILED", + "UNDO FAILED", + "AUTORISATION ERROR", + "NOT WRITEABLE", + "INCONSISTENT NAME" }; + +#define MAX_SNMP_ERR 18 + + + +#define ADD_DATA(ptr, in, len, totlen) memcpy(ptr, in, len);\ + *totlen = *totlen + len; + +#define min(a,b) ((a)<(b)?(a):(b)) + + +static int isinit=0; +/* + * some variables from the binary-process + */ +extern int dlt_len; +extern u_char *align_buf; +extern unsigned short ip_options; +extern struct ip *ip; +extern struct Ether_header *eth; +extern u_int plen, pcaplen; +extern struct timeval *pts; + +struct _pdu +{ + u_char *varbuf; + int varlen; +}; + +struct _mopt +{ + char *community; + u_char flags; + u_char snmptor; /* type of request */ + struct _pdu pdu; +} static mopt; + +struct _pdunfo +{ + u_char *community; + u_char *pdu_type; + u_char *error_status; + u_char *error_idx; +} static pdunfo; + + +/* + * static functions prototypes + */ +static int mdo_opt(int, char **, struct _opt *); +static void init_vars(struct _opt *); +static int process_rcv(struct _opt *); +static int add_snmp (u_char *, int *); +static int add_snmpreq (u_char *, int *, u_char, u_char *, struct _pdu *); +static int add_snmp_var(struct _pdu *, u_char *); +static int build_snmp_objreq(u_char *, u_char *,u_char *, u_char, u_char *); +static int str2asnv(u_char *, u_char, u_char *, u_char *); +static int str2objid(u_char *, u_char *, u_char *); + + +/* + * print out usage informations + */ +void +musage() +{ + printf ("\n"MOD_NAME"\n"); + printf ("snmp module\n"); + printf (" -p , destination port, default 161\n"); + printf (" -o , source port, default 53\n"); + printf (" -r , default '1.3.6.1.2.1.1 (system)'\n"); + printf (" -c , default 'public'\n"); + printf (" -g , (get|getnext|set), default 'getnext'\n"); + printf (" -s strip unprintable characters from STRING types, and output as text\n"); + printf (" -q dont print out OBJ-types\n"); + printf ("\n"); + printf ("type: i: INTEGER, s: STRING, n: NULLOBJ, o: OBJID\n"); + printf (" t: TIMETICKS, a: IPADDRESS, b: BITSTRING, c: COUNTER\n"); + printf ("\n"); + printf ("you can request multiple objects with one request:\n"); + printf ("-g get -r 1.3.6.1.2.1.1.1.0 -r 1.3.6.1.2.1.1.4.0 -r 1.3.6.1.2.1.1.5.0\n"); +} + + +/* + * return 0 on success, != 0 on failure + */ +int +init(char **modname, int argc, char *argv[], struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE INIT\n"); +#endif + if (isinit) + return(-1); + + *modname = MOD_NAME; + isinit = 1; + init_vars(opt); + + if (mdo_opt(argc, argv, opt) != 0) + return(-1); + + return(0); +} + +/* + * fini-routine. called on cleanup + */ +int +fini() +{ +#ifdef DEBUG + printf("MODULE FINI\n"); +#endif + return(0); +} + + +/* + * Module entry point [entry] + * RMOD_OK: everything allright. send the packet out [if first] + * or do nothing [MOD_RCV]. + * RMOD_SKIP: proceed with next IP without sending out the packet. + * RMOD_ERROR: failed to create packet. + * RMOD_ABRT: critical failure, abort! + */ +int +callmdl(int entry, struct _opt *opt) +{ +#ifdef DEBUG + printf("MODULE CALLMDL\n"); +#endif + if (entry == MOD_FIRSTPKG) + { + add_snmp(opt->packet+ ETH_SIZE + IP_SIZE + UDP_SIZE, &opt->pkg_len); + add_udphdr (opt->packet+ ETH_SIZE+ IP_SIZE, &opt->nt, opt->pkg_len); + add_iphdr (opt->packet + ETH_SIZE, IPPROTO_UDP, &opt->nt, opt->pkg_len + UDP_SIZE); + opt->pkg_len += UDP_SIZE + IP_SIZE; + + return(RMOD_OK); + } + + if (entry == MOD_RCV) + process_rcv(opt); + + return(RMOD_OK); +} + + +/* + *********************************************************** + * Our OWN/static functions for THIS module * + *********************************************************** + */ + +/* + * initialize all local variables. + * We use some 'unused' variables of the masterprogramm + */ +static void +init_vars(struct _opt *opt) +{ + opt->nt.sport = htons(32770); + opt->nt.dport = htons(161); + mopt.flags = 0; + mopt.community = "public"; + mopt.snmptor = SNMP_GET_NEXT; +} + + +/* + * LOCAL/STATIC function, only available in the module + * return 0 on success, != 0 on failure + */ +static int +mdo_opt(int argc, char *argv[], struct _opt *opt) +{ + extern char *optarg; + /*extern int optind, opterr, optopt;*/ + int c; + + while ((c = getopt (argc, argv, "qsg:c:r:p:o:")) != -1) + { + switch (c) + { + case 'q': + mopt.flags |= MOPT_NOOBJ; + break; + case 's': + mopt.flags |= MOPT_STRIP; + break; + case 'p': + opt->nt.dport = htons(atoi(optarg)); + break; + case 'o': + opt->nt.sport = htons(atoi(optarg)); + break; + case 'r': + add_snmp_var(&mopt.pdu, optarg); + break; + case 'c': + mopt.community = optarg; + break; + case 'g': + if (strcasecmp (optarg, "get") == 0) + mopt.snmptor = SNMP_GET; + else if (strcasecmp (optarg, "getnext") == 0) + mopt.snmptor = SNMP_GET_NEXT; + else if (strcasecmp (optarg, "set") == 0) + mopt.snmptor = SNMP_SET; + else + return (-1); + break; + case ':': + fprintf(stderr, "missing parameter\n"); + return(-1); + default: + return(-1); + } + } + + if (mopt.pdu.varbuf == NULL) + add_snmp_var(&mopt.pdu, SNMP_DFLT_REQOBJ); + + return(0); +} + + +static u_char +strtoasn_vtype(int src) +{ + + src = tolower(src); + + switch (src) + { + case 'i': + return(ASN_INTEGER); + case 's': + return(ASN_OCTET_STR); + case 'n': + return(ASN_NULL); + case 'o': + return(ASN_OBJECT_ID); + case 't': + return(ASN_TIMETICKS); + case 'b': + return(ASN_BIT_STR); + case 'a': + return(ASN_IPADDRESS); + case 'u': + return(ASN_UNSIGNED); + case 'c': + return(ASN_COUNTER); + default: + fprintf(stderr, "WARNING: unsupported value-type.\n"); + return(src); + } + + return(ASN_NULL); +} + +/* + * add variable to our variable-queue + * input: ::-format + * return 0 on success, !=0 on parse error etc + */ +static int +add_snmp_var(struct _pdu *pdu, u_char *src) +{ + u_char *request; + u_char vtype = 5; + u_char *value = NULL; + u_char *ptr = NULL; + u_char reqlen=0; + + if (pdu->varbuf == NULL) + { + pdu->varbuf = calloc(1, 1024); + pdu->varlen = 0; + } + + request = src; + + if ( (ptr = strchr(src, ':')) != NULL) + *ptr++ = '\0'; + + src = ptr; + if (ptr != NULL) + { + if ( (ptr = strchr(src, ':')) != NULL) + { + *ptr++ = '\0'; + if (strlen(ptr) > 0) + value = ptr; + } + vtype = strtoasn_vtype(*src); + } + + if (build_snmp_objreq(pdu->varbuf + pdu->varlen, &reqlen, request, vtype, value) != 0) + { + fprintf(stderr, "WARNING: error while parsing reqOBJ\n"); + return(-1); + } + + pdu->varlen += reqlen; + + return(0); +} + +/* + * convert OBJ-ID and build the snmp-request packet + * save the work and reuse [better performance, the snmp + * packet is always the same]. + * return 0 on success + */ +static int +add_snmp(u_char *ptr, int *lenptr) +{ + static u_char *buf = NULL; + static int buflen; + + if (buf != NULL) /* fastmode, use old copy of previous build snmppkg */ + { + *lenptr = buflen; + memcpy(ptr, buf, buflen); + return(0); + } + + if (buf == NULL) + buf = malloc(1024); + + add_snmpreq (ptr, lenptr, mopt.snmptor, mopt.community, &mopt.pdu); + + memcpy(buf, ptr, *lenptr); /* for later reuse */ + buflen = *lenptr; + + return(0); +} + +/* + * convert snmp obj in dotted-notation, 0-terminated string to obj-id in asn.1 + */ +static int +str2objid(u_char *dst, u_char *retlen, u_char *src) +{ + u_char *dotptr; + u_char len; + + if (strncmp(src, "1.3.6.1.", 8) != 0) + return(-1); /* snmp only , iso.org.dot.internet.* */ + + src += 8; /* we know the first 8 bytes. */ + + memcpy(dst, "\x2b\x06\x01", 3); /* yepp, we know this. "1.3.6.1" */ + dst += 3; + dotptr = src; + len = 3; /* 2b-06-01 */ + while ( (dotptr = strchr (src, '.')) != NULL) + { + *dotptr = '\0'; + *dst++ = (u_char)atoi(src); + src = ++dotptr; + len++; + } + if (strlen(src) > 0) + { + *dst++ = (u_char)atoi(src); + len++; + } + + *retlen = len; + return(0); +} + + +/* + * convert input to ASN.1 BER encodet + * dst: guess what. + * ptr: snmp obj in dotted-notation (1.3.6.1.2.1.1....), 0-terminated string + * tov: type of value, ASN.1 encodet (int, 8octet string, ...) + * value: the value (string, 0-terminated) + * return: 0 on success + */ +static int +build_snmp_objreq(u_char *dst, u_char *retlen, u_char *src, u_char tov, + u_char *value) +{ + u_char *srcw; + u_char vlen = 0; + u_char *sublen; + u_char *subsublen; + u_char *subvlen; + u_char len; + + srcw = alloca(strlen(src)+1); + memcpy(srcw, src, strlen(src)+1); + if (strlen(srcw) <= 4) + return(-1); + + *dst++ = ASN_SUBCAT; + sublen = dst++; /* we set the length later coz we dont know it yet */ + + *dst++ = 0x06; /* OBJ-ID */ + subsublen = dst++; /* and this also not */ + + if (str2objid(dst, &len, srcw) != 0) + return(-1); + + *subsublen = len; /* length of obj */ + dst += len; + + *dst++ = tov; /* type of value */ + subvlen = dst++; /* we set this later..we dont know the length yet */ + str2asnv(value, tov, dst, &vlen); + + *subvlen = vlen; /* length of value */ + + *sublen = len + vlen + 4; /* length of */ + + *retlen = len + vlen + 6; + return(0); +} + + +/* + * convert 0-terminated string value to asn encodet value + * return 0 on success + * on return the length of rvalue < value. + * input: value [0 terminated string] + * tov [asn]-type of value + * output: rvalue [non 0-terminated string with asn-value] + * vlen [length of rvalue] + * return 0 on success + * attention: we use full integers (length=4, not reduced in length + * to the minimum size). the snmp-lib reduces the length of an + * integer to the minimum size...but this is not a must + */ +static int +str2asnv(u_char *value, u_char tov, u_char *rvalue, u_char *vlen) +{ + unsigned long int ltmp; + + if (rvalue == NULL) + return(0); /* yes, NULL is allowed */ + if ((rvalue != NULL) && (vlen == NULL)) + return(-1); + + switch(tov) + { + case ASN_INTEGER: + ltmp = htonl(strtol(value, NULL, 10)); + memcpy(rvalue, <mp, sizeof(ltmp)); + *vlen = sizeof(ltmp); + break; + case ASN_UNSIGNED: + case ASN_COUNTER: + case ASN_TIMETICKS: + ltmp = htonl(strtoul(value, NULL, 10)); + memcpy(rvalue, <mp, sizeof(ltmp)); + *vlen = (sizeof(ltmp)); + break; + case ASN_IPADDRESS: + ltmp = inet_addr(value); + memcpy(rvalue, <mp, sizeof(ltmp)); + *vlen = sizeof(ltmp); + break; + case ASN_OBJECT_ID: + str2objid(rvalue, vlen, value); + break; + case ASN_OCTET_STR: + memcpy(rvalue, value, strlen(value)); + *vlen = strlen(value); + break; + case ASN_NULL: + *vlen = 0; + break; + default: + *vlen = 0; + fprintf(stderr, "WARNING, unsupported value type !\n"); + } + + return(0); +} + +/* + * add snmp request + * build the entire SNMP packet [version, community, pdu, id, error, idx, ..] + * req: objs + values [BER encodet, already with header and \x30 sub start] + * reqlen: len of entire req [objs + values] + * tor: type of request [get, getnext, set] + */ +static int +add_snmpreq (u_char *pkt, int *len, u_char tor, u_char *community, struct _pdu *pdu) +{ + int le = 0; + + *(pkt + le++) = ASN_SUBCAT; + *(pkt + le++) = (u_char)(pdu->varlen + strlen(community) + 18); + ADD_DATA(pkt + le, "\x02\x01\x00\x04" , 4, &le); /* SNMPv1 + STRINGOBJ*/ + *(pkt + le++) = (u_char)strlen(community); + ADD_DATA(pkt + le, community, strlen(community), &le); + *(pkt + le++) = tor; /* PDU GET-NEXTrequest */ + /* lenof( + + + ) */ + *(pkt + le++) = (u_char)(pdu->varlen + 11); + /* + + */ + ADD_DATA(pkt + le, "\x02\x01\x01\x02\x01\00\x02\x01\x00\x30", 10, &le); + *(pkt + le++) = (u_char)(pdu->varlen); + ADD_DATA(pkt + le, pdu->varbuf, pdu->varlen, &le); + + *len = le; + return(0); +} + + +/* + * convert asn encoded obj to string + * input: string of + * datalen: max len i'm allowed to read from "ptr --> ..." + * return: + * prefix is the string representation of the value-type e.g. "OCTET-STRING".. + * and '' if value got truncated. + * is < 64 chars... + * val: the value (0-terminated string) + * return 0 on success + * 1 if truncated (value-length > size of snmp or val to small) + * -1 on error + */ +static int +asn2str(u_char *ptr, u_char *prefix, u_char *val, unsigned int datalen) +{ + unsigned long int len, day, hour, min, sec, msec; + u_char *ptr2; + u_char vlen = *(ptr+1); /* saved value length */ + u_char tov = *ptr; + unsigned long int ltmp; + int i, slen = 0; + u_char buf[128]; + + if (vlen > datalen-2) + len = datalen-2; + else + len = vlen; + + *val = '\0'; + *prefix = '\0'; + + switch(tov) + { + case ASN_IPADDRESS: + if (len > sizeof(ltmp)) + len = sizeof(ltmp); + + ptr2 = (u_char *)<mp; + memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); + sprintf(val, "%s", int_ntoa(ltmp)); + strcpy(prefix, ASN_IPADDRESSSTR); + break; + case ASN_NULL: + strcpy(prefix, ASN_NULLSTR); + break; + case ASN_TIMETICKS: + if (len > sizeof(ltmp)) + len = sizeof(ltmp); + + ltmp = 0; + ptr2 = (u_char *)<mp; + memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); + ltmp = ntohl(ltmp); + day = ltmp / 8640000; + hour = (ltmp % 8640000) / 360000; + min = (ltmp % 360000) / 6000; + sec = (ltmp % 6000) / 100; + msec = (ltmp % 100); + sprintf(val, "(%lu) %d days, %2.2d:%2.2d:%2.2d.%d", ltmp, + (int)day, (int)hour, (int)min, (int)sec, (int)msec); + if (tov == ASN_TIMETICKS) + strcpy(prefix, ASN_TIMETICKSSTR); + break; + case ASN_INTEGER: + case ASN_UNSIGNED: + case ASN_COUNTER: + ltmp = 0; + if (len > sizeof(ltmp)) + len = sizeof(ltmp); + + ptr2 = (u_char *)<mp; + memcpy(ptr2 + sizeof(ltmp) - len, ptr+2, len); + + if (tov == ASN_INTEGER) + sprintf(val, "%lu", (unsigned long int)ntohl(ltmp)); + else + sprintf(val, "%ld", (long int)ntohl(ltmp)); + + if (tov == ASN_INTEGER) + strcpy(prefix, ASN_INTEGERSTR); + if (tov == ASN_UNSIGNED) + strcpy(prefix, ASN_UNSIGNEDSTR); + if (tov == ASN_COUNTER) + strcpy(prefix, ASN_COUNTERSTR); + break; + case ASN_OCTET_STR: + if (isprintdata(ptr+2, len)) + { + if (len > MAX_VALSTRLEN-1) + len = MAX_VALSTRLEN-1; + memcpy(val, ptr+2, len); + val[len] = '\0'; + } else if ((mopt.flags & MOPT_STRIP) == MOPT_STRIP) { + dat2strip(val, MAX_VALSTRLEN, ptr+2, len); + } else { + dat2hexstr(val, MAX_VALSTRLEN, ptr+2, len); + } + + strcpy(prefix, ASN_OCTET_STRSTR); + break; + case ASN_OBJECT_ID: + i = 0; + slen = 0; + while(i < len) + { + if (*(ptr+2+i) == 0x2b) + strcpy(buf, "1.3."); /* substituate shorts */ + else + snprintf(buf, sizeof(buf), "%d.", *(ptr+2+i)); + + buf[sizeof(buf)-1] = '\0'; + slen = strlen(val) + strlen(buf); + + if (slen < MAX_VALSTRLEN -1) + strcat(val, buf); + else + break; + + i++; + } + val[slen-1] = '\0'; /* remove last '.' */ + strcpy(prefix, ASN_OBJECT_IDSTR); + break; + default: + dat2hexstr(val, MAX_VALSTRLEN, ptr+2, len); + break; + } + + if (*prefix == '\0') + strcpy(prefix, "UNKNOWN"); + + if (vlen > len) + { + strcat(prefix, ""); + return(1); + } + + return(0); +} + +/* + * return TypeOfValue and let next point to the next asn encodet obj + * ptr: pointer to asn.1 encodet obj + * len: returns the length of the OLD value + suffix [length we skipped] + * next: returns a pointer to the next obj. + */ +static u_char +asn_getnext(u_char *ptr, u_char *len, u_char **next) +{ + u_char vlen = *(ptr+1); + + if (*ptr == ASN_SUBCAT) + { + if (vlen & ASN_LONG_LEN) + vlen = vlen & ~ASN_LONG_LEN; + else + vlen = 0; + } + + *next = ptr + vlen + 2; + + *len = vlen + 2; + return(**next); +} + +#define RETURN_ILLLEN(x,y,r) if (x >= y) return(r); + +/* + * handle incoming snmp answers, answer with 'next' if not last record + */ +static int +process_rcv(struct _opt *opt) +{ + struct udphdr *udp; + u_char *ptr; + int len; + int snmplen; + uint iphdr_len = 0; + u_char objlen; + u_char buf[MAX_VALSTRLEN]; + u_char prefix[32]; + u_char buf2[MAX_VALSTRLEN + 32]; + u_char asnprefix[128]; + u_char c; + + if (ip->ip_p != IPPROTO_UDP) + return(0); + + iphdr_len = IP_SIZE + ip_options; + if (plen < dlt_len + iphdr_len + sizeof(*udp)) + return(-1); /* invalid size */ + + udp = (struct udphdr *) (align_buf + iphdr_len); + ptr = (u_char *) (align_buf + iphdr_len + sizeof(*udp)); + snmplen = plen - dlt_len - iphdr_len - sizeof(*udp); + len = 0; + + /* + * we dont check the value of the ASN_SUBCAT-length coz many buggy + * hosts out there return a wrong length [0xff, 0x80, ...] + */ + + ptr += 2; len += 3; /* pointing on the 3rd element */ + RETURN_ILLLEN(len, snmplen, 0); + + asn_getnext(ptr, &objlen, &ptr); /* skip version, get community */ + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + pdunfo.community = ptr; + + asn_getnext(ptr, &objlen, &ptr); /* skip community, get pdu */ + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + pdunfo.pdu_type = ptr; + ptr += 2; + len += 2; /* skip pdu, get reqid */ + RETURN_ILLLEN(len, snmplen, 0); + + asn_getnext(ptr, &objlen, &ptr); /* skip reqid, get errorstatus */ + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + pdunfo.error_status = ptr; + + asn_getnext(ptr, &objlen, &ptr); /* skip errorstatus, get erroridx */ + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + pdunfo.error_idx = ptr; + + asn_getnext(ptr, &objlen, &ptr); /* skip erroridx, get */ + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + + asn_getnext(ptr, &objlen, &ptr); /* we reached the SUB section */ + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + + snprintf(prefix, sizeof(prefix) - 1, "%s:%d ", int_ntoa(ip->ip_src), + ntohs(udp->uh_sport)); + + c = *(pdunfo.error_status+2); + if (c != 0) + { + if (c < MAX_SNMP_ERR) + { + printf("%s%s (%d)\n", prefix, snmp_error[c], + *(pdunfo.error_idx+2)); + } else { + printf("%s UNKNOWN ERROR\n", prefix); + } + } + + while (1) + { + asn_getnext(ptr, &objlen, &ptr); + if (objlen == 0) + return(0); + + len += objlen; + RETURN_ILLLEN(len, snmplen, 0); + if (*ptr == ASN_SUBCAT) + continue; + + if ((mopt.flags & MOPT_NOOBJ) && (*ptr == ASN_OBJECT_ID)) + continue; + + asn2str(ptr, asnprefix, buf, snmplen - len + 1); + snprintf(buf2, sizeof(buf2)-1, "%s %s", asnprefix, buf); + buf2[sizeof(buf2)-1] = '\0'; + save_write(stdout, prefix, buf2, strlen(buf2)); + } + + return(0); + +} + + -- cgit v1.3