bgp协议实现通告

简单 BGP C 程序,让 客户端和服务端在程序内部打印 BGP 握手状态和 UPDATE 通告状态,无需外部抓包。示例依然最简化,仅用于学习和实验。


完整示例:simple_bgp_status.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BGP_PORT 179
#define BUF_SIZE 1024

// BGP 消息类型
#define BGP_OPEN     1
#define BGP_UPDATE   2
#define BGP_KEEPALIVE 4

void send_open(int sock) {
    char buf[BUF_SIZE];
    memset(buf, 0, sizeof(buf));
    // Marker
    for(int i=0;i<16;i++) buf[i] = 0xff;
    buf[16] = 19; // length
    buf[17] = BGP_OPEN;
    buf[18] = 4;  // version
    buf[19] = 0;  // my AS high
    buf[20] = 0;  // my AS low
    buf[21] = 0;  // hold time high
    buf[22] = 90; // hold time low
    buf[23] = 0; buf[24] = 0; buf[25] = 0; buf[26] = 1; // BGP identifier
    write(sock, buf, 27);
    printf("[BGP] Sent OPEN message\n");
}

void send_update(int sock) {
    char buf[BUF_SIZE];
    memset(buf,0,sizeof(buf));
    for(int i=0;i<16;i++) buf[i]=0xff;
    buf[16] = 23; // length
    buf[17] = BGP_UPDATE;
    buf[18] = 0; buf[19] = 0; // withdrawn routes length
    buf[20] = 0; buf[21] = 0; // path attribute length
    buf[22] = 24; // prefix length
    buf[23] = 192; buf[24]=168; buf[25]=100; buf[26]=0; // prefix
    write(sock, buf, 27);
    printf("[BGP] Sent UPDATE message\n");
}

void recv_message(int sock) {
    char buf[BUF_SIZE];
    int n = read(sock, buf, BUF_SIZE);
    if(n <= 0){
        printf("[BGP] Connection closed or error\n");
        return;
    }
    unsigned char type = buf[17];
    if(type == BGP_OPEN)
        printf("[BGP] Received OPEN message\n");
    else if(type == BGP_UPDATE)
        printf("[BGP] Received UPDATE message\n");
    else if(type == BGP_KEEPALIVE)
        printf("[BGP] Received KEEPALIVE message\n");
    else
        printf("[BGP] Received unknown message type: %d\n", type);
}

int main(int argc, char *argv[]) {
    if(argc != 3){
        printf("Usage: %s <peer_ip> <mode:server/client>\n", argv[0]);
        return 1;
    }

    char *peer_ip = argv[1];
    int is_server = strcmp(argv[2], "server") == 0;

    int sock, conn;
    struct sockaddr_in addr;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0) { perror("socket"); return 1; }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(BGP_PORT);
    inet_pton(AF_INET, peer_ip, &addr.sin_addr);

    if(is_server){
        if(bind(sock, (struct sockaddr*)&addr, sizeof(addr))<0){ perror("bind"); return 1;}
        listen(sock,1);
        printf("[BGP] Waiting for peer connection...\n");
        conn = accept(sock, NULL, NULL);
        if(conn<0){ perror("accept"); return 1;}
        printf("[BGP] Peer connected\n");
    } else {
        sleep(1);
        conn = sock;
        if(connect(sock, (struct sockaddr*)&addr, sizeof(addr))<0){ perror("connect"); return 1;}
        printf("[BGP] Connected to peer %s\n", peer_ip);
    }

    // 握手阶段
    send_open(conn);
    recv_message(conn);

    // 通告阶段
    send_update(conn);
    recv_message(conn);

    close(conn);
    if(is_server) close(sock);

    printf("[BGP] Session closed\n");
    return 0;
}

编译运行

gcc -o simple_bgp_status simple_bgp_status.c
  • NodeA(Server):

./simple_bgp_status 10.0.0.2 server
  • NodeB(Client):

./simple_bgp_status 10.0.0.1 client

特点

  1. 自动打印状态

    • [BGP] Sent OPEN message

    • [BGP] Received OPEN message

    • [BGP] Sent UPDATE message

    • [BGP] Received UPDATE message

  2. 无需 tcpdump,可直接在终端观察两边 BGP 状态。

  3. 可扩展

    • 后续可以增加 KEEPALIVE 定时器。

    • 后续可以增加多条路由通告。

posted on 2025-09-09 15:25  吃草的青蛙  阅读(8)  评论(0)    收藏  举报

导航