snmp/mib采用子代理模式,编码,部署

0.环境
0.1 编译net-snmp
     cd net-snmp-5.7.2
     ./configure --prefix=/usr/local/snmp

        BEGIN failed--compilation aborted at Makefile.PL line 1.

        make: *** [perlmakefiles] Error 2      
        
    yum install cpan -y
    make && make install
    /usr/local/snmp/sbin/snmpd  启动
    
0.2 直接安装(本文采用直接安装的方式)
    yum install -y net-snmp, net-snmp-devel,net-snmp-perl,net-snmp-utils

    vim /etc/snmp/snmpd.conf    
        master agentx  
        rocommunity public  
        rwcommunity public
    service snmpd restart
    
    service snmpd restart

    
1.验证
1.1 snmpd服务
    vim /etc/snmp/snmpd.conf    
        master agentx  
        rocommunity public  
        rwcommunity public
    service snmpd restart   
    
1.2 启动编写的子代理程序:
  ./snmp_agent_mib &
  提示NET-SNMP version 5.9.3 AgentX subagent connected
  
1.3 mib查询  
  1.3.1  验证方式1:
  
      验证mib文件是否有错(LINUO-ATCA-BOARD-STATUS-MIB.txt):
       snmptranslate -Tp -IR LINUO-ATCA-BOARD-STATUS-MIB::atcaModule  //解析出来说明mib文件没有语法错误之类的
        
        snmpget -v2c -c public localhost 1.3.6.1.4.1.12001.5.1.0
                  SNMPv2-SMI::enterprises.12001.5.1.0 = Gauge32: 2
        
        snmpget -v2c -c public localhost 1.3.6.1.4.1.12001.5.5.1.0
                  SNMPv2-SMI::enterprises.12001.5.5.1.0 = Gauge32: 3
 
  1.3.2 验证方式2:
       安装mib-browse 加载LINUO-ATCA-BOARD-STATUS-MIB.txt后进行查询
2.mib文件

-- LINUO-ATCA-BOARD-STATUS-MIB.my
LINUO-ATCA-BOARD-STATUS-MIB DEFINITIONS ::= BEGIN

    IMPORTS
        OBJECT-GROUP, MODULE-COMPLIANCE, NOTIFICATION-GROUP
            FROM SNMPv2-CONF
        enterprises, OBJECT-TYPE, MODULE-IDENTITY, Unsigned32
            FROM SNMPv2-SMI
        DisplayString
            FROM SNMPv2-TC;

-- Module Identity
-- OID: 1.3.6.1.4.1.12001
    atcaModule MODULE-IDENTITY
        LAST-UPDATED "202310010000Z"  -- Update with actual timestamp
        ORGANIZATION
            "LINUO Corporation"
        CONTACT-INFO
            "Postal: LINUO Corp\nEmail: support@linuo.com"
        DESCRIPTION
            "MIB for ATCA Board Status Monitoring."
        ::= { enterprises 12001 }  -- 1.3.6.1.4.1.12001

-- Top-level OID structure
    linuoAtca OBJECT IDENTIFIER ::= { atcaModule 5 }  -- 1.3.6.1.4.1.12001.5

-- Node 1: atcaCollectionStatus (Unsigned32)
-- OID: 1.3.6.1.4.1.12001.5.1
    atcaCollectionStatus OBJECT-TYPE
        SYNTAX      Unsigned32
        MAX-ACCESS  read-only
        STATUS      current
        DESCRIPTION
            "Status of ATCA board collection."
        ::= { linuoAtca 1 }

-- Subtree for chassis info
    atcaChassis OBJECT IDENTIFIER ::= { linuoAtca 5 }  -- 1.3.6.1.4.1.12001.5.5

-- Node 2: atcaBoardInfoIndex (Unsigned32)
-- OID: 1.3.6.1.4.1.12001.5.5.1
    atcaBoardInfoIndex OBJECT-TYPE
        SYNTAX      Unsigned32
        MAX-ACCESS  read-only
        STATUS      current
        DESCRIPTION
            "Index identifier for ATCA board chassis information."
        ::= { atcaChassis 1 }

END

3.代码(为了方便贴上来集中在一个文件中)

