ipsec_outbound.c
Go to the documentation of this file.
1 /**
2  * @file ipsec_outbound.c
3  * @brief IPsec processing of outbound IP traffic
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Dependencies
32 #include "ipsec/ipsec.h"
33 #include "ipsec/ipsec_outbound.h"
34 #include "ipsec/ipsec_misc.h"
35 #include "ike/ike.h"
36 #include "ah/ah.h"
37 #include "esp/esp_packet_encrypt.h"
38 #include "debug.h"
39 
40 //Check IPsec library configuration
41 #if (IPSEC_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Outbound IPv4 traffic processing
46  * @param[in] interface Underlying network interface
47  * @param[in] pseudoHeader IPv4 pseudo header
48  * @param[in] fragId Fragment identification field
49  * @param[in] buffer Multi-part buffer containing the payload
50  * @param[in] offset Offset to the first byte of the payload
51  * @param[in] ancillary Additional options passed to the stack along with
52  * the packet
53  * @return Error code
54  **/
55 
57  const Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, NetBuffer *buffer,
58  size_t offset, NetTxAncillary *ancillary)
59 {
60  error_t error;
61  IpsecContext *context;
62  IpsecSadEntry *sadEntry;
63  IpsecSpdEntry *spdEntry;
64  IpsecSelector selector;
65 
66  //Point to the IPsec context
67  context = netContext.ipsecContext;
68 
69  //Extract packet's selector from the packet headers
70  error = ipsecGetOutboundIpv4PacketSelector(pseudoHeader, buffer, offset,
71  &selector);
72 
73  //Check status code
74  if(!error)
75  {
76  //Search the SPD for a matching entry
78  &selector);
79 
80  //Any SPD entry found?
81  if(spdEntry != NULL)
82  {
83  //Check applicable SPD policies
85  {
86  //If the SPD entry calls for PROTECT, then search the SAD for an
87  //existing security association
88  sadEntry = ipsecFindOutboundSadEntry(context, &selector);
89 
90  //Any SAD entry found?
91  if(sadEntry != NULL)
92  {
93  //Protect the outbound packet using AH or ESP
94  error = ipsecProtectIpv4Packet(context, sadEntry, interface,
95  pseudoHeader, fragId, buffer, offset, ancillary);
96  }
97  else
98  {
99  IpsecPacketInfo packetInfo;
100 
101  //The key management mechanism is invoked to create the SA
102  packetInfo.localIpAddr.length = sizeof(Ipv4Addr);
103  packetInfo.localIpAddr.ipv4Addr = pseudoHeader->srcAddr;
104  packetInfo.remoteIpAddr.length = sizeof(Ipv4Addr);
105  packetInfo.remoteIpAddr.ipv4Addr = pseudoHeader->destAddr;
106  packetInfo.nextProtocol = pseudoHeader->protocol;
107  packetInfo.localPort = selector.localPort.start;
108  packetInfo.remotePort = selector.remotePort.start;
109 
110  //Create a new SA
111  ikeCreateChildSa(netContext.ikeContext, &packetInfo);
112 
113  //There is no requirement that an implementation buffer the packet
114  //if there is a cache miss (refer to RFC 4301, section 5.2)
115  error = ERROR_IN_PROGRESS;
116  }
117  }
118  else if(spdEntry->policyAction == IPSEC_POLICY_ACTION_BYPASS)
119  {
120  //If the SPD entry calls for BYPASS, then the packet is not
121  //protected
122  error = ipsecSendIpv4Packet(interface, pseudoHeader, fragId,
123  buffer, offset, ancillary);
124  }
125  else
126  {
127  //If the SPD entry calls for DISCARD, then drop the packet
128  error = ERROR_POLICY_FAILURE;
129  }
130  }
131  else
132  {
133  //If there is no match, discard the traffic
134  error = ERROR_POLICY_FAILURE;
135  }
136  }
137 
138  //Return status code
139  return error;
140 }
141 
142 
143 /**
144  * @brief Extract packet's selector from outbound IPv4 packet
145  * @param[in] pseudoHeader IPv4 pseudo header
146  * @param[in] buffer Multi-part buffer containing the IP payload
147  * @param[in] offset Offset from the beginning of the buffer
148  * @param[out] selector Pointer to the IPsec selector
149  * @return Error code
150  **/
151 
153  const NetBuffer *buffer, size_t offset, IpsecSelector *selector)
154 {
155  error_t error;
156  size_t length;
157  const uint8_t *data;
158 
159  //Initialize status code
160  error = NO_ERROR;
161 
162  //Local IP address range
163  selector->localIpAddr.start.length = sizeof(Ipv4Addr);
164  selector->localIpAddr.start.ipv4Addr = pseudoHeader->srcAddr;
165  selector->localIpAddr.end.length = sizeof(Ipv4Addr);
166  selector->localIpAddr.end.ipv4Addr = pseudoHeader->srcAddr;
167 
168  //Remote IP address range
169  selector->remoteIpAddr.start.length = sizeof(Ipv4Addr);
170  selector->remoteIpAddr.start.ipv4Addr = pseudoHeader->destAddr;
171  selector->remoteIpAddr.end.length = sizeof(Ipv4Addr);
172  selector->remoteIpAddr.end.ipv4Addr = pseudoHeader->destAddr;
173 
174  //Next Layer Protocol value
175  selector->nextProtocol = pseudoHeader->protocol;
176 
177  //Retrieve the length of the data
178  length = netBufferGetLength(buffer) - offset;
179  //Point to the data
180  data = netBufferAt(buffer, offset, 0);
181 
182  //Sanity check
183  if(data != NULL)
184  {
185  //Several additional selectors depend on the Next Layer Protocol value
186  //(refer to RFC 4301, section 4.4.1.1)
187  if(pseudoHeader->protocol == IPV4_PROTOCOL_UDP &&
188  length >= sizeof(UdpHeader))
189  {
190  //Point to the UDP header
191  UdpHeader *udpHeader = (UdpHeader *) data;
192 
193  //If the Next Layer Protocol value is UDP, then there are selectors
194  //for local and remote ports
195  selector->localPort.start = ntohs(udpHeader->srcPort);
196  selector->localPort.end = ntohs(udpHeader->srcPort);
197  selector->remotePort.start = ntohs(udpHeader->destPort);
198  selector->remotePort.end = ntohs(udpHeader->destPort);
199  }
200  else if(pseudoHeader->protocol == IPV4_PROTOCOL_TCP &&
201  length >= sizeof(TcpHeader))
202  {
203  //Point to the TCP header
204  TcpHeader *tcpHeader = (TcpHeader *) data;
205 
206  //If the Next Layer Protocol value is TCP, then there are selectors
207  //for local and remote ports
208  selector->localPort.start = ntohs(tcpHeader->srcPort);
209  selector->localPort.end = ntohs(tcpHeader->srcPort);
210  selector->remotePort.start = ntohs(tcpHeader->destPort);
211  selector->remotePort.end = ntohs(tcpHeader->destPort);
212  }
213  else if(pseudoHeader->protocol == IPV4_PROTOCOL_ICMP &&
214  length >= sizeof(IcmpHeader))
215  {
216  //Point to the ICMP header
217  IcmpHeader *icmpHeader = (IcmpHeader *) data;
218 
219  //If the Next Layer Protocol value is ICMP, then there is a 16-bit
220  //selector for the ICMP message type and code
221  selector->localPort.start = IPSEC_ICMP_PORT(icmpHeader->type, icmpHeader->code);
222  selector->localPort.end = IPSEC_ICMP_PORT(icmpHeader->type, icmpHeader->code);
225  }
226  else
227  {
228  //The local and remote port selectors may be labeled as OPAQUE to
229  //accommodate situations where these fields are inaccessible
231  selector->localPort.end = IPSEC_PORT_END_OPAQUE;
234  }
235  }
236  else
237  {
238  //Report an error
239  error = ERROR_INVALID_HEADER;
240  }
241 
242  //Return status code
243  return error;
244 }
245 
246 
247 /**
248  * @brief Protect an outbound IPv4 packet using AH or ESP
249  * @param[in] context Pointer to the IPsec context
250  * @param[in] sa Pointer to the security association
251  * @param[in] interface Underlying network interface
252  * @param[in] pseudoHeader IPv4 pseudo header
253  * @param[in] fragId Fragment identification field
254  * @param[in] buffer Multi-part buffer containing the payload
255  * @param[in] offset Offset to the first byte of the payload
256  * @param[in] ancillary Additional options passed to the stack along with
257  * the packet
258  * @return Error code
259  **/
260 
262  NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader,
263  uint16_t fragId, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
264 {
265  error_t error;
266  size_t length;
267 
268  //Check the state of the SAD entry
269  if(sa->state == IPSEC_SA_STATE_OPEN)
270  {
271  //Retrieve the length of the data
272  length = netBufferGetLength(buffer) - offset;
273 
274 #if (AH_SUPPORT == ENABLED)
275  //AH protocol?
276  if(sa->protocol == IPSEC_PROTOCOL_AH)
277  {
278  AhHeader *ahHeader;
279  Ipv4Header ipv4Header;
280  Ipv4PseudoHeader pseudoHeader2;
281 
282  //Sanity check
283  if(offset < (sizeof(AhHeader) + sa->icvLen))
284  return ERROR_FAILURE;
285 
286  //Make room for the AH header
287  offset -= sizeof(AhHeader) + sa->icvLen;
288  length += sizeof(AhHeader) + sa->icvLen;
289 
290  //The AH header is inserted after the IP header and before a next
291  //layer protocol
292  ahHeader = netBufferAt(buffer, offset, 0);
293 
294  //The sender increments the sequence number counter for this SA and
295  //inserts the low-order 32 bits of the value into the Sequence
296  //Number field (refer to RFC 4302, section 3.3.2)
297  sa->seqNum++;
298 
299  //Format AH header
300  ahHeader->nextHeader = pseudoHeader->protocol;
301  ahHeader->payloadLen = (sizeof(AhHeader) + sa->icvLen) / 4 - 2;
302  ahHeader->reserved = 0;
303  ahHeader->spi = htonl(sa->spi);
304  ahHeader->seqNum = htonl(sa->seqNum);
305 
306  //The Integrity Check Value field is also set to zero in preparation
307  //for this computation (refer to RFC 4302, section 3.3.3.1)
308  osMemset(ahHeader->icv, 0, sa->icvLen);
309 
310  //Format outer IPv4 header
311  osMemset(&ipv4Header, 0, sizeof(Ipv4Header));
312  ipv4Header.version = IPV4_VERSION;
313  ipv4Header.headerLength = 5;
314  ipv4Header.typeOfService = 0;
315  ipv4Header.totalLength = htons(length + sizeof(Ipv4Header));
316  ipv4Header.identification = htons(fragId);
317  ipv4Header.fragmentOffset = 0;
318  ipv4Header.timeToLive = 0;
319  ipv4Header.protocol = IPV4_PROTOCOL_AH;
320  ipv4Header.headerChecksum = 0;
321  ipv4Header.srcAddr = pseudoHeader->srcAddr;
322  ipv4Header.destAddr = pseudoHeader->destAddr;
323 
324  //Compute ICV value
325  error = ahGenerateIcv(sa, &ipv4Header, ahHeader, buffer,
326  offset + sizeof(AhHeader) + sa->icvLen);
327  //Any error to report?
328  if(error)
329  return error;
330 
331  //Fix the Next Layer Protocol value
332  pseudoHeader2 = *pseudoHeader;
333  pseudoHeader2.protocol = IPV4_PROTOCOL_AH;
334 
335  //Debug message
336  TRACE_INFO("AH Header:\r\n");
337  ahDumpHeader(ahHeader);
338 
339  //Send AH packet
340  error = ipsecSendIpv4Packet(interface, &pseudoHeader2, fragId, buffer,
341  offset, ancillary);
342  }
343  else
344 #endif
345 #if (ESP_SUPPORT == ENABLED)
346  //ESP protocol?
347  if(sa->protocol == IPSEC_PROTOCOL_ESP)
348  {
349  size_t offset2;
350  NetBuffer *buffer2;
351  Ipv4PseudoHeader pseudoHeader2;
352  EspHeader *espHeader;
353 
354  //Sanity check
355  if((length + sizeof(EspHeader)) > ESP_BUFFER_SIZE)
356  return ERROR_FAILURE;
357 
358  //The ESP header is inserted after the IP header and before the
359  //next layer protocol header (transport mode) or before an
360  //encapsulated IP header (tunnel mode)
361  espHeader = (EspHeader *) context->buffer;
362 
363  //The sender increments the sequence number counter for this SA and
364  //inserts the low-order 32 bits of the value into the Sequence
365  //Number field (refer to RFC 4303, section 3.3.3)
366  sa->seqNum++;
367 
368  //Format ESP header
369  espHeader->spi = htonl(sa->spi);
370  espHeader->seqNum = htonl(sa->seqNum);
371 
372  //Debug message
373  TRACE_INFO("ESP Header:\r\n");
374  espDumpHeader(espHeader);
375 
376  //Copy the payload data to be encrypted
377  netBufferRead(espHeader->payloadData + sa->ivLen, buffer,
378  offset, length);
379 
380  //The encryption algorithm employed to protect the ESP packet is
381  //specified by the SA via which the packet is transmitted
382  error = espEncryptPacket(context, sa, espHeader,
383  espHeader->payloadData, &length, pseudoHeader->protocol);
384  //Any error to report?
385  if(error)
386  return error;
387 
388  //Calculate the length of the resulting ESP packet
389  length += sizeof(EspHeader);
390 
391  //Allocate a buffer to hold the ESP packet
392  buffer2 = ipAllocBuffer(length, &offset2);
393  //Failed to allocate memory?
394  if(buffer2 == NULL)
395  return ERROR_OUT_OF_MEMORY;
396 
397  //Copy the resulting ESP packet
398  netBufferWrite(buffer2, offset2, context->buffer, length);
399 
400  //The outer IPv4 protocol header that immediately precedes the ESP
401  //header shall contain the value 50 in its Protocol field (refer to
402  //RFC 4303, section 2)
403  pseudoHeader2 = *pseudoHeader;
404  pseudoHeader2.protocol = IPV4_PROTOCOL_ESP;
405 
406  //Send ESP packet
407  error = ipsecSendIpv4Packet(interface, &pseudoHeader2, fragId,
408  buffer2, offset2, ancillary);
409 
410  //Free previously allocated memory
411  netBufferFree(buffer2);
412  }
413  else
414 #endif
415  //Invalid IPsec protocol?
416  {
417  //Report an error
418  error = ERROR_INVALID_PROTOCOL;
419  }
420  }
421  else
422  {
423  //The establishment of the SA pair is in progress
424  error = ERROR_IN_PROGRESS;
425  }
426 
427  //Return status code
428  return error;
429 }
430 
431 
432 /**
433  * @brief Send an IPv4 packet
434  * @param[in] interface Underlying network interface
435  * @param[in] pseudoHeader IPv4 pseudo header
436  * @param[in] fragId Fragment identification field
437  * @param[in] buffer Multi-part buffer containing the payload
438  * @param[in] offset Offset to the first byte of the payload
439  * @param[in] ancillary Additional options passed to the stack along with
440  * the packet
441  * @return Error code
442  **/
443 
445  const Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, NetBuffer *buffer,
446  size_t offset, NetTxAncillary *ancillary)
447 {
448  error_t error;
449  size_t length;
450 
451  //Retrieve the length of payload
452  length = netBufferGetLength(buffer) - offset;
453 
454  //Check the length of the payload
455  if((length + sizeof(Ipv4Header)) <= interface->ipv4Context.linkMtu)
456  {
457  //If the payload length is smaller than the network interface MTU
458  //then no fragmentation is needed
459  error = ipv4SendPacket(interface, pseudoHeader, fragId, 0, buffer,
460  offset, ancillary);
461  }
462  else
463  {
464 #if (IPV4_FRAG_SUPPORT == ENABLED)
465  //An IP datagram can be marked "don't fragment". Any IP datagram so
466  //marked is not to be fragmented under any circumstances (refer to
467  //RFC791, section 2.3)
468  if(!ancillary->dontFrag)
469  {
470  //If the payload length exceeds the network interface MTU then the
471  //device must fragment the data
472  error = ipv4FragmentDatagram(interface, pseudoHeader, fragId, buffer,
473  offset, ancillary);
474  }
475  else
476 #endif
477  {
478  //If IP datagram cannot be delivered to its destination without
479  //fragmenting it, it is to be discarded instead
480  error = ERROR_MESSAGE_TOO_LONG;
481  }
482  }
483 
484  //Return status code
485  return error;
486 }
487 
488 #endif
error_t espEncryptPacket(IpsecContext *context, IpsecSadEntry *sa, const EspHeader *espHeader, uint8_t *payload, size_t *payloadLen, uint8_t nextHeader)
Encrypt an outgoing ESP packet.
#define htons(value)
Definition: cpu_endian.h:413
error_t ahGenerateIcv(IpsecSadEntry *sa, const Ipv4Header *ipv4Header, AhHeader *ahHeader, const NetBuffer *buffer, size_t offset)
ICV generation.
Definition: ah.c:275
NetBuffer * ipAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an IP packet.
Definition: ip.c:711
#define Ipv4Header
Definition: ipv4.h:36
@ IPV4_PROTOCOL_ICMP
Definition: ipv4.h:250
uint16_t end
Definition: ipsec.h:293
error_t ikeCreateChildSa(IkeContext *context, const IpsecPacketInfo *packet)
Create a new Child SA.
Definition: ike.c:577
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:192
IPsec selector.
Definition: ipsec.h:302
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:690
IPsec processing of outbound IP traffic.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define IPSEC_PORT_START_OPAQUE
Definition: ipsec.h:148
IpAddr remoteIpAddr
Remote IP address.
Definition: ipsec.h:318
uint8_t data[]
Definition: ethernet.h:222
@ ERROR_INVALID_HEADER
Definition: error.h:87
IpAddr end
Definition: ipsec.h:282
#define IPSEC_ICMP_PORT(type, code)
Definition: ipsec.h:152
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
NetContext netContext
Definition: net.c:74
#define ESP_BUFFER_SIZE
Definition: esp.h:228
error_t ipv4FragmentDatagram(NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader, uint16_t id, const NetBuffer *payload, size_t payloadOffset, NetTxAncillary *ancillary)
Fragment an IPv4 datagram into smaller packets.
Definition: ipv4_frag.c:72
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:297
@ IPSEC_POLICY_ACTION_PROTECT
Definition: ipsec.h:233
@ IPSEC_PROTOCOL_ESP
Definition: ipsec.h:193
IcmpHeader
Definition: icmp.h:113
uint16_t remotePort
Remote port.
Definition: ipsec.h:321
@ IPV4_PROTOCOL_TCP
Definition: ipv4.h:252
error_t ipsecProtectIpv4Packet(IpsecContext *context, IpsecSadEntry *sa, NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Protect an outbound IPv4 packet using AH or ESP.
@ ERROR_IN_PROGRESS
Definition: error.h:213
@ IPV4_PROTOCOL_AH
Definition: ipv4.h:255
#define htonl(value)
Definition: cpu_endian.h:414
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:319
error_t ipsecGetOutboundIpv4PacketSelector(const Ipv4PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset, IpsecSelector *selector)
Extract packet's selector from outbound IPv4 packet.
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:305
uint16_t localPort
Local port.
Definition: ipsec.h:320
error_t
Error codes.
Definition: error.h:43
IpsecPolicyAction policyAction
Processing choice (DISCARD, BYPASS or PROTECT)
Definition: ipsec.h:345
error_t ipsecSendIpv4Packet(NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send an IPv4 packet.
AhHeader
Definition: ah.h:146
IpsecPortRange remotePort
Remote port range.
Definition: ipsec.h:307
IpsecSadEntry * ipsecFindOutboundSadEntry(IpsecContext *context, const IpsecSelector *selector)
Search the SAD database for a matching outbound entry.
Definition: ipsec_misc.c:174
error_t ipv4SendPacket(NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, size_t fragOffset, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send an IPv4 packet.
Definition: ipv4.c:1096
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
Helper routines for IPsec.
#define NetInterface
Definition: net.h:36
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
ESP packet encryption.
#define NetTxAncillary
Definition: net_misc.h:36
IPsec context.
Definition: ipsec.h:434
#define Ipv4PseudoHeader
Definition: ipv4.h:39
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t length
Definition: tcp.h:368
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
@ ERROR_MESSAGE_TOO_LONG
Definition: error.h:136
@ ERROR_INVALID_PROTOCOL
Definition: error.h:101
size_t length
Definition: ip.h:91
AH (IP Authentication Header)
void * ipsecContext
IPsec context.
Definition: net.h:333
IpAddr start
Definition: ipsec.h:281
IpsecSpdEntry * ipsecFindSpdEntry(IpsecContext *context, IpsecPolicyAction policyAction, const IpsecSelector *selector)
Search the SPD database for a matching entry.
Definition: ipsec_misc.c:51
#define IpsecSadEntry
Definition: ipsec.h:36
uint16_t start
Definition: ipsec.h:292
UdpHeader
Definition: udp.h:85
IKEv2 (Internet Key Exchange Protocol)
EspHeader
Definition: esp.h:255
#define ntohs(value)
Definition: cpu_endian.h:421
#define IPSEC_PORT_END_OPAQUE
Definition: ipsec.h:149
Ipv4Addr ipv4Addr
Definition: ip.h:95
IPsec (IP security)
@ IPV4_PROTOCOL_UDP
Definition: ipv4.h:253
error_t ipsecProcessOutboundIpv4Packet(NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Outbound IPv4 traffic processing.
IP packet information.
Definition: ipsec.h:316
IpsecAddrRange localIpAddr
Local IP address range.
Definition: ipsec.h:303
@ IPV4_PROTOCOL_ESP
Definition: ipv4.h:254
@ IPSEC_POLICY_ACTION_INVALID
Definition: ipsec.h:230
IpAddr localIpAddr
Local IP address.
Definition: ipsec.h:317
#define IPV4_VERSION
Definition: ipv4.h:96
size_t netBufferWrite(NetBuffer *dest, size_t destOffset, const void *src, size_t length)
Write data to a multi-part buffer.
Definition: net_mem.c:637
@ IPSEC_POLICY_ACTION_BYPASS
Definition: ipsec.h:232
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
Security Policy Database (SPD) entry.
Definition: ipsec.h:344
#define osMemset(p, value, length)
Definition: os_port.h:135
TcpHeader
Definition: tcp.h:358
void * ikeContext
IKE context.
Definition: net.h:334
@ IPSEC_SA_STATE_OPEN
Definition: ipsec.h:271
IpsecPortRange localPort
Local port range.
Definition: ipsec.h:306
void espDumpHeader(const EspHeader *espHeader)
Dump ESP header for debugging purpose.
Definition: esp.c:301
@ ERROR_POLICY_FAILURE
Definition: error.h:299
uint8_t buffer[ESP_BUFFER_SIZE]
Memory buffer for input/output operations.
Definition: ipsec.h:450
void ahDumpHeader(const AhHeader *ahHeader)
Dump AH header for debugging purpose.
Definition: ah.c:760
IpsecAddrRange remoteIpAddr
Remote IP address range.
Definition: ipsec.h:304
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.