{"id":13631430,"url":"https://github.com/WeOps-Lab/topology-scanner","last_synced_at":"2025-04-17T22:30:55.222Z","repository":{"id":79215661,"uuid":"531389171","full_name":"WeOps-Lab/topology-scanner","owner":"WeOps-Lab","description":"网络拓扑自动扫描工具","archived":false,"fork":false,"pushed_at":"2023-04-18T02:35:00.000Z","size":40,"stargazers_count":84,"open_issues_count":4,"forks_count":14,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-01T22:48:31.860Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WeOps-Lab.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-09-01T06:18:00.000Z","updated_at":"2024-07-19T14:20:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"783bb61e-40a0-4bfc-baaf-1045ac6560a0","html_url":"https://github.com/WeOps-Lab/topology-scanner","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WeOps-Lab%2Ftopology-scanner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WeOps-Lab%2Ftopology-scanner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WeOps-Lab%2Ftopology-scanner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WeOps-Lab%2Ftopology-scanner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WeOps-Lab","download_url":"https://codeload.github.com/WeOps-Lab/topology-scanner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223768469,"owners_count":17199352,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T22:02:25.069Z","updated_at":"2024-11-08T23:30:43.594Z","avatar_url":"https://github.com/WeOps-Lab.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Topology-Scanner\n\n\u003cimg src=\"https://wedoc.canway.net/imgs/img/嘉为蓝鲸.jpg\" \u003e\n\n\nTopology-Scanner是WeOps团队免费开放的一个网络拓扑自动扫描模块，可以自动发现网络设备的类型、网络设备之间的互联关系\n\n#### 更多资料/工具包下载可见“蓝鲸 S-mart市场”\nhttps://bk.tencent.com/s-mart/application/282/detail\n\n#### 更多问题欢迎添加“小嘉”微信，加入官方沟通群\n\n\u003cimg src=\"https://wedoc.canway.net/imgs/img/小嘉.jpg\" width=\"30%\" height=\"30%\"\u003e\n\n\n## 使用方式\n\n```\njava -jar ./topology-scanner.jar --config_path=./config/\n```\n\n## 拓扑发现算法\n### 常规算法\n常规算法即为 AFT 算法，是基于 AFT 建立链路。算法原理如下 ：\n由于在发现设备的过程中，设备的ip和所在的子网都会被记录下来。在确定拓扑时， 根据发现过程中记录下的每个子网，首先确定交换域，交换域的定义为：交换域建模为一棵无向树G=(D,E). D是交换域内所有结点(网络设备)的集合.E是设备端口之间的直接连接集合, S表示所有交换机的集合,H表示所有主机的集合,D=S+H.(路由器算作主机)。最终对交换域进行合并，根据AFT 建立链路。参数运行配置中如果开启了使用ARP表，那还会再根据ARP 表来补充未发现的链路。\n在发现过程中需要获取或扫描网络设备上的以下几个表： IPAdress 表，IFTable 表， ARP 表， FDB 表。\n\n### CDP算法\n适用于支持CDP协议的网络设备，如思科设备。是基于 CDP 协议来发现链路。CDP 算法原理如下 ：根据 CDP 协议从所有发现出来的设备中选出具有CDP 协议功能的设备，这是通过snmp 探测器去采集设备上的CDP 表，由此来判断是否有CDP协议能力。在利用CDP发现链路时，不需要只有路由、路由交换才具有的特征, 而且只能发现网络设备之间的连接。通过CDP表和IFTabel 表结合来确定设备的拓扑链路。由于CDP 的局限性，对拓扑发现结果精确度会影响。\n在发现过程中需要获取或扫描网络设备上的以下几个表： CDP 表,  IFTable 表。\n\n### 桥接算法\n桥接算法是根据网络设备上的多个表相结合的方式来发现链路。桥接算法比其它的几个拓扑算法要复杂一些，参与计算的表要多。在发现的所有设备中，首先根据网络设备的 FDB 表来定义域，在划分好多个域后，确定域内的设备的连接，结合 FDB 表，IFTable 表、IPAdress 表 、basePortTable表 确定设备之间的转发与交换路径。通过STP 表生成一个无环有向图，即最终的拓扑链路。\n在发现过程中需要获取或扫描网络设备上的以下几个表： basePortTable 表,  STP 表, FDB 表,IPAdress 表,  IFTable 表。\n\n### LLDP 算法\nLLDP 算法是根据 LLDP 表来确定网络设备的链路。算法原理如下 ： 从发现的所有设备中筛选出具有 LLDP 功能的设备。这步是通过 snmp 探测器获取 设备上的 LLDP 表来判断的。由于具有LLDP 协议的只能是交换机或路由器等网络设备，像防火墙，主机这种类型的设备如果没有开启LLDP协议，是不参与拓扑计算的。通过LLDP 表和 IFTable 表结合，来确定设备的拓扑。\n在发现过程中需要获取或扫描网络设备上的以下几个表： LLDP 表 , IFTable 表。\n\n\n## 配置说明\n\n### 拓扑发现请求参数文件(request.json)\n\n#### ips\n\n[全网发现] 模式时，为必填项。核心设备的ip, 多个ip 用逗号隔开。range 参数选填,起过滤作用。eg: 192.168.1.0,192.168.2.0\n\n[子网发现] 模式时，为选填项。子网ip地址和掩码，必须成对。可多个，逗号隔开。 若为子网发现， ips 参数和range 参数不能同时为空。详见子网发现方式。 eg: 192.168.1.0,255.255.255.0,\n192.168.2.0,255.255.255.0\n\n#### hop\n\n搜索深度，必填\n\n#### group\n\n使用SNMP V2协议时必填，SNMP V2的团体名，多个团体名用逗号隔开 eg: public,Huawei-public 当使用SNMP V3协议时可不填\n\n#### range\n\n[全网发现] 模式时，为选填项。Ip 范围,起过滤作用，可以多对，每对之间用; 号分隔，由开始和结束组成。eg: 192.168.1.0,192.168.1.255;192.168.2.0,192.168.2.255\n\n[子网发现] 模式时，为选填项。若发现方式为子网发现，ips 参数和range 参数不能同时为空。Ip 范围,相当于范围发现，与子网发现结果取并集。Ip范围可以多对，每对由开始和结束组成，每对之间用;号分隔，eg:\n192.168.1.0,192.168.1.255;192.168.2.0,192.168.2.255\n\n#### way\n\n发现方式： 0-全网发现 1-子网发现\n\n#### algory\n\n发现算法：\n\n* 0-常规算法\n* 1-CDP算法\n* 2-LLDP 算法\n* 3-桥接算法\n\n#### version\n\nSNMP 版本号，\n\n* 2-SNMP 版本1或2\n* 3-SNMP 版本3\n\n#### v3\n\n当使用SNMP V1/V2版本时可不填，当使用V3时，可填写如下JSON\n\n```\n[{\n    username：用户名, 根据 safeLevel 级别选填,\n    safeLevel：安全级别,必须为以下三者之一\n              NOAUTH_NOPRIV  // 无认证无加密\n              AUTH_NOPRIV    // 有认证无加密\n              AUTH_PRIV      // 有认证有加密,\n    protocol: 认证协议, 根据 safeLevel 级别选填, 必须为以下两者之一\n              AuthMD5     // MD5\n              AuthSHA     // SHA,\n    pwd:     认证密码，根据 safeLevel 级别选填 ,\n    encrypt:      加密协议，根据 safeLevel 级别选填，必须为以下5者之一\n                PrivDES       // DES 加密\n                Priv3DES      // 3DES 加密\n                PrivAES128    // AES 128位\n                PrivAES192    // AES 192位\n                PrivAES256    // AES 256位,\n    encryptPwd： 加密密码,根据 safeLevel 级别选填,\n    content: 上下文,\n    port: SNMP 端口号\n}]\n```\n\n示例参数如下\n\n```\n[\n          {\n               \"userName\":\"\",                        //用户名\n               \"safeLevel\":\"NOAUTH_NOPRIV\",          //安全级别\n               \"protocol\":\"\",                        //认证协议\n               \"pwd\":\"\",                             //认证密码\n               \"encrypt\":\"\",                         //加密协议\n               \"encryptPwd\":\"\",                     //加密密码\n               \"context\":\"\",                        //上下文\n               \"port\":\"161\"                        //端口\n           }\n  ]\n\n```\n\n### 拓扑发现运行的参数文件(discovery.properties)\n\n参数    |类型    |说明|\n----|------|---|\ndiscovery.pool.max    |int|    拓扑发现线程池最大线程数，默认：256\ndiscovery.pool.min|    int|    拓扑发现线程池最小线程数，默认：50\ndiscovery.pool.queue.size|    int|    拓扑发现线程池队列，默认：500\ndiscovery.min.maskbit    |int    |扫描的最小子网掩码位数,对子网扫描不起作用,默认：16\ndiscovery.ping.batch    |int|    Ping 批次大小\ndiscovery.ping.enable    |bool|    使用snmp探测前是否使用ping 来初次过滤，默认：false\ndiscovery.ping.delay    |int|    Ping 重试延迟时间，单位毫秒，默认：1000\ndiscovery.ping.retry    |int|    Ping 重试次数。默认：1\ndiscovery.device.timeout    |int|    单个设备发现超时时间，单位分钟，默认：3\nlink.distinct    |bool    |两条设备之间如果存在多条链路，是否去重。默认：false\nlink.remove.cycle    |bool    |设备之间链路，是否过滤掉环路，默认：true\nlink.use.arp    |bool|    设备链路时，是否使用ARP 表建立链路。默认：false\nlink.cross.subnet    |bool|    设备链路时，是否跨子网。默认：true\ndiscovery.snmp.retry|    int    |Snmp 探测时，单次报文重试次数。默认：1\ndiscovery.snmp.timeout    |int|    Snmp 探测时，单次报文的超时时间。单位毫秒，默认：1500\ndiscovery.snmp.detect.retry.number|    int    |单个ip 在snmp 探测失败时，重试次数，默认：2\n\n### 设备oid 与设备类型字典文件(systemoid.xml/getterConfig.xml)\n\n为了能更精确的采集网络设备上的各种表，特别是 FDB 表， 由于设备类型不同，FDB 表采集所用的 oid 也有差别。 通过外部 getterConfig.xml 文件来指定某种设备采集的SNMP 采集器。默认\ngetterConfig.xml 配置的getters 子节点为空。 getterConfig.xml 配置如下示例：\n\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\n\u003cgetterConfig\u003e\n    \u003cgetters\u003e\n        \u003cgetter sysOid=\"1.3.6.1.4.1.6339\" name=\"DefaultSNMPGetter\"\u003e\u003c/getter\u003e\n        \u003cgetter sysOid=\"1.3.6.1.4.1.63394\" name=\"Huawei2300Getter\"\u003e\u003c/getter\u003e\n    \u003c/getters\u003e\n\u003c/getterConfig\u003e\n\n```\n\nsysOid: 设备的oid name: 采集的SNMP 采集器。\n\n可选的采集器如下：\n\n#### 思科\n\n厂商|    采集器    |说明\n---|------|---|\nCisco924Getter|    思科924型设备采集器\nCisco10700Getter    |思科10700型设备采集器\nCiscoGetter    |思科设备通用采集器\n\n#### 华三\n\n厂商|    采集器    |说明\n---|------|---|\nH3cS10508Getter    |华三 S10508 型设备采集器\nH3CGetter    |华三设备通用采集器\n\n#### 华为\n\n厂商|    采集器    |说明\n---|------|---|\nHuawei2300Getter    |华为2300 型设备采集器\nHuawei3026cGetter    |华为3026c 型设备采集器\nHuawei6500Getter    |华为 6500型设备采集器\nHuawei6506Getter    |华为 6506 型设备采集器\nHuawei8500Getter    |华为8500型设备采集器\nHuawei9303Getter    |华为9303型设备采集器\nHuaweiS2403hGetter    |华为S2403h 型设备采集器\nHuaweiGetter|    华为设备通用采集器\n\n### 输出结果说明\n\n#### device\n\n字段    |字段    |类型    |说明\n----|-------|-------|----\nid    |string|    设备id,唯一标识符|\ncenterX|    float    |设备在拓扑图中的 x 坐标\ncenterY    |float|    设备在拓扑图中的 y 坐标\nip    |string    |设备ip\ndevName    |string|    设备名称\ndevFirstType|    string|    设备一级类型\ndevSecondType|    string    |设备二级类型\noid    |string 设备系统| oid\nhop|    int    |搜索深度|\n\n#### link\n\n字段    |字段    |类型    |说明\n----|-------|-------|----\nlinkId    |string    |链路向量id\nsx|    float    |链路向量起始 x 坐标\nsy    |float|    链路向量起始 y 坐标\nex|    float    |链路向量结束 x 坐标\ney    |float    |链路向量结束 y 坐标\nflinkId    |string|    设备到设备的id\ndeviceDestIfIdx    |string    |目标设备接口索引\ndeviceSrcIfIdx    |string|    源设备接口索引\ndeviceDestIfIdxName|    string|    目标设备接口名称\ndeviceSrcIfIdxName    |string|    源设备接口名称\nstartIp    |string    |源设备ip\nendIp    |string    |目标设备ip\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWeOps-Lab%2Ftopology-scanner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FWeOps-Lab%2Ftopology-scanner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWeOps-Lab%2Ftopology-scanner/lists"}