/* add by zhuwei 2025/3/18
 *
 * 安装依赖库(如 Net-SNMP):yum install net-snmp net-snmp-utils
 *                            yum install net-snmp-devel  //相关头文件
 * 编译:gcc -o snmp_agent snmp_agent.c -lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp   //相关库在/usr/lib64
 * 配置文件(/etc/snmp/snmpd.conf):

 * 启动 Agent:./snmp_agent_mib
 * 客户端测试:snmpget -v2c -c public localhost 1.3.6.1.4.1.12001.5.1.0
 * 查看调试日志:net-snmp-config --log-file   
 *               tail -f /var/log/snmpd.log
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <net-snmp/net-snmp-config.h>  // 必须首先包含
#include <net-snmp/types.h>            // 定义 oid、netsnmp_container 等
#include <net-snmp/library/tools.h>    // 提供基础工具函数
#include <net-snmp/library/container.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/net-snmp-includes.h>

extern int netsnmp_running;

const char *app_name = "snmp_agent_mib";
static int reconfig = 0;


// 定义 atcaCollectionStatus 的 OID
 const oid atcaCollectionStatus_oid[] = { 1, 3, 6, 1, 4, 1, 12001, 5, 1 };

// 定义 atcaBoardInfoIndex 的 OID
const oid atcaBoardInfoIndex_oid[] = { 1, 3, 6, 1, 4, 1, 12001, 5, 5, 1 };

#ifdef __GNUC__
    #define UNUSED __attribute__((unused))
#else
    #define UNUSED
#endif


RETSIGTYPE stop_server(UNUSED int a) 
{
    puts("捕捉到信号 SIGTERM/SIGINT");
    netsnmp_running = 0;
}

#ifdef SIGHUP
RETSIGTYPE hup_handler(int sig)
{
    puts("捕捉到信号 SIGHUP");
    reconfig = 1;
    signal(SIGHUP, hup_handler);
}
#endif


void reg_sig()
{
#ifdef SIGTERM
    signal(SIGTERM, stop_server);
#endif
#ifdef SIGINT
    signal(SIGINT, stop_server);
#endif
#ifdef SIGHUP
    signal(SIGHUP, hup_handler);
#endif
}

int handle_atcaCollectionStatus(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
);
int handle_atcaBoardInfoIndex(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
);


void register_oids() 
{
    netsnmp_handler_registration *reg;

    // 注册 atcaCollectionStatus
    reg = netsnmp_create_handler_registration(
        "atcaCollectionStatus",
        handle_atcaCollectionStatus, // 回调函数
        atcaCollectionStatus_oid,
        OID_LENGTH(atcaCollectionStatus_oid),
        HANDLER_CAN_RONLY
    );
    
    if(MIB_REGISTERED_OK != netsnmp_register_scalar(reg))
    {
        printf("atcaCollectionStatus register fail \n");
    }

    // 注册 atcaBoardInfoIndex(类似逻辑)
    reg = netsnmp_create_handler_registration(
        "atcaBoardInfoIndex",
        handle_atcaBoardInfoIndex, // 回调函数
        atcaBoardInfoIndex_oid,
        OID_LENGTH(atcaBoardInfoIndex_oid),
        HANDLER_CAN_RONLY
    );

    if(MIB_REGISTERED_OK != netsnmp_register_scalar(reg))
    {
        printf("atcaBoardInfoIndex register fail \n");
    }
}


unsigned int read_hardware_status() {
    // 通过 ioctl 或内存映射读取硬件寄存器
   // int fd = open("/dev/atca_device", O_RDONLY);
    unsigned int status = 2;
    //ioctl(fd, ATCA_GET_STATUS, &status);
   // close(fd);
    return status;
}

int handle_atcaCollectionStatus(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
) {
    unsigned int status = 0;
    switch (reqinfo->mode) {
        case MODE_GET:
            // 从设备读取数据(示例值)
            status = read_hardware_status(); // 自定义数据采集函数
            snmp_set_var_typed_value(
                requests->requestvb,
                ASN_UNSIGNED, // 数据类型与 MIB 一致
                &status,
                sizeof(status)
            );
            break;
        default:
            // 不支持的操作(如 SET)
            return SNMP_ERR_GENERR;
    }
    return SNMP_ERR_NOERROR;
}


unsigned int read_hardware_index() {
    // 通过 ioctl 或内存映射读取硬件寄存器
    //int fd = open("/dev/atca_device", O_RDONLY);
    unsigned int status = 3;
    //ioctl(fd, ATCA_GET_STATUS, &status);
    //close(fd);
    return status;
}


int handle_atcaBoardInfoIndex(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
) {
    unsigned int status = 0;
    switch (reqinfo->mode) {
        case MODE_GET:
            // 从设备读取数据(示例值)
            status = read_hardware_index(); // 自定义数据采集函数
            snmp_set_var_typed_value(
                requests->requestvb,
                ASN_UNSIGNED, // 数据类型与 MIB 一致
                &status,
                sizeof(status)
            );
            break;
        default:
            // 不支持的操作(如 SET)
            return SNMP_ERR_GENERR;
    }
    return SNMP_ERR_NOERROR;
}

static void usage(const char *prog)
{
    fprintf(stderr,
            "USAGE: %s [OPTIONS]\n"
            "\n"
            "OPTIONS:\n", prog);

    fprintf(stderr,
            "  -d\t\t\tdump all traffic\n"
            "  -D TOKEN[,...]\tturn on debugging output for the specified "
            "TOKENs\n"
            "\t\t\t   (ALL gives extremely verbose debugging output)\n"
            "  -f\t\t\tDo not fork() from the calling shell.\n"
            "  -h\t\t\tdisplay this help message\n"
            "  -H\t\t\tdisplay a list of configuration file directives\n"
            "  -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
    snmp_log_options_usage("\t\t\t  ", stderr);
#ifndef DISABLE_MIB_LOADING
    fprintf(stderr,
            "  -m MIB[:...]\t\tload given list of MIBs (ALL loads "
            "everything)\n"
            "  -M DIR[:...]\t\tlook in given list of directories for MIBs\n");
#endif /* DISABLE_MIB_LOADING */
#ifndef DISABLE_MIB_LOADING
    fprintf(stderr,
            "  -P MIBOPTS\t\tToggle various defaults controlling mib "
            "parsing:\n");
    snmp_mib_toggle_options_usage("\t\t\t  ", stderr);
