OpenVAS Scanner 23.40.3
nasl_snmp.c File Reference

Implementation of an API for SNMP used by NASL scripts. More...

#include "nasl_snmp.h"
#include "../misc/plugutils.h"
#include "nasl_lex_ctxt.h"
#include <assert.h>
#include <errno.h>
#include <gvm/base/logging.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
Include dependency graph for nasl_snmp.c:

Go to the source code of this file.

Data Structures

struct  snmpv1v2_request
 SNMP Request struct for snmp v1 and v2c. More...
struct  snmpv3_request
 SNMP Request struct for snmp v3. More...
struct  snmp_result

Macros

#define G_LOG_DOMAIN   "lib nasl"
 GLib logging domain.
#define SNMP_VERSION_1   0
 SNMP V1.
#define SNMP_VERSION_2c   1
 SNMP V2c.
#define FD_STDERR_FLAG   1
#define FD_STDOUT_FLAG   0
#define NASL_SNMP_GET   0
#define NASL_SNMP_GETNEXT   1

Typedefs

typedef struct snmpv1v2_requestsnmpv1v2_request_t
typedef struct snmpv3_requestsnmpv3_request_t
typedef struct snmp_resultsnmp_result_t

Functions

static void destroy_snmp_result (snmp_result_t result)
static int proto_is_valid (const char *proto)
static tree_cellarray_from_snmp_result (int ret, const snmp_result_t result)
static tree_cellarray_from_snmp_error (int ret, const char *err)
static void parse_snmp_error (snmp_result_t result)
 Parse the snmp error.
static int check_spwan_output (int fd, snmp_result_t result, int fd_flag)
 Read data from a file descriptor.
static int snmpv1v2c_get (const snmpv1v2_request_t request, snmp_result_t result)
 SNMP v1 or v2c Get query value. snmpget cmd wrapper.
static int snmpv3_get (const snmpv3_request_t request, snmp_result_t result)
 SNMPv3 Get query value. snmpget cmd wrapper.
static tree_cellnasl_snmpv1v2c_get (lex_ctxt *lexic, int version, u_char action)
tree_cellnasl_snmpv1_get (lex_ctxt *lexic)
tree_cellnasl_snmpv1_getnext (lex_ctxt *lexic)
tree_cellnasl_snmpv2c_get (lex_ctxt *lexic)
tree_cellnasl_snmpv2c_getnext (lex_ctxt *lexic)
static tree_cellnasl_snmpv3_get_action (lex_ctxt *lexic, u_char action)
tree_cellnasl_snmpv3_get (lex_ctxt *lexic)
tree_cellnasl_snmpv3_getnext (lex_ctxt *lexic)

Detailed Description

Implementation of an API for SNMP used by NASL scripts.

Definition in file nasl_snmp.c.

Macro Definition Documentation

◆ FD_STDERR_FLAG

#define FD_STDERR_FLAG   1

Definition at line 40 of file nasl_snmp.c.

Referenced by snmpv1v2c_get(), and snmpv3_get().

◆ FD_STDOUT_FLAG

#define FD_STDOUT_FLAG   0

Definition at line 41 of file nasl_snmp.c.

Referenced by check_spwan_output(), snmpv1v2c_get(), and snmpv3_get().

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib nasl"

GLib logging domain.

Definition at line 28 of file nasl_snmp.c.

◆ NASL_SNMP_GET

#define NASL_SNMP_GET   0

◆ NASL_SNMP_GETNEXT

#define NASL_SNMP_GETNEXT   1

◆ SNMP_VERSION_1

#define SNMP_VERSION_1   0

SNMP V1.

Definition at line 33 of file nasl_snmp.c.

Referenced by nasl_snmpv1_get(), nasl_snmpv1_getnext(), and snmpv1v2c_get().

◆ SNMP_VERSION_2c

#define SNMP_VERSION_2c   1

SNMP V2c.

Definition at line 38 of file nasl_snmp.c.

Referenced by nasl_snmpv2c_get(), nasl_snmpv2c_getnext(), and snmpv1v2c_get().

Typedef Documentation

◆ snmp_result_t

typedef struct snmp_result* snmp_result_t

Definition at line 80 of file nasl_snmp.c.

◆ snmpv1v2_request_t

Definition at line 55 of file nasl_snmp.c.

◆ snmpv3_request_t

Definition at line 72 of file nasl_snmp.c.

Function Documentation

