return 0;
}
-int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt)
+int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr)
{
const int blksize = 16;
int i, padlen, ret;
+ if (!next_hdr) {
+ if ((pkt->data[0] & 0xf0) == 0x60) /* iph->ip_v */
+ next_hdr = IPPROTO_IPV6;
+ else
+ next_hdr = IPPROTO_IPIP;
+ }
+
/* This gets much more fun if the IV is variable-length */
pkt->esp.spi = vpninfo->esp_out.spi;
pkt->esp.seq = htonl(vpninfo->esp_out.seq++);
for (i=0; i<padlen; i++)
pkt->data[pkt->len + i] = i + 1;
pkt->data[pkt->len + padlen] = padlen;
- pkt->data[pkt->len + padlen + 1] = 0x04; /* Legacy IP */
+ pkt->data[pkt->len + padlen + 1] = next_hdr;
memcpy(pkt->esp.iv, vpninfo->esp_out.iv, sizeof(pkt->esp.iv));
if (!this)
break;
- len = construct_esp_packet(vpninfo, this);
+ len = construct_esp_packet(vpninfo, this, 0);
if (len < 0) {
/* Should we disable ESP? */
free(this);
memcpy(pmagic, magic_ping_payload, sizeof(magic_ping_payload)); /* required to get gateway to respond */
icmph->icmp_cksum = csum((uint16_t *)icmph, (ICMP_MINLEN+sizeof(magic_ping_payload))/2);
- pktlen = construct_esp_packet(vpninfo, pkt);
+ pktlen = construct_esp_packet(vpninfo, pkt, IPPROTO_IPIP);
if (pktlen >= 0)
send(vpninfo->dtls_fd, (void *)&pkt->esp, pktlen, 0);
}
for (seq=1; seq <= (vpninfo->dtls_state==DTLS_CONNECTED ? 1 : 2); seq++) {
pkt->len = 1;
pkt->data[0] = 0;
- pktlen = construct_esp_packet(vpninfo, pkt);
+ pktlen = construct_esp_packet(vpninfo, pkt, IPPROTO_IPIP);
if (pktlen >= 0)
send(vpninfo->dtls_fd, (void *)&pkt->esp, pktlen, 0);
}
void esp_shutdown(struct openconnect_info *vpninfo);
int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct esp *esp);
int openconnect_setup_esp_keys(struct openconnect_info *vpninfo, int new_keys);
-int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt);
+int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr);
/* {gnutls,openssl}-esp.c */
void destroy_esp_ciphers(struct esp *esp);