#endif /* DISABLE_MIB_LOADING */
    fprintf(stderr,
            "  -v\t\t\tdisplay package version number\n"
            "  -x TRANSPORT\tconnect to master agent using TRANSPORT\n");
    exit(1);
}

static void version(void)
{
    fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
    exit(0);
}


int main (int argc, char **argv)
{
    int arg;
    char* cp = NULL;
    int dont_fork = 0, do_help = 0;

    while ((arg = getopt(argc, argv, "dD:fhHL:"
    #ifndef DISABLE_MIB_LOADING
                       "m:M:"
    #endif /* DISABLE_MIB_LOADING */
                       "n:"
    #ifndef DISABLE_MIB_LOADING
                       "P:"
    #endif /* DISABLE_MIB_LOADING */
                       "vx:")) != EOF) 
    {
        switch (arg) {
        case 'd':
          
          //netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_LOG_FILE, "/var/log/snmpd.log");
          //netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_DEBUG_LEVEL, 3);
          netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,NETSNMP_DS_LIB_DUMP_PACKET, 1);
          
          break;

        case 'D':
          debug_register_tokens(optarg);
          snmp_set_do_debugging(1);
          break;

        case 'f':
          dont_fork = 1;
          break;

        case 'h':
          usage(argv[0]);
          break;

        case 'H':
          do_help = 1;
          break;

        case 'L':
          if (snmp_log_options(optarg, argc, argv) < 0) {
            exit(1);
          }
          break;

    #ifndef DISABLE_MIB_LOADING
        case 'm':
          if (optarg != NULL) {
            setenv("MIBS", optarg, 1);
          } else {
            usage(argv[0]);
          }
          break;

        case 'M':
          if (optarg != NULL) {
            setenv("MIBDIRS", optarg, 1);
          } else {
            usage(argv[0]);
          }
          break;
    #endif /* DISABLE_MIB_LOADING */

        case 'n':
          if (optarg != NULL) {
            app_name = optarg;
            netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                  NETSNMP_DS_LIB_APPTYPE, app_name);
          } else {
            usage(argv[0]);
          }
          break;

    #ifndef DISABLE_MIB_LOADING
        case 'P':
          cp = snmp_mib_toggle_options(optarg);
          if (cp != NULL) {
            fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
            usage(argv[0]);
          }
          break;
    #endif /* DISABLE_MIB_LOADING */

        case 'v':
          version();
          break;

        case 'x':
          if (optarg != NULL) {
            netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                  NETSNMP_DS_AGENT_X_SOCKET, optarg);
          } else {
            usage(argv[0]);
          }
          break;

        default:
          fprintf(stderr, "invalid option: -%c\n", arg);
          usage(argv[0]);
          break;
        }
    }
    if (do_help) 
    {
      netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
    }
    else
    {    
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,NETSNMP_DS_AGENT_ROLE, 1);

#if 0
        if (!dont_fork) 
        {
            if (netsnmp_daemonize(1, snmp_stderrlog_status()) != 0)
                exit(1);
        }            
