C线程套接字 - 使用TLS的tcp,无法获取ip / ether数据包标头

时间:2017-12-17 23:36:11

标签: c linux sockets tcp openssl

感谢您阅读此问题。已经在C套接字上工作了一段时间 - 特别是带有tls的c线程tcp套接字。使用Openssl API。

我一直面临一个问题,现在我可以获得源IP和端口 - 例如printf("Connection: %s:%d\n",inet_ntoa(d->addr.sin_addr), ntohs(d->addr.sin_port));

问题在于我需要所有数据 - 以太网和IP,我可以查看源和目标IP,MAC地址,协议,TTL和列表。

从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 : %d\n",ntohs(iph->check));
fprintf(logfile,"   |-Source IP        : %s\n",inet_ntoa(source.sin_addr));
fprintf(logfile,"   |-Destination IP   : %s\n",inet_ntoa(dest.sin_addr));

但我继续获得"垃圾数据"。基本上,IP和其他领域都是奇怪和随机的。

SSL_read()将数据放入缓冲区(基本上是https请求),所以那时我已经太晚了? 我尝试在尝试SSL_Accept()之前尝试读取套接字,所以从未加密的套接字读取,我仍然得到垃圾数据。

基本上任何帮助:

1)c例子

2)我是否需要使用BIO?

3)我将遵循哪些流程来捕获该数据

在我的主要内容我只是循环,例如

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);

这是一个线程函数的片段:

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] = '\0';
            char *reply = HTTPHeaderResponse(3);
            SSL_write(ssl, reply, strlen(reply));
        }
        break;
        //Good
    }
}

2 个答案:

答案 0 :(得分:0)

在此代码中:

sock_raw

{{1}}是一个提示。你需要一个名为" raw socket"的东西,它允许你访问某个级别的底层数据包(取决于你的平台,可能包括以太网数据包级别,或者只是IP)。

参考文献:LinuxWindows

答案 1 :(得分:-1)

对于任何希望使用内置防火墙实现代理的人来说,这不是1-10步编程任务。您可以使用C / C ++构建代理或像我一样使用Golang - 如果您需要,很乐意分享。在过滤数据包方面,我通过使用insmod将用C编写的模块插入内核空间来实现这一点。您无法从您的应用程序执行此操作的原因是 - 一旦数据包从内核空间传递到UserSpace,标题都将被删除。因此,捕获标头的唯一方法是将模块插入到每次数据包到达时触发的内核空间。 tcpdump.org有一些很好的文章,但是会使用他们的方法,我决定使用自己的,并使用内核模块