<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "haka/ipv4.h"

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

#include <haka/log.h>
#include <haka/error.h>


static bool ipv4_flatten_header(struct vbuffer *payload, size_t hdrlen)
{
	struct vsubbuffer header_part;
	if (!vbuffer_sub(payload, 0, hdrlen, &header_part)) {
		return false;
	}

	if (!vsubbuffer_flatten(&header_part)) {
		return false;
	}

	return true;
}

struct ipv4 *ipv4_dissect(struct packet *packet)
{
	struct ipv4 *ip = NULL;
	struct vbuffer *payload;
	struct {
#ifdef HAKA_LITTLEENDIAN
		uint8    hdr_len:4;
		uint8    version:4;
#else
		uint8    version:4;
		uint8    hdr_len:4;
#endif
	} hdrlen;

	assert(packet);
	payload = packet_payload(packet);

	if (!vbuffer_checksize(payload, sizeof(struct ipv4_header))) {
		error(L"invalid packet size");
		return NULL;
	}

	ip = malloc(sizeof(struct ipv4));
	if (!ip) {
		error(L"memory error");
		return NULL;
	}

	ip->packet = packet;
	ip->invalid_checksum = false;

	if (!payload) {
		assert(check_error());
		free(ip);
		return NULL;
	}

	/* extract ip header len */
	*(uint8 *)&hdrlen = vbuffer_getbyte(payload, 0);

	if (!ipv4_flatten_header(payload, hdrlen.hdr_len << IPV4_HDR_LEN_OFFSET)) {
		assert(check_error());
		free(ip);
		return NULL;
	}

	ip->payload = vbuffer_extract(payload, hdrlen.hdr_len << IPV4_HDR_LEN_OFFSET, ALL, false);
	if (!ip->payload) {
		assert(check_error());<commit_msg>Fix ipv4 issue when packet contains some padding<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "haka/ipv4.h"

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

#include <haka/log.h>
#include <haka/error.h>


static bool ipv4_flatten_header(struct vbuffer *payload, size_t hdrlen)
{
	struct vsubbuffer header_part;
	if (!vbuffer_sub(payload, 0, hdrlen, &header_part)) {
		return false;
	}

	if (!vsubbuffer_flatten(&header_part)) {
		return false;
	}

	return true;
}

struct ipv4 *ipv4_dissect(struct packet *packet)
{
	struct ipv4 *ip = NULL;
	struct vbuffer *payload;
	struct {
#ifdef HAKA_LITTLEENDIAN
		uint8    hdr_len:4;
		uint8    version:4;
#else
		uint8    version:4;
		uint8    hdr_len:4;
#endif
	} hdrlen;

	assert(packet);
	payload = packet_payload(packet);

	if (!vbuffer_checksize(payload, sizeof(struct ipv4_header))) {
		error(L"invalid packet size");
		return NULL;
	}

	ip = malloc(sizeof(struct ipv4));
	if (!ip) {
		error(L"memory error");
		return NULL;
	}

	ip->packet = packet;
	ip->invalid_checksum = false;

	if (!payload) {
		assert(check_error());
		free(ip);
		return NULL;
	}

	/* extract ip header len */
	*(uint8 *)&hdrlen = vbuffer_getbyte(payload, 0);

	if (!ipv4_flatten_header(payload, hdrlen.hdr_len << IPV4_HDR_LEN_OFFSET)) {
		assert(check_error());
		free(ip);
		return NULL;
	}

	/* extract the ip data, we cannot just take everything that is after the header
	 * as the packet might contains some padding.
	 */
	ip->payload = vbuffer_extract(payload, hdrlen.hdr_len << IPV4_HDR_LEN_OFFSET,
			ipv4_get_len(ip)-(hdrlen.hdr_len << IPV4_HDR_LEN_OFFSET), false);
	if (!ip->payload) {
		assert(check_error());
{'fraction_non_alphanumeric': 0.13381088825214899, 'fraction_numerical': 0.01518624641833811, 'mean_word_length': 4.281391830559758, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '333254', 'n_tokens_mistral': 1394, 'n_tokens_neox': 1315, 'n_words': 337}