◆ array_from_snmp_error()

tree_cell * array_from_snmp_error ( int ret,
const char * err )
static

Definition at line 150 of file nasl_snmp.c.

151{
153
154 assert (err);
156 retc->x.ref_val = g_malloc0 (sizeof (nasl_array));
157 /* Return code */
158 memset (&v, 0, sizeof (v));
159 v.var_type = VAR2_INT;
160 v.v.v_int = ret;
161 add_var_to_list (retc->x.ref_val, 0, &v);
162 /* Return error */
163 memset (&v, 0, sizeof v);
165 v.v.v_str.s_val = (unsigned char *) err;
166 v.v.v_str.s_siz = strlen (err);
167 add_var_to_list (retc->x.ref_val, 1, &v);
168
169 return retc;
170}
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ DYN_ARRAY
Definition nasl_tree.h:90
struct TC tree_cell
int add_var_to_list(nasl_array *a, int i, const anon_nasl_var *v)
Definition nasl_var.c:1245
struct st_a_nasl_var anon_nasl_var
struct st_nasl_array nasl_array
@ VAR2_STRING
Definition nasl_var.h:17
@ VAR2_INT
Definition nasl_var.h:16
union TC::@332262321161220155002104006201360276211317150140 x
void * ref_val
Definition nasl_tree.h:105
nasl_string_t v_str
Definition nasl_var.h:47
union st_a_nasl_var::@154137074032032170165360023270032033276061363156 v
long int v_int
Definition nasl_var.h:48
unsigned char * s_val
Definition nasl_var.h:26
long int s_siz
Definition nasl_var.h:27

References add_var_to_list(), alloc_typed_cell(), DYN_ARRAY, TC::ref_val, st_nasl_string::s_siz, st_nasl_string::s_val, st_a_nasl_var::v, st_a_nasl_var::v_int, st_a_nasl_var::v_str, VAR2_INT, VAR2_STRING, st_a_nasl_var::var_type, and TC::x.

Referenced by nasl_snmpv1v2c_get(), and nasl_snmpv3_get_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ array_from_snmp_result()

tree_cell * array_from_snmp_result ( int ret,
const snmp_result_t result )
static

Definition at line 117 of file nasl_snmp.c.

118{
120
121 assert (result);
122 assert (result->name);
124 retc->x.ref_val = g_malloc0 (sizeof (nasl_array));
125 /* Return code */
126 memset (&v, 0, sizeof (v));
127 v.var_type = VAR2_INT;
128 v.v.v_int = ret;
129 add_var_to_list (retc->x.ref_val, 0, &v);
130 /* Name */
131 memset (&v, 0, sizeof v);
133 v.v.v_str.s_val = (unsigned char *) g_strdup (result->name);
134 v.v.v_str.s_siz = strlen (result->name);
135 add_var_to_list (retc->x.ref_val, 1, &v);
136 /* OID */
137 if (result->oid_str != NULL)
138 {
139 memset (&v, 0, sizeof v);
141 v.v.v_str.s_val = (unsigned char *) g_strdup (result->oid_str);
142 v.v.v_str.s_siz = strlen (result->oid_str);
143 add_var_to_list (retc->x.ref_val, 2, &v);
144 }
145
146 return retc;
147}
char * oid_str
Definition nasl_snmp.c:76
char * name
Definition nasl_snmp.c:77

References add_var_to_list(), alloc_typed_cell(), DYN_ARRAY, snmp_result::name, snmp_result::oid_str, TC::ref_val, st_nasl_string::s_siz, st_nasl_string::s_val, st_a_nasl_var::v, st_a_nasl_var::v_int, st_a_nasl_var::v_str, VAR2_INT, VAR2_STRING, st_a_nasl_var::var_type, and TC::x.

Referenced by nasl_snmpv1v2c_get(), and nasl_snmpv3_get_action().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_spwan_output()

int check_spwan_output ( int fd,
snmp_result_t result,
int fd_flag )
static

Read data from a file descriptor.

Parameters
fd[in]File descriptor to read from.
result[out]String to write to.
Returns
0 success, -1 read error.

Definition at line 414 of file nasl_snmp.c.