#endif         
        SOCK_STARTUP;
    }
    
    init_agent(app_name);
    
    register_oids();
    
    //load app_name.conf
    init_snmp(app_name);
    
    
    if (do_help) 
    {
        fprintf(stderr, "Configuration directives understood:\n");
        read_config_print_usage("  ");
        exit(0);
    }    
    
    netsnmp_running = 1;
    reg_sig();    
    
    while(netsnmp_running) 
    {
        if (reconfig) 
        {
            free_config();
            read_configs();
            reconfig = 0;
        }
        agent_check_and_process(1);
    }    

    snmp_shutdown(app_name);
    
    shutdown_agent();
    
    SOCK_CLEANUP;
    
    exit(0);
    
}


4.Makefile

# Makefile for SNMP Agent (snmp_agent_mib)

# Compiler and flags
CC = gcc
CFLAGS = -g -Wall -I/usr/include/net-snmp
LDFLAGS += -L/usr/local/lib -Wl,-rpath=/usr/local/lib
LDFLAGS += -lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp

# Targets
TARGET = snmp_agent_mib
SRC = snmp_agent_mib.c

all: $(TARGET)

$(TARGET): $(SRC)
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

clean:
    rm -f $(TARGET)

.PHONY: all clean

5.代码直接拷贝编译运行即能使用

   需要set的tx可以自行添加.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

# [RPA] 使用八爪鱼进行高效网页数据采集

在许多行业中&#xff0c;数据是核心资产。然而&#xff0c;虽然许多网站的文本内容可以免费访问&#xff0c;但手动一条一条采集&#xff0c;不仅耗时耗力&#xff0c;还容易出错。这种情况下&#xff0c;使用自动化工具来提高采集效率就显得尤为重要。本文将介绍 八爪鱼 这一…

IDI_APPLICATION 与 IDC_ARROW资源存放在工程的哪个路径?

书籍&#xff1a;《windows程序设计(第五版)》的开始 环境&#xff1a;visual studio 2022 内容&#xff1a;HELLOWIN程序 说明&#xff1a;以下内容大部分来自腾讯元宝。 IDI_APPLICATION 和 IDC_ARROW 是 ​Windows 系统预定义的资源标识符&#xff0c;它们并不以文件形式…

算法 | 优化算法比较

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 优化算法 ‌一、主流优化算法分类‌1‌、传统梯度类算法‌2‌、启发式算…

腾讯云HAI1元体验:轻松调用DeepSeek-R1模型搭建网站

前言 随着云计算和人工智能技术的不断发展&#xff0c;构建和部署智能化的网页变得越来越简单。腾讯云提供的HAI&#xff08;人工智能平台&#xff09;和DeepSeek&#xff08;智能搜索引擎&#xff09;服务&#xff0c;能帮助开发者快速搭建智能化网页&#xff0c;提升用户体验…

AI Agent系列(七) -思维链(Chain of Thought,CoT)

AI Agent系列【七】 前言一、CoT技术详解1.1 CoT组成1.2 CoT的特点 二、CoT的作用三、CoT的好处四、CoT适用场景五、CoT的推理结构 前言 思维链(Chain of Thought,CoT)&#xff0c;思维链就是一系列中间的推理步骤(a series of intermediate reasoning steps)&#xff0c;通过…

【一起来学kubernetes】21、Secret使用详解

Secret 的详细介绍 Secret 是 Kubernetes 中用于存储和管理敏感信息&#xff08;如密码、令牌、密钥等&#xff09;的资源对象。Secret的设计目的是为了安全地存储和传输敏感信息&#xff0c;如密码、API密钥、证书等。这些信息通常不应该直接硬编码在配置文件或镜像中&#x…

opencv中stitch图像融合

openv版本: opencv249 vs &#xff1a;2010 qt : 4.85 #include "quanjing.h"#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <open…

1201. 【高精度练习】蜜蜂路线

题目描述 一只蜜蜂在图5.1-2所示的数字蜂房上爬动&#xff0c;已知它只能从标号小的蜂房爬到标号大的相邻蜂房&#xff0c; 现在问你&#xff1a;蜜蜂从蜂房M开始爬到蜂房N&#xff0c;l≤M 输入 M&#xff0c;N的值。 输出 一个数表示爬行路线种数。 样例输入 1 14 样…

linux下基本命令和扩展命令(安装和登录命令、文件处理命令、系统管理相关命令、网络操作命令、系统安全相关命令、其他命令)欢迎补充噢

