Кодирование / декодирование пакетов TCP

#c #bgp

#c #bgp

Вопрос:

Я изучаю c и имею опыт работы сетевым инженером, и мне интересно программировать что-то, с чем я знаком, на сетевой стороне. Я начал создавать динамик BGP.

Вот моя среда:

[mybgp]<———— TCP-порт-179————->[ птица]

Вот мой текущий код.

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

#define BIND_ADDR INADDR_ANY
#define BIND_PORT htons(179)

int createServerSocket(){
    //Create Socket
    int serverSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
    if (serverSocket < 0) {
        fprintf(stderr, "socket(): %sn", strerror(errno));
        return 1;
    }
    return serverSocket;
}

int createBind(const int amp;serverSocket, sockaddr_in amp;serverAddr){
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = BIND_PORT;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    int bind_ret = bind(serverSocket, (sockaddr *) amp;serverAddr, sizeof(serverAddr));
    // if (bind(serverSocket, (struct sockaddr*) amp;serverAddr, sizeof(serverAddr)) == -1) {
    //     std::cerr << "Can't bind to ip/port";
    //     return -2;
    // }
    if (bind_ret < 0) {
        fprintf(stderr, "bind(): %sn", strerror(errno));
        close(serverSocket);
        return 1;
    }
    return bind_ret;
}

int createListener(const int amp;serverSocket){
    int amount;
    int listen_ret = listen(serverSocket, 3);
    if (listen_ret < 0) {
        fprintf(stderr, "listen(): %sn", strerror(errno));
        close(serverSocket);
        return 1;
    }
    return listen_ret;

}

int acceptConnect(const int amp;serverSocket, sockaddr_in amp;clientAddr){
    fprintf(stderr, "waiting for any client...n");
    char ip_str[INET_ADDRSTRLEN];
    socklen_t caddr_len = sizeof(clientAddr);
    int serverConn = accept(serverSocket, (sockaddr *) amp;clientAddr, amp;caddr_len);
    if (serverConn < 0) {
        fprintf(stderr, "accept(): %sn", strerror(errno));
        close(serverSocket);
        close(serverConn);
        return 1;
    }
    inet_ntop(AF_INET, amp;(clientAddr.sin_addr), ip_str, INET_ADDRSTRLEN);
    fprintf(stderr, "accept(): new client from %s.n", ip_str);
    return serverConn;

}

int main(){
    //Create Socket
    int serverSocket = createServerSocket();
    // declare server and client address struct
    // bind socket.
    sockaddr_in serverAddr, clientAddr;
    memset(amp;serverAddr, 0, sizeof(serverAddr));
    int bind_ret = createBind(serverSocket, serverAddr);
    
    // listening for connection
    int listen_ret = createListener(serverSocket);
    int serverConn = acceptConnect(serverSocket, clientAddr);
    // we only do one at a time, no new client.
    char buffer[4048] = {0};
    char valread;
    valread = read( serverConn , buffer, 4048); 
    printf("%sn",buffer );
    close(serverSocket);
    return 0;
}
 

Мое текущее состояние таково, что я могу:

  1. Создать сокет
  2. Привязать сокет к IP
  3. Прослушивание
  4. Принять одно соединение (пока один поток)
  5. Полученные данные

На шаге 5 я получил тарабарское TCP-сообщение от BGP-спикера (BIRD). Зная, как работает протокол BGP, это TCP-сообщение находится в формате ОТКРЫТОГО сообщения. Чтобы установить пиринг BGP, mybgp и bird должны вернуться назад и для разных типов сообщений и согласовать.

Чтобы я мог выполнить этот пиринг, я должен:

  1. Декодирование [полученного пакета]
  2. Кодирование [отправка пакета]

Как я могу декодировать / кодировать TCP-пакет, чтобы я мог начать процесс пиринга BGP.

Комментарии:

1. Можете ли вы уточнить, в чем заключается ваш точный вопрос?

2.Есть ли у вас реализация BGP, которую вы используете, суть показывает, что тривиальный / номинальный сокет обменивается данными через TCP / IP, и из данного кода не видно использования такого протокола, как BGP. смотрите также github.com/Nat-Lab/libbgp github.com/Nat-Lab/libbgp/blob/master/src/bgp-packet.cc

3. BGP — это протокол, который работает поверх TCP, и теперь у меня есть TCP-соединение, работающее на TCP-порту 179. Мне нужно иметь возможность читать сообщение, отправленное одноранговым узлом BGP, и иметь возможность создавать свое собственное сообщение BGP, чтобы затем, если оба устройства согласны с параметрами в пакете, устройства установили пиринг BGP.

4. Итак, если вы можете получать данные, вы внедряете анализатор и загружаете в него свои данные. Я что-то упускаю?

5. Теперь, когда я перенес ваш код, мы видим, что помимо использования read вместо recv , вы допустили ошибку, о которой я упоминал выше. Цитируя справочную страницу для read , read() пытается прочитать до подсчета байтов из файлового дескриптора fd в буфер, начиная с buf . Поскольку вы неправильно учитываете возвращаемое значение, вы понятия не имеете, что вы на самом деле прочитали. Может быть 0 байт. Может быть 4048 байт. Может быть что-то среднее. Ввод этого, printf("%sn",buffer ); не убедившись, что то, что у вас есть, завершено (и строка с нулевым завершением), приводит к непредсказуемому результату.