415{
416 GString *string = NULL;
417
418 string = g_string_new ("");
419 while (1)
420 {
421 char buf[4096];
422 size_t bytes;
423
424 bytes = read (fd, buf, sizeof (buf));
425 if (!bytes)
426 break;
427 else if (bytes > 0)
428 g_string_append_len (string, buf, bytes);
429 else
430 {
431 g_warning ("snmpget: %s", strerror (errno));
432 g_string_free (string, TRUE);
433 return -1;
434 }
435 }
436
437 // Split the result and store the oid and name
438 // in the result struct if there is a result
439 if (fd_flag == FD_STDOUT_FLAG)
440 {
441 gchar **oid_and_name;
442
443 oid_and_name = g_strsplit (string->str, " ", 2);
444 result->oid_str = g_strdup (oid_and_name[0]);
445 result->name = g_strdup (oid_and_name[1]);
446 g_strfreev (oid_and_name);
447 }
448 else // STDERR, no oid
449 result->name = g_strdup (string->str);
450
451 g_string_free (string, TRUE);
452
453 return 0;
454}
#define FD_STDOUT_FLAG
Definition nasl_snmp.c:41
Define a string struct for storing the response.

References FD_STDOUT_FLAG, snmp_result::name, and snmp_result::oid_str.

Referenced by snmpv1v2c_get(), and snmpv3_get().

Here is the caller graph for this function:

◆ destroy_snmp_result()

void destroy_snmp_result ( snmp_result_t result)
static

Definition at line 83 of file nasl_snmp.c.

84{
85 if (result == NULL)
86 return;
87 g_free (result->name);
88 g_free (result->oid_str);
89 g_free (result);
90}

References snmp_result::name, and snmp_result::oid_str.

Referenced by nasl_snmpv1v2c_get(), and nasl_snmpv3_get_action().

Here is the caller graph for this function:

◆ nasl_snmpv1_get()

tree_cell * nasl_snmpv1_get ( lex_ctxt * lexic)

Definition at line 703 of file nasl_snmp.c.

704{
706}
#define SNMP_VERSION_1
SNMP V1.
Definition nasl_snmp.c:33
#define NASL_SNMP_GET
Definition nasl_snmp.c:358
static tree_cell * nasl_snmpv1v2c_get(lex_ctxt *lexic, int version, u_char action)
Definition nasl_snmp.c:633

References NASL_SNMP_GET, nasl_snmpv1v2c_get(), and SNMP_VERSION_1.

Here is the call graph for this function:

◆ nasl_snmpv1_getnext()

tree_cell * nasl_snmpv1_getnext ( lex_ctxt * lexic)

Definition at line 709 of file nasl_snmp.c.

710{
712}
#define NASL_SNMP_GETNEXT
Definition nasl_snmp.c:359

References NASL_SNMP_GETNEXT, nasl_snmpv1v2c_get(), and SNMP_VERSION_1.

Here is the call graph for this function:

◆ nasl_snmpv1v2c_get()

tree_cell * nasl_snmpv1v2c_get ( lex_ctxt * lexic,
int version,
u_char action )
static

Definition at line 633 of file nasl_snmp.c.

