esp_packet_t implements packet_t interface
This should allow to avoid unnecessary cloning of packet data.
This commit is contained in:
+90
-52
@@ -40,14 +40,9 @@ struct private_esp_packet_t {
|
|||||||
esp_packet_t public;
|
esp_packet_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source address
|
* Raw ESP packet
|
||||||
*/
|
*/
|
||||||
host_t *src;
|
packet_t *packet;
|
||||||
|
|
||||||
/**
|
|
||||||
* Destination address
|
|
||||||
*/
|
|
||||||
host_t *dst;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Payload of this packet
|
* Payload of this packet
|
||||||
@@ -59,19 +54,73 @@ struct private_esp_packet_t {
|
|||||||
*/
|
*/
|
||||||
u_int8_t next_header;
|
u_int8_t next_header;
|
||||||
|
|
||||||
/**
|
|
||||||
* Raw packet data
|
|
||||||
*/
|
|
||||||
chunk_t packet_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward declaration for clone()
|
||||||
|
*/
|
||||||
|
static private_esp_packet_t *esp_packet_create_empty(packet_t *packet);
|
||||||
|
|
||||||
|
METHOD(packet_t, set_source, void,
|
||||||
|
private_esp_packet_t *this, host_t *src)
|
||||||
|
{
|
||||||
|
return this->packet->set_source(this->packet, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD2(esp_packet_t, packet_t, get_source, host_t*,
|
||||||
|
private_esp_packet_t *this)
|
||||||
|
{
|
||||||
|
return this->packet->get_source(this->packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(packet_t, set_destination, void,
|
||||||
|
private_esp_packet_t *this, host_t *dst)
|
||||||
|
{
|
||||||
|
return this->packet->set_destination(this->packet, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD2(esp_packet_t, packet_t, get_destination, host_t*,
|
||||||
|
private_esp_packet_t *this)
|
||||||
|
{
|
||||||
|
return this->packet->get_destination(this->packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(packet_t, get_data, chunk_t,
|
||||||
|
private_esp_packet_t *this)
|
||||||
|
{
|
||||||
|
return this->packet->get_data(this->packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(packet_t, set_data, void,
|
||||||
|
private_esp_packet_t *this, chunk_t data)
|
||||||
|
{
|
||||||
|
return this->packet->set_data(this->packet, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(packet_t, skip_bytes, void,
|
||||||
|
private_esp_packet_t *this, size_t bytes)
|
||||||
|
{
|
||||||
|
return this->packet->skip_bytes(this->packet, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(packet_t, clone, packet_t*,
|
||||||
|
private_esp_packet_t *this)
|
||||||
|
{
|
||||||
|
private_esp_packet_t *pkt;
|
||||||
|
|
||||||
|
pkt = esp_packet_create_empty(this->packet->clone(this->packet));
|
||||||
|
pkt->payload = chunk_clone(this->payload);
|
||||||
|
pkt->next_header = this->next_header;
|
||||||
|
return &pkt->public.packet;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(esp_packet_t, parse_header, bool,
|
METHOD(esp_packet_t, parse_header, bool,
|
||||||
private_esp_packet_t *this, u_int32_t *spi)
|
private_esp_packet_t *this, u_int32_t *spi)
|
||||||
{
|
{
|
||||||
bio_reader_t *reader;
|
bio_reader_t *reader;
|
||||||
u_int32_t seq;
|
u_int32_t seq;
|
||||||
|
|
||||||
reader = bio_reader_create(this->packet_data);
|
reader = bio_reader_create(this->packet->get_data(this->packet));
|
||||||
if (!reader->read_uint32(reader, spi) ||
|
if (!reader->read_uint32(reader, spi) ||
|
||||||
!reader->read_uint32(reader, &seq))
|
!reader->read_uint32(reader, &seq))
|
||||||
{
|
{
|
||||||
@@ -142,16 +191,17 @@ METHOD(esp_packet_t, decrypt, status_t,
|
|||||||
{
|
{
|
||||||
bio_reader_t *reader;
|
bio_reader_t *reader;
|
||||||
u_int32_t spi, seq;
|
u_int32_t spi, seq;
|
||||||
chunk_t spi_seq, iv, icv, ciphertext;
|
chunk_t data, iv, icv, ciphertext;
|
||||||
crypter_t *crypter;
|
crypter_t *crypter;
|
||||||
signer_t *signer;
|
signer_t *signer;
|
||||||
|
|
||||||
chunk_free(&this->payload);
|
chunk_free(&this->payload);
|
||||||
|
|
||||||
|
data = this->packet->get_data(this->packet);
|
||||||
crypter = esp_context->get_crypter(esp_context);
|
crypter = esp_context->get_crypter(esp_context);
|
||||||
signer = esp_context->get_signer(esp_context);
|
signer = esp_context->get_signer(esp_context);
|
||||||
|
|
||||||
reader = bio_reader_create(this->packet_data);
|
reader = bio_reader_create(data);
|
||||||
if (!reader->read_uint32(reader, &spi) ||
|
if (!reader->read_uint32(reader, &spi) ||
|
||||||
!reader->read_uint32(reader, &seq) ||
|
!reader->read_uint32(reader, &seq) ||
|
||||||
!reader->read_data(reader, crypter->get_iv_size(crypter), &iv) ||
|
!reader->read_data(reader, crypter->get_iv_size(crypter), &iv) ||
|
||||||
@@ -168,14 +218,13 @@ METHOD(esp_packet_t, decrypt, status_t,
|
|||||||
{
|
{
|
||||||
DBG1(DBG_ESP, "ESP sequence number verification failed:\n "
|
DBG1(DBG_ESP, "ESP sequence number verification failed:\n "
|
||||||
"src %H, dst %H, SPI %.8x [seq %u]",
|
"src %H, dst %H, SPI %.8x [seq %u]",
|
||||||
this->src, this->dst, spi, seq);
|
get_source(this), get_destination(this), spi, seq);
|
||||||
return VERIFY_ERROR;
|
return VERIFY_ERROR;
|
||||||
}
|
}
|
||||||
DBG3(DBG_ESP, "ESP decryption:\n SPI %.8x [seq %u]\n IV %B\n "
|
DBG3(DBG_ESP, "ESP decryption:\n SPI %.8x [seq %u]\n IV %B\n "
|
||||||
"encrypted %B\n ICV %B", spi, seq, &iv, &ciphertext, &icv);
|
"encrypted %B\n ICV %B", spi, seq, &iv, &ciphertext, &icv);
|
||||||
|
|
||||||
spi_seq = chunk_create(this->packet_data.ptr, 8);
|
if (!signer->get_signature(signer, chunk_create(data.ptr, 8), NULL) ||
|
||||||
if (!signer->get_signature(signer, spi_seq, NULL) ||
|
|
||||||
!signer->get_signature(signer, iv, NULL) ||
|
!signer->get_signature(signer, iv, NULL) ||
|
||||||
!signer->verify_signature(signer, ciphertext, icv))
|
!signer->verify_signature(signer, ciphertext, icv))
|
||||||
{
|
{
|
||||||
@@ -222,7 +271,7 @@ METHOD(esp_packet_t, encrypt, status_t,
|
|||||||
signer_t *signer;
|
signer_t *signer;
|
||||||
rng_t *rng;
|
rng_t *rng;
|
||||||
|
|
||||||
chunk_free(&this->packet_data);
|
this->packet->set_data(this->packet, chunk_empty);
|
||||||
|
|
||||||
if (!esp_context->next_seqno(esp_context, &next_seqno))
|
if (!esp_context->next_seqno(esp_context, &next_seqno))
|
||||||
{
|
{
|
||||||
@@ -303,7 +352,7 @@ METHOD(esp_packet_t, encrypt, status_t,
|
|||||||
"encrypted %B\n ICV %B", ntohl(spi), next_seqno, &iv,
|
"encrypted %B\n ICV %B", ntohl(spi), next_seqno, &iv,
|
||||||
&ciphertext, &icv);
|
&ciphertext, &icv);
|
||||||
|
|
||||||
this->packet_data = writer->extract_buf(writer);
|
this->packet->set_data(this->packet, writer->extract_buf(writer));
|
||||||
writer->destroy(writer);
|
writer->destroy(writer);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -320,43 +369,33 @@ METHOD(esp_packet_t, get_payload, chunk_t,
|
|||||||
return this->payload;
|
return this->payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(esp_packet_t, get_packet_data, chunk_t,
|
METHOD2(esp_packet_t, packet_t, destroy, void,
|
||||||
private_esp_packet_t *this)
|
|
||||||
{
|
|
||||||
return this->packet_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(esp_packet_t, get_source, host_t*,
|
|
||||||
private_esp_packet_t *this)
|
|
||||||
{
|
|
||||||
return this->src;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(esp_packet_t, get_destination, host_t*,
|
|
||||||
private_esp_packet_t *this)
|
|
||||||
{
|
|
||||||
return this->dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(esp_packet_t, destroy, void,
|
|
||||||
private_esp_packet_t *this)
|
private_esp_packet_t *this)
|
||||||
{
|
{
|
||||||
chunk_free(&this->payload);
|
chunk_free(&this->payload);
|
||||||
chunk_free(&this->packet_data);
|
this->packet->destroy(this->packet);
|
||||||
this->src->destroy(this->src);
|
|
||||||
this->dst->destroy(this->dst);
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private_esp_packet_t *esp_packet_create_empty(host_t *src, host_t *dst)
|
static private_esp_packet_t *esp_packet_create_empty(packet_t *packet)
|
||||||
{
|
{
|
||||||
private_esp_packet_t *this;
|
private_esp_packet_t *this;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
|
.packet = {
|
||||||
|
.set_source = _set_source,
|
||||||
|
.get_source = _get_source,
|
||||||
|
.set_destination = _set_destination,
|
||||||
|
.get_destination = _get_destination,
|
||||||
|
.get_data = _get_data,
|
||||||
|
.set_data = _set_data,
|
||||||
|
.skip_bytes = _skip_bytes,
|
||||||
|
.clone = _clone,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
.get_source = _get_source,
|
.get_source = _get_source,
|
||||||
.get_destination = _get_destination,
|
.get_destination = _get_destination,
|
||||||
.get_packet_data = _get_packet_data,
|
|
||||||
.get_payload = _get_payload,
|
.get_payload = _get_payload,
|
||||||
.get_next_header = _get_next_header,
|
.get_next_header = _get_next_header,
|
||||||
.parse_header = _parse_header,
|
.parse_header = _parse_header,
|
||||||
@@ -364,8 +403,7 @@ static private_esp_packet_t *esp_packet_create_empty(host_t *src, host_t *dst)
|
|||||||
.encrypt = _encrypt,
|
.encrypt = _encrypt,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.src = src,
|
.packet = packet,
|
||||||
.dst = dst,
|
|
||||||
.next_header = IPPROTO_NONE,
|
.next_header = IPPROTO_NONE,
|
||||||
);
|
);
|
||||||
return this;
|
return this;
|
||||||
@@ -374,13 +412,11 @@ static private_esp_packet_t *esp_packet_create_empty(host_t *src, host_t *dst)
|
|||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst,
|
esp_packet_t *esp_packet_create_from_packet(packet_t *packet)
|
||||||
chunk_t packet_data)
|
|
||||||
{
|
{
|
||||||
private_esp_packet_t *this;
|
private_esp_packet_t *this;
|
||||||
|
|
||||||
this = esp_packet_create_empty(src, dst);
|
this = esp_packet_create_empty(packet);
|
||||||
this->packet_data = packet_data;
|
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
@@ -389,14 +425,16 @@ esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst,
|
|||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst,
|
esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst,
|
||||||
chunk_t payload, u_int8_t next_header)
|
chunk_t payload,
|
||||||
|
u_int8_t next_header)
|
||||||
{
|
{
|
||||||
private_esp_packet_t *this;
|
private_esp_packet_t *this;
|
||||||
|
packet_t *packet;
|
||||||
|
|
||||||
this = esp_packet_create_empty(src, dst);
|
packet = packet_create_from_data(src, dst, chunk_empty);
|
||||||
|
this = esp_packet_create_empty(packet);
|
||||||
this->next_header = next_header;
|
this->next_header = next_header;
|
||||||
this->payload = payload;
|
this->payload = payload;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-14
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <utils/host.h>
|
#include <utils/host.h>
|
||||||
|
#include <utils/packet.h>
|
||||||
|
|
||||||
typedef struct esp_packet_t esp_packet_t;
|
typedef struct esp_packet_t esp_packet_t;
|
||||||
|
|
||||||
@@ -35,6 +36,11 @@ typedef struct esp_packet_t esp_packet_t;
|
|||||||
*/
|
*/
|
||||||
struct esp_packet_t {
|
struct esp_packet_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements packet_t interface to access the raw ESP packet
|
||||||
|
*/
|
||||||
|
packet_t packet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the source address of this packet
|
* Get the source address of this packet
|
||||||
*
|
*
|
||||||
@@ -106,14 +112,6 @@ struct esp_packet_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t (*get_payload)(esp_packet_t *this);
|
chunk_t (*get_payload)(esp_packet_t *this);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the packet data to send / as received on the wire.
|
|
||||||
*
|
|
||||||
* @return encrypted packet data (internal data),
|
|
||||||
* chunk_empty if not encrypted
|
|
||||||
*/
|
|
||||||
chunk_t (*get_packet_data)(esp_packet_t *this);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy an esp_packet_t
|
* Destroy an esp_packet_t
|
||||||
*/
|
*/
|
||||||
@@ -124,13 +122,10 @@ struct esp_packet_t {
|
|||||||
/**
|
/**
|
||||||
* Create an ESP packet out of data from the wire.
|
* Create an ESP packet out of data from the wire.
|
||||||
*
|
*
|
||||||
* @param src source address from which the packet was sent, owned
|
* @param packet the packet data as received, gets owned
|
||||||
* @param dst destination address to which the packet was sent, owned
|
|
||||||
* @param data the packet data as received, gets owned
|
|
||||||
* @return esp_packet_t instance
|
* @return esp_packet_t instance
|
||||||
*/
|
*/
|
||||||
esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst,
|
esp_packet_t *esp_packet_create_from_packet(packet_t *packet);
|
||||||
chunk_t data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an ESP packet from a plaintext payload (e.g. inner IP packet)
|
* Create an ESP packet from a plaintext payload (e.g. inner IP packet)
|
||||||
@@ -142,7 +137,8 @@ esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst,
|
|||||||
* @return esp_packet_t instance
|
* @return esp_packet_t instance
|
||||||
*/
|
*/
|
||||||
esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst,
|
esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst,
|
||||||
chunk_t payload, u_int8_t next_header);
|
chunk_t payload,
|
||||||
|
u_int8_t next_header);
|
||||||
|
|
||||||
#endif /** ESP_PACKET_H_ @}*/
|
#endif /** ESP_PACKET_H_ @}*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user