* NAT-T support. * IKEd may request the use ESP in UDP encapsulation when it detects the * presence of NAT. It uses NAT-T extension headers for such SAs to specify * parameters needed for encapsulation and decapsulation. These PF_KEY * extension headers are not standardized, so this comment addresses our * implementation. * SADB_X_EXT_NAT_T_TYPE specifies type of encapsulation, we support on
| 5686 | * to SADB_ADD, SADB_UPDATE, SADB_GET, and SADB_DUMP messages. |
| 5687 | */ |
| 5688 | static int |
| 5689 | key_setnatt(struct secasvar *sav, const struct sadb_msghdr *mhp) |
| 5690 | { |
| 5691 | struct sadb_x_nat_t_port *port; |
| 5692 | struct sadb_x_nat_t_type *type; |
| 5693 | struct sadb_address *oai, *oar; |
| 5694 | struct sockaddr *sa; |
| 5695 | uint32_t addr; |
| 5696 | uint16_t cksum; |
| 5697 | |
| 5698 | IPSEC_ASSERT(sav->natt == NULL, ("natt is already initialized")); |
| 5699 | /* |
| 5700 | * Ignore NAT-T headers if sproto isn't ESP. |
| 5701 | */ |
| 5702 | if (sav->sah->saidx.proto != IPPROTO_ESP) |
| 5703 | return (0); |
| 5704 | |
| 5705 | if (!SADB_CHECKHDR(mhp, SADB_X_EXT_NAT_T_TYPE) && |
| 5706 | !SADB_CHECKHDR(mhp, SADB_X_EXT_NAT_T_SPORT) && |
| 5707 | !SADB_CHECKHDR(mhp, SADB_X_EXT_NAT_T_DPORT)) { |
| 5708 | if (SADB_CHECKLEN(mhp, SADB_X_EXT_NAT_T_TYPE) || |
| 5709 | SADB_CHECKLEN(mhp, SADB_X_EXT_NAT_T_SPORT) || |
| 5710 | SADB_CHECKLEN(mhp, SADB_X_EXT_NAT_T_DPORT)) { |
| 5711 | ipseclog((LOG_DEBUG, |
| 5712 | "%s: invalid message: wrong header size.\n", |
| 5713 | __func__)); |
| 5714 | return (EINVAL); |
| 5715 | } |
| 5716 | } else |
| 5717 | return (0); |
| 5718 | |
| 5719 | type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE]; |
| 5720 | if (type->sadb_x_nat_t_type_type != UDP_ENCAP_ESPINUDP) { |
| 5721 | ipseclog((LOG_DEBUG, "%s: unsupported NAT-T type %u.\n", |
| 5722 | __func__, type->sadb_x_nat_t_type_type)); |
| 5723 | return (EINVAL); |
| 5724 | } |
| 5725 | /* |
| 5726 | * Allocate storage for NAT-T config. |
| 5727 | * On error it will be released by key_cleansav(). |
| 5728 | */ |
| 5729 | sav->natt = malloc(sizeof(struct secnatt), M_IPSEC_MISC, |
| 5730 | M_NOWAIT | M_ZERO); |
| 5731 | if (sav->natt == NULL) { |
| 5732 | PFKEYSTAT_INC(in_nomem); |
| 5733 | ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); |
| 5734 | return (ENOBUFS); |
| 5735 | } |
| 5736 | port = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT]; |
| 5737 | if (port->sadb_x_nat_t_port_port == 0) { |
| 5738 | ipseclog((LOG_DEBUG, "%s: invalid NAT-T sport specified.\n", |
| 5739 | __func__)); |
| 5740 | return (EINVAL); |
| 5741 | } |
| 5742 | sav->natt->sport = port->sadb_x_nat_t_port_port; |
| 5743 | port = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT]; |
| 5744 | if (port->sadb_x_nat_t_port_port == 0) { |
| 5745 | ipseclog((LOG_DEBUG, "%s: invalid NAT-T dport specified.\n", |
no test coverage detected