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
特点
-
自动打印状态:
-
[BGP] Sent OPEN message -
[BGP] Received OPEN message -
[BGP] Sent UPDATE message -
[BGP] Received UPDATE message
-
-
无需 tcpdump,可直接在终端观察两边 BGP 状态。
-
可扩展:
-
后续可以增加 KEEPALIVE 定时器。
-
后续可以增加多条路由通告。
-
浙公网安备 33010602011771号