I'm learning c++ and coming from a Network Engineer background, and it is fun for me to program something that I'm familiar with it on the network side. I started creating a BGP speaker.
Here is my environment:
[mybgp]<------------TCP-Port-179------------->[bird]
Here is my current code.
#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(): %s\n", strerror(errno));
return 1;
}
return serverSocket;
}
int createBind(const int &serverSocket, sockaddr_in &serverAddr){
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = BIND_PORT;
serverAddr.sin_addr.s_addr = INADDR_ANY;
int bind_ret = bind(serverSocket, (sockaddr *) &serverAddr, sizeof(serverAddr));
// if (bind(serverSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == -1) {
// std::cerr << "Can't bind to ip/port";
// return -2;
// }
if (bind_ret < 0) {
fprintf(stderr, "bind(): %s\n", strerror(errno));
close(serverSocket);
return 1;
}
return bind_ret;
}
int createListener(const int &serverSocket){
int amount;
int listen_ret = listen(serverSocket, 3);
if (listen_ret < 0) {
fprintf(stderr, "listen(): %s\n", strerror(errno));
close(serverSocket);
return 1;
}
return listen_ret;
}
int acceptConnect(const int &serverSocket, sockaddr_in &clientAddr){
fprintf(stderr, "waiting for any client...\n");
char ip_str[INET_ADDRSTRLEN];
socklen_t caddr_len = sizeof(clientAddr);
int serverConn = accept(serverSocket, (sockaddr *) &clientAddr, &caddr_len);
if (serverConn < 0) {
fprintf(stderr, "accept(): %s\n", strerror(errno));
close(serverSocket);
close(serverConn);
return 1;
}
inet_ntop(AF_INET, &(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(&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("%s\n",buffer );
close(serverSocket);
return 0;
}
My current state is that I'm able to:
- Create Socket
- Bind the Socket to IP
- Listening
- Accept a Single Connection(Single thread for now)
- Received Data
At step 5, I received a gibberish TCP Message from the BGP speaker(BIRD). Knowing how the BGP Protocol works, this TCP message is in an OPEN Message Format. To establish BGP peering, mybgp and bird need to go back and for with different types of messages and agree.
For me to be able to accomplish this peering, I have to:
- Decode[Received Package]
- Encode[send package]
How can I decode/encode the TCP packet so I can start the process of BGP peering.