634{
635 tree_cell *retc = NULL;
636 const char *proto;
637 char peername[2048];
638 int port, ret;
639 snmpv1v2_request_t request;
640 snmp_result_t result;
641 char *oid_str;
642 static char *next_oid_str;
643
644 request = g_malloc0 (sizeof (struct snmpv1v2_request));
645
646 request->version = version;
647 request->action = action;
648 port = get_int_var_by_name (lexic, "port", -1);
649 proto = get_str_var_by_name (lexic, "protocol");
650 request->community = get_str_var_by_name (lexic, "community");
651
652 oid_str = get_str_var_by_name (lexic, "oid");
653 if (action == NASL_SNMP_GETNEXT && oid_str == NULL && next_oid_str != NULL)
654 request->oid_str = next_oid_str;
655 else
656 request->oid_str = oid_str;
657
658 if (!proto || !request->community || !request->oid_str)
659 {
660 g_free (request);
661 return array_from_snmp_error (-2, "Missing function argument");
662 }
663 if (port < 0 || port > 65535)
664 {
665 g_free (request);
666 return array_from_snmp_error (-2, "Invalid port value");
667 }
668 if (!proto_is_valid (proto))
669 {
670 g_free (request);
671 return array_from_snmp_error (-2, "Invalid protocol value");
672 }
673
674 g_snprintf (peername, sizeof (peername), "%s:%s:%d", proto,
675 plug_get_host_ip_str (lexic->script_infos), port);
676 request->peername = peername;
677
678 result = g_malloc0 (sizeof (struct snmp_result));
679 ret = snmpv1v2c_get (request, result);
680
681 // Hack the OID string to adjust format. Replace 'iso.' with '.1.'
682 // This Allows to call getnext without an oid, since the last oid
683 // is stored.
684 if (result->oid_str != NULL && g_strstr_len (result->oid_str, 3, "iso"))
685 {
686 next_oid_str = result->oid_str + 2;
687 next_oid_str[0] = '1';
688 result->oid_str = g_strdup (next_oid_str);
689 }
690 else if (result->oid_str != NULL)
691 next_oid_str = result->oid_str;
692
693 /* Free request only, since members are pointers to the nasl lexic context
694 which will be free()'d later */
695 g_free (request);
696
697 retc = array_from_snmp_result (ret, result);
698 destroy_snmp_result (result);
699 return retc;
700}
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
static int snmpv1v2c_get(const snmpv1v2_request_t request, snmp_result_t result)
SNMP v1 or v2c Get query value. snmpget cmd wrapper.
Definition nasl_snmp.c:466
static void destroy_snmp_result(snmp_result_t result)
Definition nasl_snmp.c:83
struct snmpv1v2_request * snmpv1v2_request_t
Definition nasl_snmp.c:55
static tree_cell * array_from_snmp_result(int ret, const snmp_result_t result)
Definition nasl_snmp.c:117
static int proto_is_valid(const char *proto)
Definition nasl_snmp.c:100
struct snmp_result * snmp_result_t
Definition nasl_snmp.c:80
static tree_cell * array_from_snmp_error(int ret, const char *err)
Definition nasl_snmp.c:150
char * plug_get_host_ip_str(struct script_infos *desc)
Definition plugutils.c:377
SNMP Request struct for snmp v1 and v2c.
Definition nasl_snmp.c:47
struct script_infos * script_infos

References snmpv1v2_request::action, array_from_snmp_error(), array_from_snmp_result(), snmpv1v2_request::community, destroy_snmp_result(), get_int_var_by_name(), get_str_var_by_name(), NASL_SNMP_GETNEXT, snmp_result::oid_str, snmpv1v2_request::oid_str, snmpv1v2_request::peername, plug_get_host_ip_str(), proto_is_valid(), struct_lex_ctxt::script_infos, snmpv1v2c_get(), and snmpv1v2_request::version.

Referenced by nasl_snmpv1_get(), nasl_snmpv1_getnext(), nasl_snmpv2c_get(), and nasl_snmpv2c_getnext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nasl_snmpv2c_get()

tree_cell * nasl_snmpv2c_get ( lex_ctxt * lexic)

Definition at line 715 of file nasl_snmp.c.

716{
718}
#define SNMP_VERSION_2c
SNMP V2c.
Definition nasl_snmp.c:38

References NASL_SNMP_GET, nasl_snmpv1v2c_get(), and SNMP_VERSION_2c.

Here is the call graph for this function:

◆ nasl_snmpv2c_getnext()

tree_cell * nasl_snmpv2c_getnext ( lex_ctxt * lexic)

Definition at line 721 of file nasl_snmp.c.

722{
724}

References NASL_SNMP_GETNEXT, nasl_snmpv1v2c_get(), and SNMP_VERSION_2c.

Here is the call graph for this function:

◆ nasl_snmpv3_get()

tree_cell * nasl_snmpv3_get ( lex_ctxt * lexic)

Definition at line 832 of file nasl_snmp.c.

833{
835}
static tree_cell * nasl_snmpv3_get_action(lex_ctxt *lexic, u_char action)
Definition nasl_snmp.c:727

References NASL_SNMP_GET, and nasl_snmpv3_get_action().

Here is the call graph for this function:

◆ nasl_snmpv3_get_action()

tree_cell * nasl_snmpv3_get_action ( lex_ctxt * lexic,
u_char action )
static

Definition at line 727 of file nasl_snmp.c.

