File: iface.h

package info (click to toggle)
libreswan 4.3-1%2Bdeb11u4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 62,688 kB
  • sloc: ansic: 108,293; sh: 25,973; xml: 11,756; python: 10,230; makefile: 1,580; javascript: 1,353; yacc: 825; sed: 647; perl: 584; lex: 159; awk: 156
file content (192 lines) | stat: -rw-r--r-- 6,456 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* iface, for libreswan
 *
 * Copyright (C) 1998-2001,2013  D. Hugh Redelmeier <hugh@mimosa.com>
 * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
 * Copyright (C) 2013 Florian Weimer <fweimer@redhat.com>
 * Copyright (C) 2019-2020 Andrew Cagney
 * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <https://www.gnu.org/licenses/gpl2.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#ifndef IFACE_H
#define IFACE_H


#include "ip_endpoint.h"
#include "refcnt.h"
#include "list_entry.h"

struct fd;
struct raw_iface;
struct iface_endpoint;
struct show;
struct iface_dev;
struct logger;

struct iface_packet {
	ssize_t len;
	ip_endpoint sender;
	uint8_t *ptr;
	struct logger *logger; /*global*/
};

enum iface_status {
	IFACE_OK = 0,
	IFACE_EOF,
	IFACE_FATAL,
	IFACE_IGNORE, /* aka EAGAIN */
};

struct iface_io {
	bool send_keepalive;
	const struct ip_protocol *protocol;
	enum iface_status (*read_packet)(const struct iface_endpoint *ifp,
					 struct iface_packet *,
					 struct logger *logger);
	ssize_t (*write_packet)(const struct iface_endpoint *ifp,
				const void *ptr, size_t len,
				const ip_endpoint *remote_endpoint,
				struct logger *logger);
	void (*cleanup)(struct iface_endpoint *ifp);
	void (*listen)(struct iface_endpoint *fip, struct logger *logger);
	int (*bind_iface_endpoint)(struct iface_dev *ifd,
				   ip_port port, bool esp_encapsulation_enabled,
				   struct logger *logger);
};

extern const struct iface_io udp_iface_io;
extern const struct iface_io iketcp_iface_io; /*IKETCP specific*/

/* interface: a terminal point for IKE traffic, IPsec transport mode
 * and IPsec tunnels.
 * Essentially:
 * - an IP device (eg. eth1), and
 * - its partner, an ipsec device (eg. ipsec0), and
 * - their shared IP address (eg. 10.7.3.2)
 * Note: the port for IKE is always implicitly UDP/pluto_port.
 *
 * The iface is a unique IP address on a system. It may be used by
 * multiple port numbers. In general, two conns have the same
 * interface if they have the same iface_endpoint->iface_alias.
 */

struct iface_dev {
	struct list_entry ifd_entry;
	refcnt_t refcnt;
	char *id_rname; /* real device name */
	bool id_nic_offload;
	ip_address id_address;
	enum { IFD_ADD, IFD_KEEP, IFD_DELETE } ifd_change;
};

void release_iface_dev(struct iface_dev **id);
void add_or_keep_iface_dev(struct raw_iface *ifp, struct logger *logger);
struct iface_dev *find_iface_dev_by_address(const ip_address *address);

struct iface_endpoint {
	struct iface_dev   *ip_dev;
	const struct iface_io *io;
	ip_endpoint local_endpoint;	/* interface IP address:port */
	int fd;                 /* file descriptor of socket for IKE UDP messages */
	struct iface_endpoint *next;
	const struct ip_protocol *protocol;
	/*
	 * Here's what the RFC has to say:
	 *
	 * 2.  IKE Protocol Details and Variations
	 *
	 *     The UDP payload of all packets containing IKE messages
	 *     sent on port 4500 MUST begin with the prefix of four
	 *     zeros; otherwise, the receiver won't know how to handle
	 *     them.
	 *
	 * 2.23.  NAT Traversal
	 *
	 *     ... UDP encapsulation MUST NOT be done on port 500.
	 *
	 * 3.1.  The IKE Header
	 *
	 *     When sent on UDP port 500, IKE messages begin
	 *     immediately following the UDP header.  When sent on UDP
	 *     port 4500, IKE messages have prepended four octets of
	 *     zeros.
	 *
	 * I'm assuming that "sent on port ..." is intended to mean
	 * "sent from port ... to port ...".  But now we've got us
	 * deliberately sending from a random port to ...
	 *
	 * to port 500 with no ESP=0:
	 * -> since esp encal is disabled, the kernel passes the packet through
	 * -> pluto responds with no ESP=0
	 *
	 * to port 500 with ESP=0:
	 * -> since esp encal is disabled, the kernel passes the packet through
	 * -> pluto sees the ESP=0 prefix and rejects it
	 *
	 * to port 4500 with no ESP=0:
	 * -> since esp encap is enabled, the kernel will see the leading bytes
	 * are non-zero and eats an ESP packet
	 *
	 * to port 4500 with ESP=0:
	 * -> since esp encap is enabled, and ESP=0, kernel passes the packet through
	 * -> pluto sees ESP=0 prefix
	 * -> pluto responds with ESP=0 prefix
	 *
	 * to a random port:
	 * - to be able to work with NAT esp encap needs to be enabled and that
	 * in turn means all incoming messages must have the ESP=0 prefix
	 * - trying to negotiate to port 500 will fail - the incoming message
	 * will be missing the ESP=0 prefix
	 */
	bool esp_encapsulation_enabled;
	/*
	 * For IKEv2 2.23.  NAT Traversal.  When NAT is detected, must
	 * the initiators float away, switching to port 4500?  This
	 * doesn't make sense for TCP, and this doesn't make sense
	 * when using IKEPORT.
	 */
	bool float_nat_initiator;
	/* udp only */
	struct event *udp_message_listener;
	/* tcp port only */
	struct evconnlistener *tcp_accept_listener;
	/* tcp stream only */
	struct event *iketcp_message_listener;
	ip_endpoint iketcp_remote_endpoint;
	bool iketcp_server;
	enum iketcp_state {
		IKETCP_OPEN = 1,
		IKETCP_PREFIXED, /* received IKETCP */
		IKETCP_RUNNING,  /* received at least one packet */
		IKETCP_STOPPED, /* waiting on state to close */
	} iketcp_state;
	struct event *iketcp_timeout;
};

void stop_iketcp_iface_endpoint(struct iface_endpoint **ifp);
void free_any_iface_endpoint(struct iface_endpoint **ifp);

extern struct iface_endpoint *interfaces;   /* public interfaces */

extern struct iface_endpoint *find_iface_endpoint_by_local_endpoint(ip_endpoint *local_endpoint);
extern bool use_interface(const char *rifn);
extern void find_ifaces(bool rm_dead, struct logger *logger);
extern void show_ifaces_status(struct show *s);
extern void free_ifaces(struct logger *logger);
void listen_on_iface_endpoint(struct iface_endpoint *ifp, struct logger *logger);
struct iface_endpoint *bind_iface_endpoint(struct iface_dev *ifd, const struct iface_io *io,
					   ip_port port,
					   bool esp_encapsulation_enabled,
					   bool float_nat_initiator,
					   struct logger *logger);

#endif