Packet relay server in c

  • Thread starter ArifulHossain tuhin
  • Start date
A

ArifulHossain tuhin

I need to write a packet relay server which will have the following functionality:

1.It will listen on multiple ports(udp/tcp). Upon receiving packet it will manipulate the packets without knowing anything about the contents of the packets.

2.When manipulation ends, it will forward the packets to a specified ip/port interface.

So it will work as a relay. Any suggestion about the software? If any open source implementation is available which does a similar job, will be very helpful.

Thanks in advance.
 
K

Kleuske

I need to write a packet relay server which will have the following
functionality:

1.It will listen on multiple ports(udp/tcp). Upon receiving packet it
will manipulate the packets without knowing anything about the contents
of the packets.

2.When manipulation ends, it will forward the packets to a specified
ip/port interface.

So it will work as a relay. Any suggestion about the software? If any
open source implementation is available which does a similar job, will
be very helpful.

Thanks in advance.

Off-topic. Blablabla...

http://sourceforge.net/projects/echovnc/
 
M

Markus Wichmann

I need to write a packet relay server which will have the following
functionality:

Off-topic here since out-of-focus of the standard. However, assuming BSD
socket API is used...
1.It will listen on multiple ports(udp/tcp).

That means just multiple sockets and select().
Upon receiving packet it will manipulate the packets without knowing
anything about the contents of the packets.

Dump your manipulations into this function:

static void manip(unsigned char* packet, size_t len)
{
//when called, a packet was received of length len
}

static struct {
int type;
unsigned short port;
} config[] = {
{SOCK_STREAM, 80},
{SOCK_DGRAM, 53},
};

static int sockets[sizeof config / sizeof *config];

int main(void)
{
unsigned int i;
struct sockaddr_in sa;
int max;
fd_set sock_set;
sa.sin_family = AF_INET;
sa.sin_addr = INADDR_ANY;
max = -1;

for (i = 0; i < sizeof config / sizeof *config; i++)
{
sockets = socket(AF_INET, config.type, 0);
if (sockets < 0) {
perror("socket failed");
return 111;
}
sa.sin_port = htons(config.port);
if (bind(sockets, (struct sockaddr*)&sa, sizeof sa)) {
perror("bind failed");
return 111;
}
if (listen(sockets, SOMAXCONN)) {
perror("listen failed");
return 111;
}
if (max < sockets) max = sockets;
}

for (;;) {
FD_ZERO(&sock_set);
for (i = 0; i < sizeof sockets / sizeof *sockets; i++)
FD_SET(sockets, &sock_set);
select(max + 1, &sock_set, NULL, NULL, NULL);
for (i = 0; i < sizeof sockets / sizeof *sockets; i++)
if (FD_ISSET(sockets, &sock_set)) {
char buf[1500];
ssize_t rc;
int readsock;
if (config.type == SOCK_STREAM)
readsock = accept(sockets, NULL, 0);
else readsock = sockets;
if (readsock < 0) {
perror("accept failed");
return 111;
}
rc = recv(readsock, buf, sizeof buf, 0)
if (rc < 0) {
perror("recv failed");
return 111;
}
manip(buf, rc);
if (config.type == SOCK_STREAM)
close(readsock);
}
}
}


2.When manipulation ends, it will forward the packets to a specified
ip/port interface.

TCP or UDP? Either way, you just create yet another socket, but you
don't bind() it, you connect() it to the target address and then send
the stuff after manip() finished.
So it will work as a relay. Any suggestion about the software? If any
open source implementation is available which does a similar job,
will be very helpful.

Ha! It will also by the way do an NAT. A real NAT would need to listen
to the control connection, too, to relay answers.
Thanks in advance.

HTH,
Markus
 
C

Chad

I need to write a packet relay server which will have the following
functionality:

Off-topic here since out-of-focus of the standard. However, assuming BSD
socket API is used...
1.It will listen on multiple ports(udp/tcp).

That means just multiple sockets and select().
Upon receiving packet it will manipulate the packets without knowing
anything about the contents of the packets.

Dump your manipulations into this function:

static void manip(unsigned char* packet, size_t len)
{
     //when called, a packet was received of length len

}

static struct {
    int type;
    unsigned short port;} config[] = {

    {SOCK_STREAM, 80},
    {SOCK_DGRAM, 53},

};

static int sockets[sizeof config / sizeof *config];

int main(void)
{
    unsigned int i;
    struct sockaddr_in sa;
    int max;
    fd_set sock_set;
    sa.sin_family = AF_INET;
    sa.sin_addr = INADDR_ANY;
    max = -1;

    for (i = 0; i < sizeof config / sizeof *config; i++)
    {
        sockets = socket(AF_INET, config.type, 0);
        if (sockets < 0) {
            perror("socket failed");
            return 111;
        }
        sa.sin_port = htons(config.port);
        if (bind(sockets, (struct sockaddr*)&sa, sizeof sa)) {
            perror("bind failed");
            return 111;
        }
        if (listen(sockets, SOMAXCONN)) {
            perror("listen failed");
            return 111;
        }
        if (max < sockets) max = sockets;
    }

    for (;;) {
        FD_ZERO(&sock_set);
        for (i = 0; i < sizeof sockets / sizeof *sockets; i++)
             FD_SET(sockets, &sock_set);
        select(max + 1, &sock_set, NULL, NULL, NULL);
        for (i = 0; i < sizeof sockets / sizeof *sockets; i++)
            if (FD_ISSET(sockets, &sock_set)) {
                char buf[1500];
                ssize_t rc;
                int readsock;
                if (config.type == SOCK_STREAM)
                    readsock = accept(sockets, NULL, 0);
                else readsock = sockets;
                if (readsock < 0) {
                    perror("accept failed");
                    return 111;
                }
                rc = recv(readsock, buf, sizeof buf, 0)
                if (rc < 0) {
                    perror("recv failed");
                    return 111;
                }
                manip(buf, rc);
                if (config.type == SOCK_STREAM)
                    close(readsock);
            }
    }

}
2.When manipulation ends, it will forward the packets to a specified
ip/port interface.

TCP or UDP? Either way, you just create yet another socket, but you
don't bind() it, you connect() it to the target address and then send
the stuff after manip() finished.
So it will work as a relay. Any suggestion about the software? If any
open source implementation is available which does a similar job,
will be very helpful.

Ha! It will also by the way do an NAT. A real NAT would need to listen
to the control connection, too, to relay answers.


Thanks in advance.


2/10.

I would have given this 1, but like, even though it's not topical,
it's still written in C.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top