在C中使用Zlib对ip/tcp有效负载进行压缩



我正在尝试压缩数据包负载。我正在读取pcap文件。但是,压缩后,大多数数据包的大小都会增加。我将有效载荷长度解析为源长度,将有效载荷解析为in_data。为什么压缩后的大小会变大?

我知道可以添加6个字节,但一些具有1300或2300字节的有效载荷也会增加压缩大小。如果您查看输出,您可以看到压缩大小是如何增加的。

代码为:

#include <string.h>  // for strlen
#include <assert.h>
#include <stdlib.h>
#include <pcap.h>
#include <stdint.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netinet/ether.h>
#include <string.h>
#include<sys/types.h>
#include <zlib.h>
#include "packet_structures.h"
#include "tls.h"
#include "ipzip_ipm.h"
void callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet) {
//printf("Packet size : %u n", pkthdr->len);
pq_ip_hdr* ip = (pq_ip_hdr*) (packet + sizeof (pq_eth_hdr));
pq_tcp_hdr* tcp = (pq_tcp_hdr*) (packet + sizeof (pq_eth_hdr) + sizeof ( pq_ip_hdr));
tls_Handshake_header* tls = (tls_Handshake_header*) (packet + sizeof (pq_eth_hdr) + sizeof ( pq_ip_hdr) + sizeof (pq_tcp_hdr));

int ip_len, tcp_len;
const u_char *payload;
static int p_count = 1;

ip_len = ip->hdr_len * 4;
tcp_len = (((const u_char*) ip)[ip_len + 12] >> 4) * 4;

int payload_length = pkthdr->caplen - (14 + ip_len + tcp_len);
int total_headers_size = 14 + ip_len + tcp_len;
payload = total_headers_size + packet;
switch (ip->protocol) {
case 6:
switch (tls->Handshake__type) {
case 22:
printf("packet[%d]", p_count);
compress_data(payload, payload_length);//calling compressing function
break;
}
}
p_count++;
}
void compress_data(void* in_data, size_t payload_length) {
const size_t BUFSIZE = 128 * 1024;
uint8_t temp_buffer[BUFSIZE];
uLong size[payload_length+1];
uLong s = compressBound(temp_buffer);
z_stream com_stream;
com_stream.zalloc = Z_NULL;
com_stream.zfree = Z_NULL;
com_stream.opaque = Z_NULL;
com_stream.avail_in = (uInt) payload_length;
com_stream.next_in = (Bytef *) in_data;
com_stream.avail_out = s;
com_stream.next_out = (Bytef *) temp_buffer;
while (com_stream.avail_in != 0) {
deflateInit(&com_stream, Z_BEST_COMPRESSION);
deflate(&com_stream, Z_FINISH);
deflateEnd(&com_stream);
printf("Uncompressed size is: %lu ||", com_stream.total_in);
printf("Compressed size is: %lu ||", com_stream.total_out);
float c_size = ((float) (com_stream.total_in - com_stream.total_out) / (float) com_stream.total_in) * 100;
printf("compressed Percentage: %.2f%% n", c_size);

}

}
int main(int argc, char** argv) {
char *device;
pcap_t *handle;
char error_buffer[100];
handle = pcap_open_offline("packet.pcap", error_buffer);
pcap_loop(handle, -1, callback, NULL);
}````
**output** :
packet[2729]Uncompressed size is: 517 ||Compressed size is: 384 ||compressed Percentage: 25.73% 
packet[2740]Uncompressed size is: 1360 ||Compressed size is: 1371 ||compressed Percentage: 1356378297306447872.00% 
packet[2741]packet[2755]Uncompressed size is: 4291 ||Compressed size is: 4302 ||compressed Percentage: 429893825096318976.00% 
packet[2756]packet[3462]Uncompressed size is: 517 ||Compressed size is: 393 ||compressed Percentage: 23.98% 
packet[3469]Uncompressed size is: 1360 ||Compressed size is: 1371 ||compressed Percentage: 1356378297306447872.00% 
packet[3470]packet[3521]Uncompressed size is: 517 ||Compressed size is: 378 ||compressed Percentage: 26.89% 
packet[3529]Uncompressed size is: 1360 ||Compressed size is: 1371 ||compressed Percentage: 1356378297306447872.00% 
packet[3530]packet[3836]Uncompressed size is: 659 ||Compressed size is: 670 ||compressed Percentage: 2799202397811900416.00% 
packet[3978]packet[4134]Uncompressed size is: 517 ||Compressed size is: 395 ||compressed Percentage: 23.60% 
packet[4136]Uncompressed size is: 2720 ||Compressed size is: 2731 ||compressed Percentage: 678189148653223936.00% 
packet[4137]packet[4155]Uncompressed size is: 517 ||Compressed size is: 405 ||compressed Percentage: 21.66% 
packet[4157]Uncompressed size is: 2720 ||Compressed size is: 2731 ||compressed Percentage: 678189148653223936.00% 
packet[4158]packet[4206]Uncompressed size is: 517 ||Compressed size is: 405 ||compressed Percentage: 21.66% 
packet[4208]Uncompressed size is: 517 ||Compressed size is: 406 ||compressed Percentage: 21.47% 
packet[4212]Uncompressed size is: 517 ||Compressed size is: 406 ||compressed Percentage: 21.47% 
packet[4216]Uncompressed size is: 517 ||Compressed size is: 406 ||compressed Percentage: 21.47% 
packet[4220]Uncompressed size is: 517 ||Compressed size is: 405 ||compressed Percentage: 21.66% 
packet[4224]Uncompressed size is: 517 ||Compressed size is: 406 ||compressed Percentage: 21.47% 
packet[4226]Uncompressed size is: 2720 ||Compressed size is: 2731 ||compressed Percentage: 678189148653223936.00% 

结果显示的开销最多为11个字节。这与zlib在不可压缩数据的情况下的开销相匹配。引用有关技术细节的官方文件:最大膨胀系数:

在最坏的情况下,其他块类型会扩展数据,收缩会回落到存储(未压缩(块。因此,对于deflateInit((、compress((和compress2((使用的默认设置,唯一的扩展是每16KB块5个字节的开销(约0.03%(,加上整个流的一次性开销6个字节

因此,压缩行为与预期一致。

然而,错误的是您对压缩百分比的计算,它不能处理输出站点大于有效负载大小的情况。相反,它会导致无符号整数下溢——对话将浮动除了从无符号整数中计算浮点值外,还必须在减去输出和输入大小之前完成。

最新更新