728{
729 tree_cell *retc = NULL;
730 const char *proto, *authproto, *privproto;
731 char peername[2048];
732 int port, ret;
733 snmpv3_request_t request;
734 snmp_result_t result;
735 char *oid_str;
736 static char *next_oid_str;
737
738 request = g_malloc0 (sizeof (struct snmpv3_request));
739
740 request->action = action;
741 port = get_int_var_by_name (lexic, "port", -1);
742 proto = get_str_var_by_name (lexic, "protocol");
743 request->username = get_str_var_by_name (lexic, "username");
744 request->authpass = get_str_var_by_name (lexic, "authpass");
745
746 oid_str = get_str_var_by_name (lexic, "oid");
747
748 if (action == NASL_SNMP_GETNEXT && oid_str == NULL && next_oid_str != NULL)
749 request->oid_str = next_oid_str;
750 else
751 request->oid_str = oid_str;
752
753 authproto = get_str_var_by_name (lexic, "authproto");
754 request->privpass = get_str_var_by_name (lexic, "privpass");
755 privproto = get_str_var_by_name (lexic, "privproto");
756
757 if (!proto || !request->username || !request->authpass || !request->oid_str
758 || !authproto)
759 {
760 g_free (request);
761 return array_from_snmp_error (-2, "Missing function argument");
762 }
763 if (port < 0 || port > 65535)
764 {
765 g_free (request);
766 return array_from_snmp_error (-2, "Invalid port value");
767 }
768 if (!proto_is_valid (proto))
769 {
770 g_free (request);
771 return array_from_snmp_error (-2, "Invalid protocol value");
772 }
773
774 if (!privproto || !request->privpass)
775 {
776 g_free (request);
777 return array_from_snmp_error (-2, "Missing privproto or privpass");
778 }
779
780 if (!strcasecmp (authproto, "md5"))
781 request->authproto = 0;
782 else if (!strcasecmp (authproto, "sha1"))
783 request->authproto = 1;
784 else
785 {
786 g_free (request);
787 return array_from_snmp_error (-2, "authproto should be md5 or sha1");
788 }
789
790 if (privproto)
791 {
792 if (!strcasecmp (privproto, "des"))
793 request->privproto = 0;
794 else if (!strcasecmp (privproto, "aes"))
795 request->privproto = 1;
796 else
797 {
798 g_free (request);
799 return array_from_snmp_error (-2, "privproto should be des or aes");
800 }
801 }
802
803 g_snprintf (peername, sizeof (peername), "%s:%s:%d", proto,
804 plug_get_host_ip_str (lexic->script_infos), port);
805 request->peername = peername;
806
807 result = g_malloc0 (sizeof (struct snmp_result));
808 ret = snmpv3_get (request, result);
809
810 // Hack the OID string to adjust format. Replace 'iso.' with '.1.'
811 // This Allows to call getnext without an oid, since the last oid
812 // is stored.
813 if (result->oid_str != NULL && g_strstr_len (result->oid_str, 3, "iso"))
814 {
815 next_oid_str = result->oid_str + 2;
816 next_oid_str[0] = '1';
817 result->oid_str = g_strdup (next_oid_str);
818 }
819 else if (result->oid_str != NULL)
820 next_oid_str = result->oid_str;
821
822 /* Free request only, since members are pointers to the nasl lexic context
823 which will be free()'d later */
824 g_free (request);
825
826 retc = array_from_snmp_result (ret, result);
827 destroy_snmp_result (result);
828 return retc;
829}
struct snmpv3_request * snmpv3_request_t
Definition nasl_snmp.c:72
static int snmpv3_get(const snmpv3_request_t request, snmp_result_t result)
SNMPv3 Get query value. snmpget cmd wrapper.
Definition nasl_snmp.c:544
SNMP Request struct for snmp v3.
Definition nasl_snmp.c:61
char * peername
Definition nasl_snmp.c:62
u_char action
Definition nasl_snmp.c:69
char * username
Definition nasl_snmp.c:63
char * oid_str
Definition nasl_snmp.c:66
char * authpass
Definition nasl_snmp.c:64
char * privpass
Definition nasl_snmp.c:65

References snmpv3_request::action, array_from_snmp_error(), array_from_snmp_result(), snmpv3_request::authpass, snmpv3_request::authproto, destroy_snmp_result(), get_int_var_by_name(), get_str_var_by_name(), NASL_SNMP_GETNEXT, snmp_result::oid_str, snmpv3_request::oid_str, snmpv3_request::peername, plug_get_host_ip_str(), snmpv3_request::privpass, snmpv3_request::privproto, proto_is_valid(), struct_lex_ctxt::script_infos, snmpv3_get(), and snmpv3_request::username.

Referenced by nasl_snmpv3_get(), and nasl_snmpv3_getnext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nasl_snmpv3_getnext()

tree_cell * nasl_snmpv3_getnext ( lex_ctxt * lexic)

