1 /* $OpenBSD: udp_usrreq.c,v 1.257 2019/12/06 14:43:14 tobhe Exp $ */ 2 /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1988, 1990, 1993 6 * The Regents of the University of California. 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 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 33 * 34 * NRL grants permission for redistribution and use in source and binary 35 * forms, with or without modification, of the software and documentation 36 * created at NRL provided that the following conditions are met: 37 * 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. All advertising materials mentioning features or use of this software 44 * must display the following acknowledgements: 45 * This product includes software developed by the University of 46 * California, Berkeley and its contributors. 47 * This product includes software developed at the Information 48 * Technology Division, US Naval Research Laboratory. 49 * 4. Neither the name of the NRL nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS 54 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 56 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR 57 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 58 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 59 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 60 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 61 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 62 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 63 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 * 65 * The views and conclusions contained in the software and documentation 66 * are those of the authors and should not be interpreted as representing 67 * official policies, either expressed or implied, of the US Naval 68 * Research Laboratory (NRL). 69 */ 70 71 #include <sys/param.h> 72 #include <sys/systm.h> 73 #include <sys/mbuf.h> 74 #include <sys/protosw.h> 75 #include <sys/socket.h> 76 #include <sys/socketvar.h> 77 #include <sys/sysctl.h> 78 #include <sys/domain.h> 79 80 #include <net/if.h> 81 #include <net/if_var.h> 82 #include <net/if_media.h> 83 #include <net/route.h> 84 85 #include <netinet/in.h> 86 #include <netinet/in_var.h> 87 #include <netinet/ip.h> 88 #include <netinet/in_pcb.h> 89 #include <netinet/ip_var.h> 90 #include <netinet/ip_icmp.h> 91 #include <netinet/udp.h> 92 #include <netinet/udp_var.h> 93 94 #ifdef IPSEC 95 #include <netinet/ip_ipsp.h> 96 #include <netinet/ip_esp.h> 97 #endif 98 99 #ifdef INET6 100 #include <netinet6/in6_var.h> 101 #include <netinet6/ip6_var.h> 102 #include <netinet6/ip6protosw.h> 103 #endif /* INET6 */ 104 105 #include "pf.h" 106 #if NPF > 0 107 #include <net/pfvar.h> 108 #endif 109 110 #ifdef PIPEX 111 #include <netinet/if_ether.h> 112 #include <net/pipex.h> 113 #endif 114 115 #include "vxlan.h" 116 #if NVXLAN > 0 117 #include <net/if_vxlan.h> 118 #endif 119 120 /* 121 * UDP protocol implementation. 122 * Per RFC 768, August, 1980. 123 */ 124 int udpcksum = 1; 125 126 u_int udp_sendspace = 9216; /* really max datagram size */ 127 u_int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); 128 /* 40 1K datagrams */ 129 130 int *udpctl_vars[UDPCTL_MAXID] = UDPCTL_VARS; 131 132 struct inpcbtable udbtable; 133 struct cpumem *udpcounters; 134 135 void udp_sbappend(struct inpcb *, struct mbuf *, struct ip *, 136 struct ip6_hdr *, int, struct udphdr *, struct sockaddr *, 137 u_int32_t); 138 int udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *); 139 void udp_notify(struct inpcb *, int); 140 int udp_sysctl_udpstat(void *, size_t *, void *); 141 142 #ifndef UDB_INITIAL_HASH_SIZE 143 #define UDB_INITIAL_HASH_SIZE 128 144 #endif 145 146 void 147 udp_init(void) 148 { 149 udpcounters = counters_alloc(udps_ncounters); 150 in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE); 151 } 152 153 int 154 udp_input(struct mbuf **mp, int *offp, int proto, int af) 155 { 156 struct mbuf *m = *mp; 157 int iphlen = *offp; 158 struct ip *ip = NULL; 159 struct udphdr *uh; 160 struct inpcb *inp = NULL; 161 struct ip save_ip; 162 int len; 163 u_int16_t savesum; 164 union { 165 struct sockaddr sa; 166 struct sockaddr_in sin; 167 #ifdef INET6 168 struct sockaddr_in6 sin6; 169 #endif /* INET6 */ 170 } srcsa, dstsa; 171 struct ip6_hdr *ip6 = NULL; 172 #ifdef IPSEC 173 struct m_tag *mtag; 174 struct tdb_ident *tdbi; 175 struct tdb *tdb; 176 int error, protoff; 177 #endif /* IPSEC */ 178 u_int32_t ipsecflowinfo = 0; 179 180 udpstat_inc(udps_ipackets); 181 182 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr)); 183 if (!uh) { 184 udpstat_inc(udps_hdrops); 185 return IPPROTO_DONE; 186 } 187 188 /* Check for illegal destination port 0 */ 189 if (uh->uh_dport == 0) { 190 udpstat_inc(udps_noport); 191 goto bad; 192 } 193 194 /* 195 * Make mbuf data length reflect UDP length. 196 * If not enough data to reflect UDP length, drop. 197 */ 198 len = ntohs((u_int16_t)uh->uh_ulen); 199 switch (af) { 200 case AF_INET: 201 if (m->m_pkthdr.len - iphlen != len) { 202 if (len > (m->m_pkthdr.len - iphlen) || 203 len < sizeof(struct udphdr)) { 204 udpstat_inc(udps_badlen); 205 goto bad; 206 } 207 m_adj(m, len - (m->m_pkthdr.len - iphlen)); 208 } 209 ip = mtod(m, struct ip *); 210 /* 211 * Save a copy of the IP header in case we want restore it 212 * for sending an ICMP error message in response. 213 */ 214 save_ip = *ip; 215 break; 216 #ifdef INET6 217 case AF_INET6: 218 /* jumbograms */ 219 if (len == 0 && m->m_pkthdr.len - iphlen > 0xffff) 220 len = m->m_pkthdr.len - iphlen; 221 if (len != m->m_pkthdr.len - iphlen) { 222 udpstat_inc(udps_badlen); 223 goto bad; 224 } 225 ip6 = mtod(m, struct ip6_hdr *); 226 break; 227 #endif /* INET6 */ 228 default: 229 unhandled_af(af); 230 } 231 232 /* 233 * Checksum extended UDP header and data. 234 * from W.R.Stevens: check incoming udp cksums even if 235 * udpcksum is not set. 236 */ 237 savesum = uh->uh_sum; 238 if (uh->uh_sum == 0) { 239 udpstat_inc(udps_nosum); 240 #ifdef INET6 241 /* 242 * In IPv6, the UDP checksum is ALWAYS used. 243 */ 244 if (ip6) 245 goto bad; 246 #endif /* INET6 */ 247 } else { 248 if ((m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_OK) == 0) { 249 if (m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_BAD) { 250 udpstat_inc(udps_badsum); 251 goto bad; 252 } 253 udpstat_inc(udps_inswcsum); 254 255 if (ip) 256 uh->uh_sum = in4_cksum(m, IPPROTO_UDP, 257 iphlen, len); 258 #ifdef INET6 259 else if (ip6) 260 uh->uh_sum = in6_cksum(m, IPPROTO_UDP, 261 iphlen, len); 262 #endif /* INET6 */ 263 if (uh->uh_sum != 0) { 264 udpstat_inc(udps_badsum); 265 goto bad; 266 } 267 } 268 } 269 270 #ifdef IPSEC 271 if (udpencap_enable && udpencap_port && esp_enable && 272 #if NPF > 0 273 !(m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) && 274 #endif 275 uh->uh_dport == htons(udpencap_port)) { 276 u_int32_t spi; 277 int skip = iphlen + sizeof(struct udphdr); 278 279 if (m->m_pkthdr.len - skip < sizeof(u_int32_t)) { 280 /* packet too short */ 281 m_freem(m); 282 return IPPROTO_DONE; 283 } 284 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi); 285 /* 286 * decapsulate if the SPI is not zero, otherwise pass 287 * to userland 288 */ 289 if (spi != 0) { 290 if ((m = *mp = m_pullup(m, skip)) == NULL) { 291 udpstat_inc(udps_hdrops); 292 return IPPROTO_DONE; 293 } 294 295 /* remove the UDP header */ 296 bcopy(mtod(m, u_char *), 297 mtod(m, u_char *) + sizeof(struct udphdr), iphlen); 298 m_adj(m, sizeof(struct udphdr)); 299 skip -= sizeof(struct udphdr); 300 301 espstat_inc(esps_udpencin); 302 protoff = af == AF_INET ? offsetof(struct ip, ip_p) : 303 offsetof(struct ip6_hdr, ip6_nxt); 304 ipsec_common_input(m, skip, protoff, 305 af, IPPROTO_ESP, 1); 306 return IPPROTO_DONE; 307 } 308 } 309 #endif 310 311 switch (af) { 312 case AF_INET: 313 bzero(&srcsa, sizeof(struct sockaddr_in)); 314 srcsa.sin.sin_len = sizeof(struct sockaddr_in); 315 srcsa.sin.sin_family = AF_INET; 316 srcsa.sin.sin_port = uh->uh_sport; 317 srcsa.sin.sin_addr = ip->ip_src; 318 319 bzero(&dstsa, sizeof(struct sockaddr_in)); 320 dstsa.sin.sin_len = sizeof(struct sockaddr_in); 321 dstsa.sin.sin_family = AF_INET; 322 dstsa.sin.sin_port = uh->uh_dport; 323 dstsa.sin.sin_addr = ip->ip_dst; 324 break; 325 #ifdef INET6 326 case AF_INET6: 327 bzero(&srcsa, sizeof(struct sockaddr_in6)); 328 srcsa.sin6.sin6_len = sizeof(struct sockaddr_in6); 329 srcsa.sin6.sin6_family = AF_INET6; 330 srcsa.sin6.sin6_port = uh->uh_sport; 331 #if 0 /*XXX inbound flowinfo */ 332 srcsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ip6->ip6_flow; 333 #endif 334 /* KAME hack: recover scopeid */ 335 in6_recoverscope(&srcsa.sin6, &ip6->ip6_src); 336 337 bzero(&dstsa, sizeof(struct sockaddr_in6)); 338 dstsa.sin6.sin6_len = sizeof(struct sockaddr_in6); 339 dstsa.sin6.sin6_family = AF_INET6; 340 dstsa.sin6.sin6_port = uh->uh_dport; 341 #if 0 /*XXX inbound flowinfo */ 342 dstsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ip6->ip6_flow; 343 #endif 344 /* KAME hack: recover scopeid */ 345 in6_recoverscope(&dstsa.sin6, &ip6->ip6_dst); 346 break; 347 #endif /* INET6 */ 348 } 349 350 #if NVXLAN > 0 351 if (vxlan_enable > 0 && 352 #if NPF > 0 353 !(m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) && 354 #endif 355 vxlan_lookup(m, uh, iphlen, &srcsa.sa, &dstsa.sa) != 0) 356 return IPPROTO_DONE; 357 #endif 358 359 if (m->m_flags & (M_BCAST|M_MCAST)) { 360 struct inpcb *last; 361 /* 362 * Deliver a multicast or broadcast datagram to *all* sockets 363 * for which the local and remote addresses and ports match 364 * those of the incoming datagram. This allows more than 365 * one process to receive multi/broadcasts on the same port. 366 * (This really ought to be done for unicast datagrams as 367 * well, but that would cause problems with existing 368 * applications that open both address-specific sockets and 369 * a wildcard socket listening to the same port -- they would 370 * end up receiving duplicates of every unicast datagram. 371 * Those applications open the multiple sockets to overcome an 372 * inadequacy of the UDP socket interface, but for backwards 373 * compatibility we avoid the problem here rather than 374 * fixing the interface. Maybe 4.5BSD will remedy this?) 375 */ 376 377 /* 378 * Locate pcb(s) for datagram. 379 * (Algorithm copied from raw_intr().) 380 */ 381 last = NULL; 382 NET_ASSERT_LOCKED(); 383 TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) { 384 if (inp->inp_socket->so_state & SS_CANTRCVMORE) 385 continue; 386 #ifdef INET6 387 /* don't accept it if AF does not match */ 388 if (ip6 && !(inp->inp_flags & INP_IPV6)) 389 continue; 390 if (!ip6 && (inp->inp_flags & INP_IPV6)) 391 continue; 392 #endif 393 if (rtable_l2(inp->inp_rtableid) != 394 rtable_l2(m->m_pkthdr.ph_rtableid)) 395 continue; 396 if (inp->inp_lport != uh->uh_dport) 397 continue; 398 #ifdef INET6 399 if (ip6) { 400 if (inp->inp_ip6_minhlim && 401 inp->inp_ip6_minhlim > ip6->ip6_hlim) 402 continue; 403 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) 404 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, 405 &ip6->ip6_dst)) 406 continue; 407 } else 408 #endif /* INET6 */ 409 { 410 if (inp->inp_ip_minttl && 411 inp->inp_ip_minttl > ip->ip_ttl) 412 continue; 413 414 if (inp->inp_laddr.s_addr != INADDR_ANY) { 415 if (inp->inp_laddr.s_addr != 416 ip->ip_dst.s_addr) 417 continue; 418 } 419 } 420 #ifdef INET6 421 if (ip6) { 422 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) 423 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, 424 &ip6->ip6_src) || 425 inp->inp_fport != uh->uh_sport) 426 continue; 427 } else 428 #endif /* INET6 */ 429 if (inp->inp_faddr.s_addr != INADDR_ANY) { 430 if (inp->inp_faddr.s_addr != 431 ip->ip_src.s_addr || 432 inp->inp_fport != uh->uh_sport) 433 continue; 434 } 435 436 if (last != NULL) { 437 struct mbuf *n; 438 439 n = m_copym(m, 0, M_COPYALL, M_NOWAIT); 440 if (n != NULL) { 441 udp_sbappend(last, n, ip, ip6, iphlen, 442 uh, &srcsa.sa, 0); 443 } 444 } 445 last = inp; 446 /* 447 * Don't look for additional matches if this one does 448 * not have either the SO_REUSEPORT or SO_REUSEADDR 449 * socket options set. This heuristic avoids searching 450 * through all pcbs in the common case of a non-shared 451 * port. It assumes that an application will never 452 * clear these options after setting them. 453 */ 454 if ((last->inp_socket->so_options & (SO_REUSEPORT | 455 SO_REUSEADDR)) == 0) 456 break; 457 } 458 459 if (last == NULL) { 460 /* 461 * No matching pcb found; discard datagram. 462 * (No need to send an ICMP Port Unreachable 463 * for a broadcast or multicast datgram.) 464 */ 465 udpstat_inc(udps_noportbcast); 466 goto bad; 467 } 468 469 udp_sbappend(last, m, ip, ip6, iphlen, uh, &srcsa.sa, 0); 470 return IPPROTO_DONE; 471 } 472 /* 473 * Locate pcb for datagram. 474 */ 475 #if NPF > 0 476 inp = pf_inp_lookup(m); 477 #endif 478 if (inp == NULL) { 479 #ifdef INET6 480 if (ip6) 481 inp = in6_pcbhashlookup(&udbtable, &ip6->ip6_src, 482 uh->uh_sport, &ip6->ip6_dst, uh->uh_dport, 483 m->m_pkthdr.ph_rtableid); 484 else 485 #endif /* INET6 */ 486 inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport, 487 ip->ip_dst, uh->uh_dport, m->m_pkthdr.ph_rtableid); 488 } 489 if (inp == 0) { 490 udpstat_inc(udps_pcbhashmiss); 491 #ifdef INET6 492 if (ip6) { 493 inp = in6_pcblookup_listen(&udbtable, &ip6->ip6_dst, 494 uh->uh_dport, m, m->m_pkthdr.ph_rtableid); 495 } else 496 #endif /* INET6 */ 497 inp = in_pcblookup_listen(&udbtable, ip->ip_dst, 498 uh->uh_dport, m, m->m_pkthdr.ph_rtableid); 499 } 500 501 #ifdef IPSEC 502 if (ipsec_in_use) { 503 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); 504 if (mtag != NULL) { 505 tdbi = (struct tdb_ident *)(mtag + 1); 506 tdb = gettdb(tdbi->rdomain, tdbi->spi, 507 &tdbi->dst, tdbi->proto); 508 } else 509 tdb = NULL; 510 ipsp_spd_lookup(m, af, iphlen, &error, 511 IPSP_DIRECTION_IN, tdb, inp, 0); 512 if (error) { 513 udpstat_inc(udps_nosec); 514 goto bad; 515 } 516 /* create ipsec options while we know that tdb cannot be modified */ 517 if (tdb && tdb->tdb_ids) 518 ipsecflowinfo = tdb->tdb_ids->id_flow; 519 } 520 #endif /*IPSEC */ 521 522 if (inp == 0) { 523 udpstat_inc(udps_noport); 524 if (m->m_flags & (M_BCAST | M_MCAST)) { 525 udpstat_inc(udps_noportbcast); 526 goto bad; 527 } 528 #ifdef INET6 529 if (ip6) { 530 uh->uh_sum = savesum; 531 icmp6_error(m, ICMP6_DST_UNREACH, 532 ICMP6_DST_UNREACH_NOPORT,0); 533 } else 534 #endif /* INET6 */ 535 { 536 *ip = save_ip; 537 uh->uh_sum = savesum; 538 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 539 0, 0); 540 } 541 return IPPROTO_DONE; 542 } 543 544 KASSERT(sotoinpcb(inp->inp_socket) == inp); 545 soassertlocked(inp->inp_socket); 546 547 #ifdef INET6 548 if (ip6 && inp->inp_ip6_minhlim && 549 inp->inp_ip6_minhlim > ip6->ip6_hlim) { 550 goto bad; 551 } else 552 #endif 553 if (ip && inp->inp_ip_minttl && 554 inp->inp_ip_minttl > ip->ip_ttl) { 555 goto bad; 556 } 557 558 #if NPF > 0 559 if (inp->inp_socket->so_state & SS_ISCONNECTED) 560 pf_inp_link(m, inp); 561 #endif 562 563 #ifdef PIPEX 564 if (pipex_enable && inp->inp_pipex) { 565 struct pipex_session *session; 566 int off = iphlen + sizeof(struct udphdr); 567 if ((session = pipex_l2tp_lookup_session(m, off)) != NULL) { 568 if ((m = *mp = pipex_l2tp_input(m, off, session, 569 ipsecflowinfo)) == NULL) { 570 /* the packet is handled by PIPEX */ 571 return IPPROTO_DONE; 572 } 573 } 574 } 575 #endif 576 577 udp_sbappend(inp, m, ip, ip6, iphlen, uh, &srcsa.sa, ipsecflowinfo); 578 return IPPROTO_DONE; 579 bad: 580 m_freem(m); 581 return IPPROTO_DONE; 582 } 583 584 void 585 udp_sbappend(struct inpcb *inp, struct mbuf *m, struct ip *ip, 586 struct ip6_hdr *ip6, int iphlen, struct udphdr *uh, 587 struct sockaddr *srcaddr, u_int32_t ipsecflowinfo) 588 { 589 struct socket *so = inp->inp_socket; 590 struct mbuf *opts = NULL; 591 592 #ifdef INET6 593 if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS || 594 so->so_options & SO_TIMESTAMP)) 595 ip6_savecontrol(inp, m, &opts); 596 #endif /* INET6 */ 597 if (ip && (inp->inp_flags & INP_CONTROLOPTS || 598 so->so_options & SO_TIMESTAMP)) 599 ip_savecontrol(inp, &opts, ip, m); 600 #ifdef INET6 601 if (ip6 && (inp->inp_flags & IN6P_RECVDSTPORT)) { 602 struct mbuf **mp = &opts; 603 604 while (*mp) 605 mp = &(*mp)->m_next; 606 *mp = sbcreatecontrol((caddr_t)&uh->uh_dport, sizeof(u_int16_t), 607 IPV6_RECVDSTPORT, IPPROTO_IPV6); 608 } 609 #endif /* INET6 */ 610 if (ip && (inp->inp_flags & INP_RECVDSTPORT)) { 611 struct mbuf **mp = &opts; 612 613 while (*mp) 614 mp = &(*mp)->m_next; 615 *mp = sbcreatecontrol((caddr_t)&uh->uh_dport, sizeof(u_int16_t), 616 IP_RECVDSTPORT, IPPROTO_IP); 617 } 618 #ifdef IPSEC 619 if (ipsecflowinfo && (inp->inp_flags & INP_IPSECFLOWINFO)) { 620 struct mbuf **mp = &opts; 621 622 while (*mp) 623 mp = &(*mp)->m_next; 624 *mp = sbcreatecontrol((caddr_t)&ipsecflowinfo, 625 sizeof(u_int32_t), IP_IPSECFLOWINFO, IPPROTO_IP); 626 } 627 #endif 628 m_adj(m, iphlen + sizeof(struct udphdr)); 629 if (sbappendaddr(so, &so->so_rcv, srcaddr, m, opts) == 0) { 630 udpstat_inc(udps_fullsock); 631 m_freem(m); 632 m_freem(opts); 633 return; 634 } 635 sorwakeup(so); 636 } 637 638 /* 639 * Notify a udp user of an asynchronous error; 640 * just wake up so that he can collect error status. 641 */ 642 void 643 udp_notify(struct inpcb *inp, int errno) 644 { 645 inp->inp_socket->so_error = errno; 646 sorwakeup(inp->inp_socket); 647 sowwakeup(inp->inp_socket); 648 } 649 650 #ifdef INET6 651 void 652 udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d) 653 { 654 struct udphdr uh; 655 struct sockaddr_in6 sa6; 656 struct ip6_hdr *ip6; 657 struct mbuf *m; 658 int off; 659 void *cmdarg; 660 struct ip6ctlparam *ip6cp = NULL; 661 struct udp_portonly { 662 u_int16_t uh_sport; 663 u_int16_t uh_dport; 664 } *uhp; 665 void (*notify)(struct inpcb *, int) = udp_notify; 666 667 if (sa == NULL) 668 return; 669 if (sa->sa_family != AF_INET6 || 670 sa->sa_len != sizeof(struct sockaddr_in6)) 671 return; 672 673 if ((unsigned)cmd >= PRC_NCMDS) 674 return; 675 if (PRC_IS_REDIRECT(cmd)) 676 notify = in_rtchange, d = NULL; 677 else if (cmd == PRC_HOSTDEAD) 678 d = NULL; 679 else if (cmd == PRC_MSGSIZE) 680 ; /* special code is present, see below */ 681 else if (inet6ctlerrmap[cmd] == 0) 682 return; 683 684 /* if the parameter is from icmp6, decode it. */ 685 if (d != NULL) { 686 ip6cp = (struct ip6ctlparam *)d; 687 m = ip6cp->ip6c_m; 688 ip6 = ip6cp->ip6c_ip6; 689 off = ip6cp->ip6c_off; 690 cmdarg = ip6cp->ip6c_cmdarg; 691 } else { 692 m = NULL; 693 ip6 = NULL; 694 cmdarg = NULL; 695 /* XXX: translate addresses into internal form */ 696 sa6 = *satosin6(sa); 697 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL)) { 698 /* should be impossible */ 699 return; 700 } 701 } 702 703 if (ip6cp && ip6cp->ip6c_finaldst) { 704 bzero(&sa6, sizeof(sa6)); 705 sa6.sin6_family = AF_INET6; 706 sa6.sin6_len = sizeof(sa6); 707 sa6.sin6_addr = *ip6cp->ip6c_finaldst; 708 /* XXX: assuming M is valid in this case */ 709 sa6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, 710 ip6cp->ip6c_finaldst); 711 if (in6_embedscope(ip6cp->ip6c_finaldst, &sa6, NULL)) { 712 /* should be impossible */ 713 return; 714 } 715 } else { 716 /* XXX: translate addresses into internal form */ 717 sa6 = *satosin6(sa); 718 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL)) { 719 /* should be impossible */ 720 return; 721 } 722 } 723 724 if (ip6) { 725 /* 726 * XXX: We assume that when IPV6 is non NULL, 727 * M and OFF are valid. 728 */ 729 struct sockaddr_in6 sa6_src; 730 731 /* check if we can safely examine src and dst ports */ 732 if (m->m_pkthdr.len < off + sizeof(*uhp)) 733 return; 734 735 bzero(&uh, sizeof(uh)); 736 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh); 737 738 bzero(&sa6_src, sizeof(sa6_src)); 739 sa6_src.sin6_family = AF_INET6; 740 sa6_src.sin6_len = sizeof(sa6_src); 741 sa6_src.sin6_addr = ip6->ip6_src; 742 sa6_src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx, 743 &ip6->ip6_src); 744 if (in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL)) { 745 /* should be impossible */ 746 return; 747 } 748 749 if (cmd == PRC_MSGSIZE) { 750 int valid = 0; 751 752 /* 753 * Check to see if we have a valid UDP socket 754 * corresponding to the address in the ICMPv6 message 755 * payload. 756 */ 757 if (in6_pcbhashlookup(&udbtable, &sa6.sin6_addr, 758 uh.uh_dport, &sa6_src.sin6_addr, uh.uh_sport, 759 rdomain)) 760 valid = 1; 761 #if 0 762 /* 763 * As the use of sendto(2) is fairly popular, 764 * we may want to allow non-connected pcb too. 765 * But it could be too weak against attacks... 766 * We should at least check if the local address (= s) 767 * is really ours. 768 */ 769 else if (in6_pcblookup_listen(&udbtable, 770 &sa6_src.sin6_addr, uh.uh_sport, NULL, 771 rdomain)) 772 valid = 1; 773 #endif 774 775 /* 776 * Depending on the value of "valid" and routing table 777 * size (mtudisc_{hi,lo}wat), we will: 778 * - recalculate the new MTU and create the 779 * corresponding routing entry, or 780 * - ignore the MTU change notification. 781 */ 782 icmp6_mtudisc_update((struct ip6ctlparam *)d, valid); 783 784 /* 785 * regardless of if we called icmp6_mtudisc_update(), 786 * we need to call in6_pcbnotify(), to notify path 787 * MTU change to the userland (2292bis-02), because 788 * some unconnected sockets may share the same 789 * destination and want to know the path MTU. 790 */ 791 } 792 793 (void) in6_pcbnotify(&udbtable, &sa6, uh.uh_dport, 794 &sa6_src, uh.uh_sport, rdomain, cmd, cmdarg, notify); 795 } else { 796 (void) in6_pcbnotify(&udbtable, &sa6, 0, 797 &sa6_any, 0, rdomain, cmd, cmdarg, notify); 798 } 799 } 800 #endif 801 802 void 803 udp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) 804 { 805 struct ip *ip = v; 806 struct udphdr *uhp; 807 struct in_addr faddr; 808 struct inpcb *inp; 809 void (*notify)(struct inpcb *, int) = udp_notify; 810 int errno; 811 812 if (sa == NULL) 813 return; 814 if (sa->sa_family != AF_INET || 815 sa->sa_len != sizeof(struct sockaddr_in)) 816 return; 817 faddr = satosin(sa)->sin_addr; 818 if (faddr.s_addr == INADDR_ANY) 819 return; 820 821 if ((unsigned)cmd >= PRC_NCMDS) 822 return; 823 errno = inetctlerrmap[cmd]; 824 if (PRC_IS_REDIRECT(cmd)) 825 notify = in_rtchange, ip = 0; 826 else if (cmd == PRC_HOSTDEAD) 827 ip = 0; 828 else if (errno == 0) 829 return; 830 if (ip) { 831 uhp = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 832 833 #ifdef IPSEC 834 /* PMTU discovery for udpencap */ 835 if (cmd == PRC_MSGSIZE && ip_mtudisc && udpencap_enable && 836 udpencap_port && uhp->uh_sport == htons(udpencap_port)) { 837 udpencap_ctlinput(cmd, sa, rdomain, v); 838 return; 839 } 840 #endif 841 inp = in_pcbhashlookup(&udbtable, 842 ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport, 843 rdomain); 844 if (inp && inp->inp_socket != NULL) 845 notify(inp, errno); 846 } else 847 in_pcbnotifyall(&udbtable, sa, rdomain, errno, notify); 848 } 849 850 int 851 udp_output(struct inpcb *inp, struct mbuf *m, struct mbuf *addr, 852 struct mbuf *control) 853 { 854 struct sockaddr_in *sin = NULL; 855 struct udpiphdr *ui; 856 u_int32_t ipsecflowinfo = 0; 857 struct sockaddr_in src_sin; 858 int len = m->m_pkthdr.len; 859 struct in_addr *laddr; 860 int error = 0; 861 862 #ifdef DIAGNOSTIC 863 if ((inp->inp_flags & INP_IPV6) != 0) 864 panic("IPv6 inpcb to %s", __func__); 865 #endif 866 867 /* 868 * Compute the packet length of the IP header, and 869 * punt if the length looks bogus. 870 */ 871 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) { 872 error = EMSGSIZE; 873 goto release; 874 } 875 876 memset(&src_sin, 0, sizeof(src_sin)); 877 878 if (control) { 879 u_int clen; 880 struct cmsghdr *cm; 881 caddr_t cmsgs; 882 883 /* 884 * XXX: Currently, we assume all the optional information is 885 * stored in a single mbuf. 886 */ 887 if (control->m_next) { 888 error = EINVAL; 889 goto release; 890 } 891 892 clen = control->m_len; 893 cmsgs = mtod(control, caddr_t); 894 do { 895 if (clen < CMSG_LEN(0)) { 896 error = EINVAL; 897 goto release; 898 } 899 cm = (struct cmsghdr *)cmsgs; 900 if (cm->cmsg_len < CMSG_LEN(0) || 901 CMSG_ALIGN(cm->cmsg_len) > clen) { 902 error = EINVAL; 903 goto release; 904 } 905 #ifdef IPSEC 906 if ((inp->inp_flags & INP_IPSECFLOWINFO) != 0 && 907 cm->cmsg_len == CMSG_LEN(sizeof(ipsecflowinfo)) && 908 cm->cmsg_level == IPPROTO_IP && 909 cm->cmsg_type == IP_IPSECFLOWINFO) { 910 ipsecflowinfo = *(u_int32_t *)CMSG_DATA(cm); 911 } else 912 #endif 913 if (cm->cmsg_len == CMSG_LEN(sizeof(struct in_addr)) && 914 cm->cmsg_level == IPPROTO_IP && 915 cm->cmsg_type == IP_SENDSRCADDR) { 916 memcpy(&src_sin.sin_addr, CMSG_DATA(cm), 917 sizeof(struct in_addr)); 918 src_sin.sin_family = AF_INET; 919 src_sin.sin_len = sizeof(src_sin); 920 /* no check on reuse when sin->sin_port == 0 */ 921 if ((error = in_pcbaddrisavail(inp, &src_sin, 922 0, curproc))) 923 goto release; 924 } 925 clen -= CMSG_ALIGN(cm->cmsg_len); 926 cmsgs += CMSG_ALIGN(cm->cmsg_len); 927 } while (clen); 928 } 929 930 if (addr) { 931 if ((error = in_nam2sin(addr, &sin))) 932 goto release; 933 if (sin->sin_port == 0) { 934 error = EADDRNOTAVAIL; 935 goto release; 936 } 937 if (inp->inp_faddr.s_addr != INADDR_ANY) { 938 error = EISCONN; 939 goto release; 940 } 941 error = in_pcbselsrc(&laddr, sin, inp); 942 if (error) 943 goto release; 944 945 if (inp->inp_lport == 0) { 946 error = in_pcbbind(inp, NULL, curproc); 947 if (error) 948 goto release; 949 } 950 951 if (src_sin.sin_len > 0 && 952 src_sin.sin_addr.s_addr != INADDR_ANY && 953 src_sin.sin_addr.s_addr != inp->inp_laddr.s_addr) { 954 src_sin.sin_port = inp->inp_lport; 955 if (inp->inp_laddr.s_addr != INADDR_ANY && 956 (error = 957 in_pcbaddrisavail(inp, &src_sin, 0, curproc))) 958 goto release; 959 laddr = &src_sin.sin_addr; 960 } 961 } else { 962 if (inp->inp_faddr.s_addr == INADDR_ANY) { 963 error = ENOTCONN; 964 goto release; 965 } 966 laddr = &inp->inp_laddr; 967 } 968 969 /* 970 * Calculate data length and get a mbuf 971 * for UDP and IP headers. 972 */ 973 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); 974 if (m == NULL) { 975 error = ENOBUFS; 976 goto bail; 977 } 978 979 /* 980 * Fill in mbuf with extended UDP header 981 * and addresses and length put into network format. 982 */ 983 ui = mtod(m, struct udpiphdr *); 984 bzero(ui->ui_x1, sizeof ui->ui_x1); 985 ui->ui_pr = IPPROTO_UDP; 986 ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr)); 987 ui->ui_src = *laddr; 988 ui->ui_dst = sin ? sin->sin_addr : inp->inp_faddr; 989 ui->ui_sport = inp->inp_lport; 990 ui->ui_dport = sin ? sin->sin_port : inp->inp_fport; 991 ui->ui_ulen = ui->ui_len; 992 ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len); 993 ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; 994 ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; 995 if (udpcksum) 996 m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT; 997 998 udpstat_inc(udps_opackets); 999 1000 /* force routing table */ 1001 m->m_pkthdr.ph_rtableid = inp->inp_rtableid; 1002 1003 #if NPF > 0 1004 if (inp->inp_socket->so_state & SS_ISCONNECTED) 1005 pf_mbuf_link_inpcb(m, inp); 1006 #endif 1007 1008 error = ip_output(m, inp->inp_options, &inp->inp_route, 1009 (inp->inp_socket->so_options & SO_BROADCAST), inp->inp_moptions, 1010 inp, ipsecflowinfo); 1011 1012 bail: 1013 m_freem(control); 1014 return (error); 1015 1016 release: 1017 m_freem(m); 1018 goto bail; 1019 } 1020 1021 /*ARGSUSED*/ 1022 int 1023 udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr, 1024 struct mbuf *control, struct proc *p) 1025 { 1026 struct inpcb *inp; 1027 int error = 0; 1028 1029 if (req == PRU_CONTROL) { 1030 #ifdef INET6 1031 if (sotopf(so) == PF_INET6) 1032 return (in6_control(so, (u_long)m, (caddr_t)addr, 1033 (struct ifnet *)control)); 1034 else 1035 #endif /* INET6 */ 1036 return (in_control(so, (u_long)m, (caddr_t)addr, 1037 (struct ifnet *)control)); 1038 } 1039 1040 soassertlocked(so); 1041 1042 inp = sotoinpcb(so); 1043 if (inp == NULL) { 1044 error = EINVAL; 1045 goto release; 1046 } 1047 1048 /* 1049 * Note: need to block udp_input while changing 1050 * the udp pcb queue and/or pcb addresses. 1051 */ 1052 switch (req) { 1053 1054 case PRU_BIND: 1055 error = in_pcbbind(inp, addr, p); 1056 break; 1057 1058 case PRU_LISTEN: 1059 error = EOPNOTSUPP; 1060 break; 1061 1062 case PRU_CONNECT: 1063 #ifdef INET6 1064 if (inp->inp_flags & INP_IPV6) { 1065 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) { 1066 error = EISCONN; 1067 break; 1068 } 1069 error = in6_pcbconnect(inp, addr); 1070 } else 1071 #endif /* INET6 */ 1072 { 1073 if (inp->inp_faddr.s_addr != INADDR_ANY) { 1074 error = EISCONN; 1075 break; 1076 } 1077 error = in_pcbconnect(inp, addr); 1078 } 1079 1080 if (error == 0) 1081 soisconnected(so); 1082 break; 1083 1084 case PRU_CONNECT2: 1085 error = EOPNOTSUPP; 1086 break; 1087 1088 case PRU_ACCEPT: 1089 error = EOPNOTSUPP; 1090 break; 1091 1092 case PRU_DISCONNECT: 1093 #ifdef INET6 1094 if (inp->inp_flags & INP_IPV6) { 1095 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) { 1096 error = ENOTCONN; 1097 break; 1098 } 1099 } else 1100 #endif /* INET6 */ 1101 { 1102 if (inp->inp_faddr.s_addr == INADDR_ANY) { 1103 error = ENOTCONN; 1104 break; 1105 } 1106 } 1107 1108 #ifdef INET6 1109 if (inp->inp_flags & INP_IPV6) 1110 inp->inp_laddr6 = in6addr_any; 1111 else 1112 #endif /* INET6 */ 1113 inp->inp_laddr.s_addr = INADDR_ANY; 1114 in_pcbdisconnect(inp); 1115 1116 so->so_state &= ~SS_ISCONNECTED; /* XXX */ 1117 break; 1118 1119 case PRU_SHUTDOWN: 1120 socantsendmore(so); 1121 break; 1122 1123 case PRU_SEND: 1124 #ifdef PIPEX 1125 if (inp->inp_pipex) { 1126 struct pipex_session *session; 1127 1128 if (addr != NULL) 1129 session = 1130 pipex_l2tp_userland_lookup_session(m, 1131 mtod(addr, struct sockaddr *)); 1132 else 1133 #ifdef INET6 1134 if (inp->inp_flags & INP_IPV6) 1135 session = 1136 pipex_l2tp_userland_lookup_session_ipv6( 1137 m, inp->inp_faddr6); 1138 else 1139 #endif 1140 session = 1141 pipex_l2tp_userland_lookup_session_ipv4( 1142 m, inp->inp_faddr); 1143 if (session != NULL) 1144 if ((m = pipex_l2tp_userland_output( 1145 m, session)) == NULL) { 1146 error = ENOMEM; 1147 goto release; 1148 } 1149 } 1150 #endif 1151 1152 #ifdef INET6 1153 if (inp->inp_flags & INP_IPV6) 1154 error = udp6_output(inp, m, addr, control); 1155 else 1156 #endif 1157 error = udp_output(inp, m, addr, control); 1158 return (error); 1159 1160 case PRU_ABORT: 1161 soisdisconnected(so); 1162 in_pcbdetach(inp); 1163 break; 1164 1165 case PRU_SOCKADDR: 1166 #ifdef INET6 1167 if (inp->inp_flags & INP_IPV6) 1168 in6_setsockaddr(inp, addr); 1169 else 1170 #endif /* INET6 */ 1171 in_setsockaddr(inp, addr); 1172 break; 1173 1174 case PRU_PEERADDR: 1175 #ifdef INET6 1176 if (inp->inp_flags & INP_IPV6) 1177 in6_setpeeraddr(inp, addr); 1178 else 1179 #endif /* INET6 */ 1180 in_setpeeraddr(inp, addr); 1181 break; 1182 1183 case PRU_SENSE: 1184 /* 1185 * stat: don't bother with a blocksize. 1186 */ 1187 /* 1188 * Perhaps Path MTU might be returned for a connected 1189 * UDP socket in this case. 1190 */ 1191 break; 1192 1193 case PRU_SENDOOB: 1194 case PRU_FASTTIMO: 1195 case PRU_SLOWTIMO: 1196 case PRU_PROTORCV: 1197 case PRU_PROTOSEND: 1198 case PRU_RCVD: 1199 case PRU_RCVOOB: 1200 error = EOPNOTSUPP; 1201 break; 1202 1203 default: 1204 panic("udp_usrreq"); 1205 } 1206 release: 1207 if (req != PRU_RCVD && req != PRU_RCVOOB && req != PRU_SENSE) { 1208 m_freem(control); 1209 m_freem(m); 1210 } 1211 return (error); 1212 } 1213 1214 int 1215 udp_attach(struct socket *so, int proto) 1216 { 1217 int error; 1218 1219 if (so->so_pcb != NULL) 1220 return EINVAL; 1221 1222 if ((error = soreserve(so, udp_sendspace, udp_recvspace))) 1223 return error; 1224 1225 NET_ASSERT_LOCKED(); 1226 if ((error = in_pcballoc(so, &udbtable))) 1227 return error; 1228 #ifdef INET6 1229 if (sotoinpcb(so)->inp_flags & INP_IPV6) 1230 sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim; 1231 else 1232 #endif /* INET6 */ 1233 sotoinpcb(so)->inp_ip.ip_ttl = ip_defttl; 1234 return 0; 1235 } 1236 1237 int 1238 udp_detach(struct socket *so) 1239 { 1240 struct inpcb *inp; 1241 1242 soassertlocked(so); 1243 1244 inp = sotoinpcb(so); 1245 if (inp == NULL) 1246 return (EINVAL); 1247 1248 in_pcbdetach(inp); 1249 return (0); 1250 } 1251 1252 /* 1253 * Sysctl for udp variables. 1254 */ 1255 int 1256 udp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 1257 size_t newlen) 1258 { 1259 int error; 1260 1261 /* All sysctl names at this level are terminal. */ 1262 if (namelen != 1) 1263 return (ENOTDIR); 1264 1265 switch (name[0]) { 1266 case UDPCTL_BADDYNAMIC: 1267 NET_LOCK(); 1268 error = sysctl_struct(oldp, oldlenp, newp, newlen, 1269 baddynamicports.udp, sizeof(baddynamicports.udp)); 1270 NET_UNLOCK(); 1271 return (error); 1272 1273 case UDPCTL_ROOTONLY: 1274 if (newp && securelevel > 0) 1275 return (EPERM); 1276 NET_LOCK(); 1277 error = sysctl_struct(oldp, oldlenp, newp, newlen, 1278 rootonlyports.udp, sizeof(rootonlyports.udp)); 1279 NET_UNLOCK(); 1280 return (error); 1281 1282 case UDPCTL_STATS: 1283 if (newp != NULL) 1284 return (EPERM); 1285 1286 return (udp_sysctl_udpstat(oldp, oldlenp, newp)); 1287 1288 default: 1289 if (name[0] < UDPCTL_MAXID) { 1290 NET_LOCK(); 1291 error = sysctl_int_arr(udpctl_vars, name, namelen, 1292 oldp, oldlenp, newp, newlen); 1293 NET_UNLOCK(); 1294 return (error); 1295 } 1296 return (ENOPROTOOPT); 1297 } 1298 /* NOTREACHED */ 1299 } 1300 1301 int 1302 udp_sysctl_udpstat(void *oldp, size_t *oldlenp, void *newp) 1303 { 1304 uint64_t counters[udps_ncounters]; 1305 struct udpstat udpstat; 1306 u_long *words = (u_long *)&udpstat; 1307 int i; 1308 1309 CTASSERT(sizeof(udpstat) == (nitems(counters) * sizeof(u_long))); 1310 memset(&udpstat, 0, sizeof udpstat); 1311 counters_read(udpcounters, counters, nitems(counters)); 1312 1313 for (i = 0; i < nitems(counters); i++) 1314 words[i] = (u_long)counters[i]; 1315 1316 return (sysctl_rdstruct(oldp, oldlenp, newp, 1317 &udpstat, sizeof(udpstat))); 1318 } 1319