基本命令 ls: 列出目录内容 ls&#xff1a;列出当前目录内容ls -l&#xff1a;以长格式列出&#xff08;显示详细信息&#xff09;ls -a&#xff1a;显示隐藏文件ls -lh&#xff1a;以易读格式显示文件大小 pwd: 显示当前工作目录 pwd&#xff1a;显示当前目录的绝对路径 cd:…

《C++11 基于CAS无锁操作的atomic原子类型》

count; count--; 我们知道&#xff0c;/--操作并不是原子性的&#xff0c;其实对应三条汇编指令来完成的。 读取&#xff1a;从内存中把变量的值读取到寄存器修改&#xff1a;在寄存器里将变量的值1/-1写入&#xff1a;把修改后的值写入到内存 在单线程环境下&#xff0c;这…

C++常用多线程模式

文章目录 1. Fork - Join模式2. Producer - Consumer模式3. Readers - Writers模式4. Work Thread模式5. Actor模式6、 Pipeline模式概述应用场景C实现示例代码解释 1. Fork - Join模式 原理&#xff1a;将一个大任务分解为多个子任务&#xff0c;这些子任务在不同的线程中并行…

【时时三省】(C语言基础)习题2 scanf函数

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 用下面的scanf函数输入数据&#xff0c;使a 3&#xff0c;b 7&#xff0c;x 8.5&#xff0c;y 71.82&#xff0c;c1 A&#xff0c;c2 x在键盘上应如何输入? 分析第一个 scanf 函数&…

微信小程序计算属性与监听器:miniprogram-computed

小程序框架没有提供计算属性相关的 api &#xff0c;但是官方为开发者提供了拓展工具库 miniprogram-computed。 该工具库提供了两个功能&#xff1a; 计算属性 computed监听器 watch 一、安装 miniprogram-computed 在项目的根目录下&#xff0c;使用如下命令&#xff0c;…

SOFAStack-00-sofa 技术栈概览

SOFAStack 前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 &#x1f31f; 核心项目 ⚙️ SOFABoot GitHub: sofastack/sofa…

企业模板(QiMoban)是一个专注于企业官网搭建的高效平台

企业模板(QiMoban.com )是一个专注于为企业提供高效、低成本网站建设解决方案的平台&#xff0c;主要面向中小企业和创业者。其核心优势在于帮助用户快速搭建企业官网&#xff0c;提升品牌形象并拓展业务渠道。以下是关于企业模板(QiMoban.com )的详细分析&#xff1a; 适用场…

Oracle 数据库安全评估(DBSAT)简明过程

下载DBSAT 从这里下载。 实际是从MOS中下载&#xff0c;即&#xff1a;Oracle Database Security Assessment Tool (DBSAT) (Doc ID 2138254.1)。 最新版本为3.1.0 (July 2024)&#xff0c;名为dbsat.zip&#xff0c;近45MB。 $ ls -lh dbsat.zip -rw-rw-r-- 1 oracle oins…

【Linux 维测专栏 1 -- Hung Task 分析与验证】

文章目录 Linux Hung Task 简介1. Hung Task 概述2. D 状态与 Hung Task3. Hung Task 的工作原理4. Hung Task 的配置5. Hung Task 的典型输出6. Hung Task 的应用场景7. kernel 配置7.1 编译选项7.2 参数控制7.3 验证方法4. 扩展接口 8. 注意事项 Linux Hung Task 简介 1. Hu…

GCC 预定义宏:解锁编译器的隐藏信息

GCC 预定义宏&#xff1a;解锁编译器的隐藏信息 在 GCC 编译器中&#xff0c;有许多内置的预定义宏&#xff0c;它们可以提供编译环境的信息&#xff0c;如文件名、行号、时间、版本等。这些宏在调试、日志记录、条件编译等场景中非常有用。本文将介绍常见的 GCC 预定义宏&…

公链开发费用及其构成内容详析

在区块链技术迅速发展的今天&#xff0c;公链&#xff08;Public Blockchain&#xff09;作为去中心化、不可篡改、高安全性的重要应用之一&#xff0c;在金融、供应链、游戏等多个领域得到了广泛应用。然而&#xff0c;开发一条公链并非易事&#xff0c;它不仅需要高度专业技能…

Java求101-200之间有多少素数

Java学习笔记 今天看教程看到了这个题&#xff0c;对于一名打过算法竞赛的选手还是很简单的&#xff0c;但由于之前是c组的&#xff0c;所以用java写一下&#xff0c;练一下手。 代码&#xff1a; package com.itheima.hello;public class Test1 {public static void main(S…