Definition at line 838 of file nasl_snmp.c.

839{
841}

References NASL_SNMP_GETNEXT, and nasl_snmpv3_get_action().

Here is the call graph for this function:

◆ parse_snmp_error()

void parse_snmp_error ( snmp_result_t result)
static

Parse the snmp error.

Parameters
result[in,out]The result error to be parsed.

Definition at line 367 of file nasl_snmp.c.

368{
369 gchar **res_split, **res_aux;
370
371 res_aux = res_split = g_strsplit (result->name, "\n", 0);
372
373 if (!res_split)
374 return;
375
376 while (res_aux)
377 {
378 /* There is no special reason, we return the whole error message
379 but removing the new line char at the end.
380 */
381 if (*res_aux == NULL)
382 {
383 char *pos;
384
385 if ((pos = strchr (result->name, '\n')) != NULL)
386 *pos = '\0';
387 break;
388 }
389
390 /* Search for the reason */
391 *res_aux = g_strrstr (*res_aux, "Reason: ");
392 if (*res_aux)
393 {
394 g_free (result->name);
395 result->name = g_strdup (*res_aux + 8);
396 break;
397 }
398 res_aux += 1;
399 }
400
401 g_strfreev (res_split);
402 return;
403}

References snmp_result::name.

Referenced by snmpv1v2c_get(), and snmpv3_get().

Here is the caller graph for this function:

◆ proto_is_valid()

int proto_is_valid ( const char * proto)
static

Definition at line 100 of file nasl_snmp.c.

101{
102 if (strcmp (proto, "tcp") && strcmp (proto, "udp") && strcmp (proto, "tcp6")
103 && strcmp (proto, "udp6"))
104 return 0;
105 return 1;
106}

Referenced by nasl_snmpv1v2c_get(), and nasl_snmpv3_get_action().

Here is the caller graph for this function:

◆ snmpv1v2c_get()

int snmpv1v2c_get ( const snmpv1v2_request_t request,
snmp_result_t result )
static

SNMP v1 or v2c Get query value. snmpget cmd wrapper.

param[in] request Contains all necessary information for SNMPv1 or SNMPv2 query. param[out] result Result of query.

Returns
0 if success and result value, -1 otherwise.

Definition at line 466 of file nasl_snmp.c.

467{
468 char *argv[8], *pos = NULL;
469 GError *err = NULL;
470 int sout = 0, serr = 0, ret;
471
472 assert (request);
473 assert (request->peername);
474 assert (request->community);
475 assert (request->oid_str);
476 assert (request->version == SNMP_VERSION_1
477 || request->version == SNMP_VERSION_2c);
478 assert (request->action == NASL_SNMP_GET
479 || request->action == NASL_SNMP_GETNEXT);
480
481 setenv ("MIBS", "", 1);
482
483 argv[0] = (request->action == NASL_SNMP_GET) ? "snmpget" : "snmpgetnext";
484 argv[1] = (request->version == SNMP_VERSION_1) ? "-v1" : "-v2c";
485 argv[2] = "-Oqn";
486 argv[3] = "-c";
487 argv[4] = g_strdup (request->community);
488 argv[5] = g_strdup (request->peername);
489 argv[6] = g_strdup (request->oid_str);
490 argv[7] = NULL;
491 ret = g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL,
492 NULL, NULL, NULL, &sout, &serr, &err);
493 g_free (argv[4]);
494 g_free (argv[5]);
495 g_free (argv[6]);
496
497 if (ret == FALSE)
498 {
499 g_warning ("snmpget: %s", err ? err->message : "Error");
500 if (err)
501 g_error_free (err);
502 return -1;
503 }
504
505 /* As we spawn the process asynchronously, we don't know the exit
506 status of the process. Therefore we need to check for errors in
507 the output.
508 We assume a valid output if there is no errors.
509 */
510 check_spwan_output (serr, result, FD_STDERR_FLAG);
511 if (result->name && result->name[0] != '\0')
512 {
513 parse_snmp_error (result);
514 close (sout);
515 close (serr);
516 return -1;
517 }
518 close (serr);
519 g_free (result->name);
520
521 check_spwan_output (sout, result, FD_STDOUT_FLAG);
522 close (sout);
523
524 /* Remove the last new line char from the result */
525 if ((pos = strchr (result->name, '\0')) != NULL)
526 {
527 pos--;
528 if (pos[0] == '\n')
529 *pos = '\0';
530 }
531
532 return 0;
533}
#define FD_STDERR_FLAG
Definition nasl_snmp.c:40
static void parse_snmp_error(snmp_result_t result)
Parse the snmp error.
Definition nasl_snmp.c:367
static int check_spwan_output(int fd, snmp_result_t result, int fd_flag)
Read data from a file descriptor.
Definition nasl_snmp.c:414

