1 /* $OpenBSD: udp_encap.c,v 1.21 2007/04/16 13:01:39 moritz Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved. 5 * Copyright (c) 2000 Angelos D. Keromytis. All rights reserved. 6 * Copyright (c) 2004 H�kan Olsson. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/ioctl.h> 31 #include <sys/socket.h> 32 #include <sys/sockio.h> 33 #include <net/if.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 #include <ctype.h> 37 #include <limits.h> 38 #include <netdb.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 #include "sysdep.h" 44 45 #include "conf.h" 46 #include "if.h" 47 #include "ipsec_doi.h" 48 #include "isakmp.h" 49 #include "log.h" 50 #include "message.h" 51 #include "monitor.h" 52 #include "transport.h" 53 #include "udp.h" 54 #include "udp_encap.h" 55 #include "util.h" 56 #include "virtual.h" 57 58 #define UDP_SIZE 65536 59 60 /* If a system doesn't have SO_REUSEPORT, SO_REUSEADDR will have to do. */ 61 #ifndef SO_REUSEPORT 62 #define SO_REUSEPORT SO_REUSEADDR 63 #endif 64 65 /* Reused, from udp.c */ 66 struct transport *udp_clone(struct transport *, struct sockaddr *); 67 int udp_fd_set(struct transport *, fd_set *, int); 68 int udp_fd_isset(struct transport *, fd_set *); 69 void udp_get_dst(struct transport *, struct sockaddr **); 70 void udp_get_src(struct transport *, struct sockaddr **); 71 char *udp_decode_ids(struct transport *); 72 void udp_remove(struct transport *); 73 74 static struct transport *udp_encap_create(char *); 75 static void udp_encap_report(struct transport *); 76 static void udp_encap_handle_message(struct transport *); 77 static struct transport *udp_encap_make(struct sockaddr *); 78 static int udp_encap_send_message(struct message *, 79 struct transport *); 80 81 static struct transport_vtbl udp_encap_transport_vtbl = { 82 { 0 }, "udp_encap", 83 udp_encap_create, 84 0, 85 udp_remove, 86 udp_encap_report, 87 udp_fd_set, 88 udp_fd_isset, 89 udp_encap_handle_message, 90 udp_encap_send_message, 91 udp_get_dst, 92 udp_get_src, 93 udp_decode_ids, 94 udp_clone, 95 0 96 }; 97 98 char *udp_encap_default_port = 0; 99 100 void 101 udp_encap_init(void) 102 { 103 transport_method_add(&udp_encap_transport_vtbl); 104 } 105 106 /* Create a UDP transport structure bound to LADDR just for listening. */ 107 static struct transport * 108 udp_encap_make(struct sockaddr *laddr) 109 { 110 struct udp_transport *t = 0; 111 int s, on, wildcardaddress = 0; 112 char *tstr; 113 114 t = calloc(1, sizeof *t); 115 if (!t) { 116 log_print("udp_encap_make: malloc (%lu) failed", 117 (unsigned long)sizeof *t); 118 free(laddr); 119 return 0; 120 } 121 t->src = laddr; 122 123 s = socket(laddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); 124 if (s == -1) { 125 log_error("udp_encap_make: socket (%d, %d, %d)", 126 laddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); 127 goto err; 128 } 129 130 /* Make sure we don't get our traffic encrypted. */ 131 if (sysdep_cleartext(s, laddr->sa_family) == -1) 132 goto err; 133 134 /* Wildcard address ? */ 135 switch (laddr->sa_family) { 136 case AF_INET: 137 if (((struct sockaddr_in *)laddr)->sin_addr.s_addr 138 == INADDR_ANY) 139 wildcardaddress = 1; 140 break; 141 case AF_INET6: 142 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)laddr)->sin6_addr)) 143 wildcardaddress = 1; 144 break; 145 } 146 147 /* 148 * In order to have several bound specific address-port combinations 149 * with the same port SO_REUSEADDR is needed. 150 * If this is a wildcard socket and we are not listening there, but 151 * only sending from it make sure it is entirely reuseable with 152 * SO_REUSEPORT. 153 */ 154 on = 1; 155 if (setsockopt(s, SOL_SOCKET, 156 wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR, 157 (void *)&on, sizeof on) == -1) { 158 log_error("udp_encap_make: setsockopt (%d, %d, %d, %p, %lu)", 159 s, SOL_SOCKET, 160 wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR, &on, 161 (unsigned long)sizeof on); 162 goto err; 163 } 164 165 t->transport.vtbl = &udp_encap_transport_vtbl; 166 if (monitor_bind(s, t->src, SA_LEN(t->src))) { 167 if (sockaddr2text(t->src, &tstr, 0)) 168 log_error("udp_encap_make: bind (%d, %p, %lu)", s, 169 &t->src, (unsigned long)sizeof t->src); 170 else { 171 log_error("udp_encap_make: bind (%d, %s, %lu)", s, 172 tstr, (unsigned long)sizeof t->src); 173 free(tstr); 174 } 175 goto err; 176 } 177 178 t->s = s; 179 if (sockaddr2text(t->src, &tstr, 0)) 180 LOG_DBG((LOG_MISC, 20, "udp_encap_make: " 181 "transport %p socket %d family %d", t, s, 182 t->src->sa_family == AF_INET ? 4 : 6)); 183 else { 184 LOG_DBG((LOG_MISC, 20, "udp_encap_make: " 185 "transport %p socket %d ip %s port %d", t, s, 186 tstr, ntohs(sockaddr_port(t->src)))); 187 free(tstr); 188 } 189 transport_setup(&t->transport, 0); 190 t->transport.flags |= TRANSPORT_LISTEN; 191 return &t->transport; 192 193 err: 194 if (s >= 0) 195 close (s); 196 if (t) { 197 /* Already closed. */ 198 t->s = -1; 199 udp_remove(&t->transport); 200 } 201 return 0; 202 } 203 204 /* 205 * Initialize an object of the UDP transport class. Fill in the local 206 * IP address and port information and create a server socket bound to 207 * that specific port. Add the polymorphic transport structure to the 208 * system-wide pools of known ISAKMP transports. 209 */ 210 struct transport * 211 udp_encap_bind(const struct sockaddr *addr) 212 { 213 struct sockaddr *src; 214 215 src = malloc(SA_LEN(addr)); 216 if (!src) 217 return 0; 218 219 memcpy(src, addr, SA_LEN(addr)); 220 return udp_encap_make(src); 221 } 222 223 /* 224 * NAME is a section name found in the config database. Setup and return 225 * a transport useable to talk to the peer specified by that name. 226 */ 227 static struct transport * 228 udp_encap_create(char *name) 229 { 230 struct virtual_transport *v; 231 struct udp_transport *u; 232 struct transport *rv, *t; 233 struct sockaddr *dst, *addr; 234 struct conf_list *addr_list = 0; 235 struct conf_list_node *addr_node; 236 char *addr_str, *port_str; 237 238 port_str = conf_get_str(name, "Port"); /* XXX "Encap-port" ? */ 239 if (!port_str) 240 port_str = udp_encap_default_port; 241 if (!port_str) 242 port_str = UDP_ENCAP_DEFAULT_PORT_STR; 243 244 addr_str = conf_get_str(name, "Address"); 245 if (!addr_str) { 246 log_print("udp_encap_create: no address configured " 247 "for \"%s\"", name); 248 return 0; 249 } 250 if (text2sockaddr(addr_str, port_str, &dst, 0, 0)) { 251 log_print("udp_encap_create: address \"%s\" not understood", 252 addr_str); 253 return 0; 254 } 255 256 addr_str = conf_get_str(name, "Local-address"); 257 if (!addr_str) 258 addr_list = conf_get_list("General", "Listen-on"); 259 if (!addr_str && !addr_list) { 260 v = virtual_get_default(dst->sa_family); 261 u = (struct udp_transport *)v->encap; 262 263 if (!u) { 264 log_print("udp_encap_create: no default transport"); 265 rv = 0; 266 goto ret; 267 } else { 268 rv = udp_clone((struct transport *)u, dst); 269 if (rv) 270 rv->vtbl = &udp_encap_transport_vtbl; 271 goto ret; 272 } 273 } 274 275 if (addr_list) { 276 for (addr_node = TAILQ_FIRST(&addr_list->fields); 277 addr_node; addr_node = TAILQ_NEXT(addr_node, link)) 278 if (text2sockaddr(addr_node->field, port_str, 279 &addr, 0, 0) == 0) { 280 v = virtual_listen_lookup(addr); 281 free(addr); 282 if (v) { 283 addr_str = addr_node->field; 284 break; 285 } 286 } 287 if (!addr_str) { 288 log_print("udp_encap_create: " 289 "no matching listener found"); 290 rv = 0; 291 goto ret; 292 } 293 } 294 if (text2sockaddr(addr_str, port_str, &addr, 0, 0)) { 295 log_print("udp_encap_create: " 296 "address \"%s\" not understood", addr_str); 297 rv = 0; 298 goto ret; 299 } 300 v = virtual_listen_lookup(addr); 301 free(addr); 302 if (!v) { 303 log_print("udp_encap_create: " 304 "%s:%s must exist as a listener too", addr_str, port_str); 305 rv = 0; 306 goto ret; 307 } 308 t = (struct transport *)v; 309 rv = udp_clone(v->encap, dst); 310 if (rv) 311 rv->vtbl = &udp_encap_transport_vtbl; 312 313 ret: 314 if (addr_list) 315 conf_free_list(addr_list); 316 free(dst); 317 return rv; 318 } 319 320 /* Report transport-method specifics of the T transport. */ 321 void 322 udp_encap_report(struct transport *t) 323 { 324 struct udp_transport *u = (struct udp_transport *)t; 325 char *src = NULL, *dst = NULL; 326 in_port_t sport, dport; 327 328 if (sockaddr2text(u->src, &src, 0)) 329 return; 330 sport = sockaddr_port(u->src); 331 332 if (!u->dst || sockaddr2text(u->dst, &dst, 0)) 333 dst = 0; 334 dport = dst ? sockaddr_port(u->dst) : 0; 335 336 LOG_DBG ((LOG_REPORT, 0, "udp_encap_report: fd %d src %s:%u dst %s:%u", 337 u->s, src, ntohs(sport), dst ? dst : "*", ntohs(dport))); 338 339 free(dst); 340 free(src); 341 } 342 343 /* 344 * A message has arrived on transport T's socket. If T is single-ended, 345 * clone it into a double-ended transport which we will use from now on. 346 * Package the message as we want it and continue processing in the message 347 * module. 348 */ 349 static void 350 udp_encap_handle_message(struct transport *t) 351 { 352 struct udp_transport *u = (struct udp_transport *)t; 353 struct sockaddr_storage from; 354 struct message *msg; 355 u_int32_t len = sizeof from; 356 ssize_t n; 357 u_int8_t buf[UDP_SIZE]; 358 359 n = recvfrom(u->s, buf, UDP_SIZE, 0, (struct sockaddr *)&from, &len); 360 if (n == -1) { 361 log_error("recvfrom (%d, %p, %d, %d, %p, %p)", u->s, buf, 362 UDP_SIZE, 0, &from, &len); 363 return; 364 } 365 366 if (t->virtual == (struct transport *)virtual_get_default(AF_INET) || 367 t->virtual == (struct transport *)virtual_get_default(AF_INET6)) { 368 t->virtual->vtbl->reinit(); 369 370 /* 371 * As we don't know the actual destination address of the 372 * packet, we can't really deal with it. So, just ignore it 373 * and hope we catch the retransmission. 374 */ 375 return; 376 } 377 378 /* 379 * Make a specialized UDP transport structure out of the incoming 380 * transport and the address information we got from recvfrom(2). 381 */ 382 t = t->virtual->vtbl->clone(t->virtual, (struct sockaddr *)&from); 383 if (!t) 384 return; 385 386 /* Check NULL-ESP marker. */ 387 if (n < (ssize_t)sizeof(u_int32_t) || *(u_int32_t *)buf != 0) { 388 /* Should never happen. */ 389 log_print("udp_encap_handle_message: " 390 "Null-ESP marker not NULL or short message"); 391 return; 392 } 393 394 /* NAT-Keepalive messages should not be processed further. */ 395 n -= sizeof(u_int32_t); 396 if (n == 1 && buf[sizeof(u_int32_t)] == 0xFF) 397 return; 398 399 msg = message_alloc(t, buf + sizeof (u_int32_t), n); 400 if (!msg) { 401 log_error("failed to allocate message structure, dropping " 402 "packet received on transport %p", u); 403 return; 404 } 405 406 msg->flags |= MSG_NATT; 407 408 message_recv(msg); 409 } 410 411 /* 412 * Physically send the message MSG over its associated transport. 413 * Special: if 'msg' is NULL, send a NAT-T keepalive message. 414 */ 415 static int 416 udp_encap_send_message(struct message *msg, struct transport *t) 417 { 418 struct udp_transport *u = (struct udp_transport *)t; 419 struct msghdr m; 420 struct iovec *new_iov = 0, keepalive; 421 ssize_t n; 422 u_int32_t marker = 0; /* NULL-ESP Marker */ 423 424 if (msg) { 425 /* Construct new iov array, prefixing NULL-ESP Marker. */ 426 new_iov = (struct iovec *)calloc (msg->iovlen + 1, 427 sizeof *new_iov); 428 if (!new_iov) { 429 log_error ("udp_encap_send_message: " 430 "calloc (%lu, %lu) failed", 431 (unsigned long)msg->iovlen + 1, 432 (unsigned long)sizeof *new_iov); 433 return -1; 434 } 435 new_iov[0].iov_base = ▮ 436 new_iov[0].iov_len = IPSEC_SPI_SIZE; 437 memcpy (new_iov + 1, msg->iov, msg->iovlen * sizeof *new_iov); 438 } else { 439 marker = ~marker; 440 keepalive.iov_base = ▮ 441 keepalive.iov_len = 1; 442 } 443 444 /* 445 * Sending on connected sockets requires that no destination address is 446 * given, or else EISCONN will occur. 447 */ 448 m.msg_name = (caddr_t)u->dst; 449 m.msg_namelen = SA_LEN(u->dst); 450 m.msg_iov = msg ? new_iov : &keepalive; 451 m.msg_iovlen = msg ? msg->iovlen + 1 : 1; 452 m.msg_control = 0; 453 m.msg_controllen = 0; 454 m.msg_flags = 0; 455 n = sendmsg (u->s, &m, 0); 456 if (msg) 457 free (new_iov); 458 if (n == -1) { 459 /* XXX We should check whether the address has gone away */ 460 log_error ("sendmsg (%d, %p, %d)", u->s, &m, 0); 461 return -1; 462 } 463 return 0; 464 } 465