A simple BGP speaker listen on TCP 0.0.0.0:179, wait for a peer, and print all BGP messages sent/received with BgpFsm.
#include <libbgp/bgp-fsm.h>
#include <libbgp/bgp-config.h>
#include <libbgp/fd-out-handler.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <condition_variable>
#include <thread>
#include <chrono>
#define ROUTER_ID "172.30.0.1"
#define BIND_ADDR INADDR_ANY
#define BIND_PORT 179
#define MY_ASN 65000
bool running = false;
std::condition_variable cv;
std::mutex ticker_mtx;
    fprintf(stderr, "ticker(): ticker started.\n");
    while (true) {
        if (!running) break;
        std::unique_lock<std::mutex> lock(ticker_mtx);
        if (cv.wait_for(lock, std::chrono::seconds(1)) == std::cv_status::timeout) {
        } else break;
    }
    fprintf(stderr, "ticker(): ticker stopped.\n");
}
int main(void) {
    
    int fd_sock = -1, fd_conn = -1;
    struct sockaddr_in server_addr, client_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = BIND_ADDR;
    server_addr.sin_port = htons(BIND_PORT);
    fd_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (fd_sock < 0) {
        fprintf(stderr, "socket(): %s\n", strerror(errno));
        return 1;
    }
    int bind_ret = bind(fd_sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
    if (bind_ret < 0) {
        fprintf(stderr, "bind(): %s\n", strerror(errno));
        close(fd_sock);
        return 1;
    }
    int listen_ret = listen(fd_sock, 1);
    if (listen_ret < 0) {
        fprintf(stderr, "listen(): %s\n", strerror(errno));
        close(fd_sock);
        return 1;
    }
    fprintf(stderr, "waiting for any client...\n");
    char ip_str[INET_ADDRSTRLEN];
    socklen_t caddr_len = sizeof(client_addr);
    fd_conn = accept(fd_sock, (struct sockaddr *) &client_addr, &caddr_len);
    if (fd_conn < 0) {
        fprintf(stderr, "accept(): %s\n", strerror(errno));
        close(fd_sock);
        close(fd_conn);
        return 1;
    }
    inet_ntop(AF_INET, &(client_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
    fprintf(stderr, "accept(): new client from %s.\n", ip_str);
    
    close(fd_sock);
    
    
    
    
    
    
    
    
    
    
    inet_pton(AF_INET, ROUTER_ID, &config.
router_id); 
    
    
    running = true;
    std::thread ticker_thread(ticker, std::ref(fsm));
    uint8_t *read_buffer = (uint8_t *) malloc(65536);
    while (true) {
        ssize_t read_ret = read(fd_conn, read_buffer, 65536);
        if (read_ret < 0) {
            fprintf(stderr, "read(): %s.\n", strerror(errno));
            break;
        }
        if (read_ret == 0) {
            fprintf(stderr, "read(): peer gone.\n");
            break;
        }
        
        int fsm_ret = fsm.
run(read_buffer, (
size_t) read_ret); 
         
        
        if (fsm_ret <= 0 || fsm_ret == 2) break;
    }
    running = false;
    cv.notify_all();
    if (ticker_thread.joinable()) {
        fprintf(stderr, "waiting for the ticker thread to stop...\n");
        ticker_thread.join();
    }
    
    fprintf(stderr, "closing socket & clean up...\n");
    free(read_buffer);
    close(fd_conn);
    return 0;
}