#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;
}
Мое текущее состояние таково, что я могу:
- Создать сокет
- Привязать сокет к IP
- Прослушивание
- Принять одно соединение (пока один поток)
- Полученные данные
На шаге 5 я получил тарабарское TCP-сообщение от BGP-спикера (BIRD). Зная, как работает протокол BGP, это TCP-сообщение находится в формате ОТКРЫТОГО сообщения. Чтобы установить пиринг BGP, mybgp и bird должны вернуться назад и для разных типов сообщений и согласовать.
Чтобы я мог выполнить этот пиринг, я должен:
- Декодирование [полученного пакета]
- Кодирование [отправка пакета]
Как я могу декодировать / кодировать 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 );
не убедившись, что то, что у вас есть, завершено (и строка с нулевым завершением), приводит к непредсказуемому результату.