References snmpv1v2_request::action, check_spwan_output(), snmpv1v2_request::community, FD_STDERR_FLAG, FD_STDOUT_FLAG, snmp_result::name, NASL_SNMP_GET, NASL_SNMP_GETNEXT, snmpv1v2_request::oid_str, parse_snmp_error(), snmpv1v2_request::peername, SNMP_VERSION_1, SNMP_VERSION_2c, and snmpv1v2_request::version.

Referenced by nasl_snmpv1v2c_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ snmpv3_get()

int snmpv3_get ( const snmpv3_request_t request,
snmp_result_t result )
static

SNMPv3 Get query value. snmpget cmd wrapper.

param[in] request Contains all necessary information for SNMPv3 query. param[out] result Result of query.

Returns
0 if success and result value, -1 otherwise.

Definition at line 544 of file nasl_snmp.c.

545{
546 char *argv[18], *pos = NULL;
547 GError *err = NULL;
548 int sout = 0, serr = 0, ret;
549
550 assert (request);
551 assert (request->peername);
552 assert (request->username);
553 assert (request->authpass);
554 assert (request->authproto == 0 || request->authproto == 1);
555 assert (request->oid_str);
556 assert (result);
557
558 setenv ("MIBS", "", 1);
559
560 argv[0] = (request->action == NASL_SNMP_GET) ? "snmpget" : "snmpgetnext";
561 argv[1] = "-v3";
562 argv[2] = "-Oqn";
563 argv[3] = "-u";
564 argv[4] = g_strdup (request->username);
565 argv[5] = "-A";
566 argv[6] = g_strdup (request->authpass);
567 argv[7] = "-l";
568 argv[8] = request->privpass ? "authPriv" : "authNoPriv";
569 argv[9] = "-a";
570 argv[10] = request->authproto ? "SHA" : "MD5";
571 if (request->privpass)
572 {
573 argv[11] = g_strdup (request->peername);
574 argv[12] = g_strdup (request->oid_str);
575 argv[13] = "-x";
576 argv[14] = request->privproto ? "AES" : "DES";
577 argv[15] = "-X";
578 argv[16] = g_strdup (request->privpass);
579 argv[17] = NULL;
580 }
581 else
582 {
583 argv[11] = g_strdup (request->peername);
584 argv[12] = g_strdup (request->oid_str);
585 argv[13] = NULL;
586 }
587
588 ret = g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL,
589 NULL, NULL, NULL, &sout, &serr, &err);
590 g_free (argv[4]);
591 g_free (argv[6]);
592 g_free (argv[11]);
593 g_free (argv[12]);
594 if (request->privpass)
595 g_free (argv[16]);
596
597 if (ret == FALSE)
598 {
599 g_warning ("%s: %s", argv[0], err ? err->message : "Error");
600 if (err)
601 g_error_free (err);
602 return -1;
603 }
604
605 check_spwan_output (serr, result, FD_STDERR_FLAG);
606 if (result->name && result->name[0] != '\0')
607 {
608 parse_snmp_error (result);
609 close (sout);
610 close (serr);
611 return -1;
612 }
613 close (serr);
614 g_free (result->name);
615
616 check_spwan_output (sout, result, FD_STDOUT_FLAG);
617 close (sout);
618
619 /* Remove the last new line char from the result */
620 if ((pos = strchr (result->name, '\0')) != NULL)
621 {
622 pos--;
623 if (pos[0] == '\n')
624 *pos = '\0';
625 }
626
627 return 0;
628}

References snmpv3_request::action, snmpv3_request::authpass, snmpv3_request::authproto, check_spwan_output(), FD_STDERR_FLAG, FD_STDOUT_FLAG, snmp_result::name, NASL_SNMP_GET, snmpv3_request::oid_str, parse_snmp_error(), snmpv3_request::peername, snmpv3_request::privpass, snmpv3_request::privproto, and snmpv3_request::username.

Referenced by nasl_snmpv3_get_action().

Here is the call graph for this function:
Here is the caller graph for this function: