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