正则表达式在过滤交换机lldp信息的应用举例

发布于:2024-10-10 ⋅ 阅读:(23) ⋅ 点赞:(0)
#include <iostream>
#include <string>
#include <regex>
#include <vector>
#include <unordered_map>
#include <sstream>
#include <unistd.h> // For usleep

// 假设存在的 LOG_INFO 和 LOG_WARNING 函数
#define LOG_INFO(...) std::cout << __VA_ARGS__ << std::endl
#define LOG_WARNING(...) std::cerr << __VA_ARGS__ << std::endl

class SwitchMonitor {
public:
    void lldpNeighborInfoHandle();

private:
    void writeExchangeSerialData(const std::string& command) {
        std::cout << "Sending command: " << command << std::endl;
    }

    std::string readExchangeSerialData() {

        return R"(
            GigabitEthernet0/0/20 has 1 neighbor(s):
            Neighbor index :1
            Chassis type   :MAC address
            Chassis ID     :1001-0114-0101
            Port ID type   :Interface name
            Port ID        :hhhhh1
            System name    :HY
            Expired time   :3s
            
            GigabitEthernet0/0/21 has 2 neighbor(s):
            Neighbor index :1
            Chassis type   :MAC address
            Chassis ID     :1004-0114-0102
            Port ID type   :Interface name
            Port ID        :CM300-PID-0001
            System name    :HhXS
            Expired time   :3s
			
            Neighbor index :2
            Chassis type   :MAC address
            Chassis ID     :1004-0113-0103
            Port ID type   :Interface name
            Port ID        :CM300-PID-0001
            System name    :HYXS
            Expired time   :3s
			
			
			GigabitEthernet0/0/22 has 1 neighbor(s):

			Neighbor index :1

			Chassis type   :MAC address

			Chassis ID     :3cc7-867d-efff

			Port ID type   :Interface name

			Port ID        :GigabitEthernet0/0/2

			Port description    :GigabitEthernet0/0/2

			System name         :FutureMatrix

			System description  :hhhhhhh

			FutureMatrix Versatile Routing Platform Software

			VRP (R) software, Version 5.170 (S5735 V200R022C00SPC500)

			System capabilities supported   :bridge router

			System capabilities enabled     :bridge router

			Management address type  :ipv4

			Management address value :192.168.1.253


			Expired time   :95s



			Port VLAN ID(PVID)  :1

			VLAN name of VLAN  1:VLAN 0001



			Auto-negotiation supported    :Yes

			Auto-negotiation enabled      :Yes

			OperMau   :speed(100)/duplex(Full)



			Power port class            :PD

			PSE power supported         :No

			PSE power enabled           :No

			PSE pairs control ability   :No

			Power pairs                 :Unknown

			Port power classification   :Unknown



			Link aggregation supported:Yes

			Link aggregation enabled :No

			Aggregation port ID      :0



			Maximum frame Size       :10232
			
			GigabitEthernet0/0/23 has 1 neighbor(s):
            Neighbor index :1
            Chassis type   :MAC address
            Chassis ID     :1001-0114-0104
            Port ID type   :Interface name
            Port ID        :S5730
            System name    :XJ
            Expired time   :3s
			
			
			GigabitEthernet0/0/24 has 2 neighbor(s):
            Neighbor index :1
            Chassis type   :MAC address
            Chassis ID     :1004-0114-0105
            Port ID type   :Interface name
            Port ID        :PID-0005
            System name    :xj2
            Expired time   :3s
			
            Neighbor index :2
            Chassis type   :MAC address
            Chassis ID     :1004-0113-0106
            Port ID type   :Interface name
            Port ID        :PID-0006
            System name    :xj3
            Expired time   :3s

        )";
    }

    struct MacAddressInfo {
        std::string deviceType;
        std::string identifier;
        std::string board;
        std::string slot;
        std::string interface;
    };

    MacAddressInfo parseMacAddress(const std::string& mac) {
        return {"DeviceType", "Identifier", "Board", "Slot", "Interface"};
    }

    std::vector<std::unordered_map<std::string, std::string>> contents_;
};

void SwitchMonitor::lldpNeighborInfoHandle() {
    std::string responseConnectInfo;
    writeExchangeSerialData("display lldp neighbor\n");
	int totalCount = 0;
    while (true) {
        usleep(10 * 1000); // 10 毫秒
        responseConnectInfo = readExchangeSerialData();

        if (responseConnectInfo.empty()) {
            break; // 如果没有回复,退出循环
        } else {
			std::regex pattern(R"(GigabitEthernet0/0/(\d+) has (\d+) neighbor\(s\):([\s\S]*?)(?=GigabitEthernet0/0/\d+|\Z|$))");
            std::smatch matches;
            std::string::const_iterator it(responseConnectInfo.cbegin());

            while (std::regex_search(it, responseConnectInfo.cend(), matches, pattern)) {
                std::string portToFind = matches[1].str();
                int neighborCount = std::stoi(matches[2].str());
                std::string neighborsDetails = matches[3].str();

				LOG_INFO("############ GigabitEthernet0/0/" << portToFind << " with " << neighborCount << " neighbor(s)" << "    neighborsDetails: " << neighborsDetails);
				
                if (neighborCount == 1) {
                    std::regex singleNeighborPattern(R"(Neighbor index\s*:(\d+)[\s\S]*?Chassis ID\s*:\s*(\S+))");
                    std::smatch singleNeighborMatches;

                    if (std::regex_search(neighborsDetails, singleNeighborMatches, singleNeighborPattern)) {
                        std::string macToFindCurrent = singleNeighborMatches[2].str();
                        LOG_INFO("Single Neighbor Chassis ID: " << macToFindCurrent);

                        MacAddressInfo foundInfo = parseMacAddress(macToFindCurrent);
                        if (foundInfo.deviceType.empty()) {
                            LOG_WARNING("Protocol MAC device, parse MAC failed, MAC: " << macToFindCurrent);
                        } else {
                                //xxxxx 处理信息
                        }
                    }
                } else if (neighborCount > 1) {
                    std::regex neighborPattern(R"(Neighbor index\s*:(\d+)[\s\S]*?Chassis ID\s*:\s*(\S+))");
                    std::smatch neighborMatches;
                    std::string::const_iterator nIt(neighborsDetails.cbegin());

                    while (std::regex_search(nIt, neighborsDetails.cend(), neighborMatches, neighborPattern)) {
                        std::string macToFindCurrent = neighborMatches[2].str();
                        LOG_INFO("multy Neighbor Chassis ID: " << macToFindCurrent);

                        MacAddressInfo foundInfo = parseMacAddress(macToFindCurrent);
                        if (foundInfo.deviceType.empty()) {
                            LOG_WARNING("Protocol MAC device, parse MAC failed, MAC: " << macToFindCurrent);
                        } else {
                         //xxxxx 处理信息
                        }

                        // 更新迭代器到下一个邻居
                        nIt = neighborMatches.suffix().first;
                    }
                }
				totalCount++;

				LOG_INFO("--------------------------------------------------------------------------------------- totalCount" << totalCount);
                // 移动迭代器到当前匹配的末尾以搜索下一个接口
                it = matches.suffix().first;
            }
			
			usleep(10);
        }
    }
}

int main() {
    SwitchMonitor monitor;
    monitor.lldpNeighborInfoHandle();
	
	LOG_INFO("$$$$$$$$$$$$$$$$$$$$ end");
    return 0;
}

经过了70w次近1小时的测试,,没有问题。
在这里插入图片描述