Skip to content
Advertisement

C Threaded Sockets – tcp with TLS, Can’t get ip/ether packet headers

thanks for reading this question. Have been working for a while on C sockets – specifically c threaded tcp sockets with tls. Using the Openssl API.

I have been facing an issue for some time now where I can get the source IP and Port – e.g printf("Connection: %s:%dn",inet_ntoa(d->addr.sin_addr), ntohs(d->addr.sin_port));.

The problem is that I need all the data – Ethernet and IP where I can look at source and destination IP’s, MAC addresses, Protocol, TTL and the list goes on.

Tried multiple examples from the web like this from Binary tides

data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , &saddr_size);
unsigned short iphdrlen;

struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen =iph->ihl*4;

memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;

memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;
fprintf(logfile,"   |-Checksum : %dn",ntohs(iph->check));
fprintf(logfile,"   |-Source IP        : %sn",inet_ntoa(source.sin_addr));
fprintf(logfile,"   |-Destination IP   : %sn",inet_ntoa(dest.sin_addr));

But I keep on getting “Junk Data”. Basically the IP’s and other fields are strange and random like.

SSL_read() puts the data into a buffer (the https request basically) so at that point I’m already too late? I tried reading the socket before attempting SSL_Accept(), so reading from an unencrypted socket, I still get the junk data.

Basically any help with:

1) c examples

2) do I need to use BIO?

3) what process do I follow to capture that data

in my main I just loop e.g

for (; ;) {
    memset(&d->addr, 0, sizeof(d->addr));
    d->len = sizeof(d->addr);
    if ( (d->client = accept(d->server, (struct sockaddr*)&d->addr, &d->len)) > 0 ) {
        pthread_create(&connection_thread, NULL, handleGuestConnection, (void *) d);

here is a snippet of the threaded function:

data *d = socketData;

SSL *ssl;
ssl = SSL_new(d->ctx);
SSL_set_fd(ssl, d->client);

int returnStatus = handleGuestSSLAccept(ssl);

switch (returnStatus) {
    case 1: {
        break;
        //Bad Socket
    }
    case 2: {
        char *reply = HTTPHeaderResponse(2);
        write(d->client, reply, strlen(reply));
        break;
        //Redirect
    }
    case 3: {
        char buf[1024] = {0};
        int bytes = SSL_read(ssl, buf, sizeof(buf));
        if ( bytes > 0 ) {
            buf[bytes] = '';
            char *reply = HTTPHeaderResponse(3);
            SSL_write(ssl, reply, strlen(reply));
        }
        break;
        //Good
    }
}

Advertisement

Answer

For anyone looking to achieve a Proxy with a built in firewall – it is not a step 1-10 programming task. You can build a proxy with C/C++ or use Golang like I did – happy to share if you need. In terms of filtering packets I accomplished this by inserting a module written in C into kernel space using insmod. The reason you cannot do this from your application is this – Once a packet passes from Kernel space to UserSpace, Headers are all stripped off. So the only way to capture headers is to insert a module into the kernel space that is triggered every time a packet arrives. tcpdump.org has a few good articles but that would be using their methods, I decided to use my own and went with a kernel module

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement