📄 ipsec_rcv.c
字号:
"klips_debug:ipsec_rcv: " "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } tdbprev = tdbp; tdbp = tdbnext; if(sysctl_ipsec_inbound_policy_check && ((tdbp == NULL) || ((tdbp != NULL) && ((ntohl(tdbp->tdb_said.spi) & 0x0000ffff) != ntohl(said.spi))))) { char sa2[SATOA_BUF]; size_t sa_len2 = 0; if(tdbp) { sa_len2 = satoa(tdbp->tdb_said, 0, sa2, SATOA_BUF); } KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n", sa_len ? sa : " (error)", tdbp ? (sa_len2 ? sa2 : " (error)") : "NULL", ntohs(compp->ipcomp_cpi), (__u32)ntohl(said.spi), tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0, tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0); spin_unlock(&tdb_lock); if(stats) { stats->rx_dropped++; } goto rcvleave; } if (tdbp) { tdbp->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len); tdbnext = tdbp->tdb_inext; } next_header = compp->ipcomp_nh; skb = skb_decompress(skb, tdbp, &flags); if (!skb || flags) { spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "skb_decompress() returned error flags=%x, dropped.\n", flags); if (stats) { if (flags) stats->rx_errors++; else stats->rx_dropped++; } goto rcvleave; }#ifdef NET_21 ipp = skb->nh.iph;#else /* NET_21 */ ipp = skb->ip_hdr;#endif /* NET_21 */ if (tdbp) { tdbp->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len); } KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n", sa_len ? sa : " (error)", (__u32)ntohl(said.spi), tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0, tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0, next_header); KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); continue; /* Skip rest of stuff and decapsulate next inner packet, if any */ }#endif /* CONFIG_IPSEC_IPCOMP */ tdbp = gettdb(&said); if (tdbp == NULL) { spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "no Tunnel Descriptor Block for SA:%s: incoming packet with no SA dropped\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(sysctl_ipsec_inbound_policy_check) { if(ipp->saddr != ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr) { spin_unlock(&tdb_lock); ipaddr.s_addr = ipp->saddr; addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", sa_len ? sa : " (error)", ipaddr_txt); if(stats) { stats->rx_dropped++; } goto rcvleave; } ipaddr.s_addr = ipp->saddr; addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n", sa_len ? sa : " (error)", ipaddr_txt); if(tdbnext) { if(tdbnext != tdbp) { spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "unexpected SA:%s: does not agree with tdb->inext policy, dropped\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "SA:%s grouping from previous SA is OK.\n", sa_len ? sa : " (error)"); } else { KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "SA:%s First SA in group.\n", sa_len ? sa : " (error)"); } if(tdbp->tdb_onext) { if(tdbprev != tdbp->tdb_onext) { spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "unexpected SA:%s: does not agree with tdb->onext policy, dropped.\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } else { KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "SA:%s grouping to previous SA is OK.\n", sa_len ? sa : " (error)"); } } else { KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "SA:%s No previous backlink in group.\n", sa_len ? sa : " (error)"); } } /* If it is in larval state, drop the packet, we cannot process yet. */ if(tdbp->tdb_state == SADB_SASTATE_LARVAL) { spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "TDB in larval state, cannot be used yet, dropping packet.\n"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(tdbp->tdb_state == SADB_SASTATE_DEAD) { spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "TDB in dead state, cannot be used any more, dropping packet.\n"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(tdbp->tdb_lifetime_bytes_h && (tdbp->tdb_lifetime_bytes_c > tdbp->tdb_lifetime_bytes_h)) { pfkey_expire(tdbp, 1); deltdbchain(tdbp); spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "hard bytes lifetime of SA:%s has been reached, SA expired, incoming packet dropped.\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(tdbp->tdb_lifetime_bytes_s && (tdbp->tdb_lifetime_bytes_c > tdbp->tdb_lifetime_bytes_s)) { if(tdbp->tdb_state != SADB_SASTATE_DYING) { pfkey_expire(tdbp, 0); } tdbp->tdb_state = SADB_SASTATE_DYING; KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "soft bytes lifetime of SA:%s has been reached, SA expiring, soft expire message sent up, incoming packet still processed.\n", sa_len ? sa : " (error)"); } if(tdbp->tdb_lifetime_addtime_h && ((jiffies / HZ) - tdbp->tdb_lifetime_addtime_c > tdbp->tdb_lifetime_addtime_h)) { pfkey_expire(tdbp, 1); deltdbchain(tdbp); spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "hard addtime lifetime of SA:%s has been reached, SA expired, incoming packet dropped.\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(tdbp->tdb_lifetime_addtime_s && ((jiffies / HZ) - tdbp->tdb_lifetime_addtime_c > tdbp->tdb_lifetime_addtime_s)) { if(tdbp->tdb_state != SADB_SASTATE_DYING) { pfkey_expire(tdbp, 0); } tdbp->tdb_state = SADB_SASTATE_DYING; KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "soft addtime lifetime of SA:%s has been reached, SA expiring, soft expire message sent up, incoming packet still processed.\n", sa_len ? sa : " (error)"); } if(tdbp->tdb_lifetime_usetime_c) { if(tdbp->tdb_lifetime_usetime_h && ((jiffies / HZ) - tdbp->tdb_lifetime_usetime_c > tdbp->tdb_lifetime_usetime_h)) { pfkey_expire(tdbp, 1); deltdbchain(tdbp); spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "hard usetime lifetime of SA:%s has been reached, SA expired, incoming packet dropped.\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(tdbp->tdb_lifetime_usetime_s && ((jiffies / HZ) - tdbp->tdb_lifetime_usetime_c > tdbp->tdb_lifetime_usetime_s)) { if(tdbp->tdb_state != SADB_SASTATE_DYING) { pfkey_expire(tdbp, 0); } tdbp->tdb_state = SADB_SASTATE_DYING; KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "soft usetime lifetime of SA:%s has been reached, SA expiring, soft expire message sent up, incoming packet still processed.\n", sa_len ? sa : " (error)"); } } if(tdbp->tdb_lifetime_packets_h && (tdbp->tdb_lifetime_packets_c > tdbp->tdb_lifetime_packets_h)) { pfkey_expire(tdbp, 1); deltdbchain(tdbp); spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "hard packets lifetime of SA:%s has been reached, SA expired, incoming packet dropped.\n", sa_len ? sa : " (error)"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if(tdbp->tdb_lifetime_packets_s && (tdbp->tdb_lifetime_packets_c > tdbp->tdb_lifetime_packets_s)) { if(tdbp->tdb_state != SADB_SASTATE_DYING) { pfkey_expire(tdbp, 0); } tdbp->tdb_state = SADB_SASTATE_DYING; KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "soft packets lifetime of SA:%s has been reached, SA expiring, soft expire message sent up, incoming packet still processed.\n", sa_len ? sa : " (error)"); } /* authenticate, if required */ idat = dat + iphlen; switch(tdbp->tdb_authalg) {#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 case AH_MD5: authlen = AHHMAC_HASHLEN; break;#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 case AH_SHA: authlen = AHHMAC_HASHLEN; break;#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ case AH_NONE: authlen = 0; break; default: tdbp->tdb_alg_errs += 1; spin_unlock(&tdb_lock); if(stats) { stats->rx_errors++; } goto rcvleave; } ilen = len - iphlen - authlen; #ifdef CONFIG_IPSEC_ESP KLIPS_PRINT(proto == IPPROTO_ESP && debug_rcv, "klips_debug:ipsec_rcv: " "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n", ipaddr_txt, (__u32)ntohl(espp->esp_rpl), (__u32)ntohl(*((__u32 *)(espp->esp_iv) )), (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)), len, ilen, sa_len ? sa : " (error)");#endif /* !CONFIG_IPSEC_ESP */ switch(proto) {#ifdef CONFIG_IPSEC_ESP case IPPROTO_ESP: replay = ntohl(espp->esp_rpl); authenticator = &(dat[len - authlen]); break;#endif /* !CONFIG_IPSEC_ESP */#ifdef CONFIG_IPSEC_AH case IPPROTO_AH: replay = ntohl(ahp->ah_rpl); authenticator = ahp->ah_data; break;#endif /* CONFIG_IPSEC_AH */ } /* If the sequence number == 0, expire SA, it had rolled */ if(tdbp->tdb_replaywin && !replay /* !tdbp->tdb_replaywin_lastseq */) { deltdbchain(tdbp); spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "replay window counter rolled, expiring SA.\n"); if(stats) { stats->rx_dropped++; } goto rcvleave; } if (!ipsec_checkreplaywindow(tdbp, replay)) { tdbp->tdb_replaywin_errs += 1; spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, "klips_debug:ipsec_rcv: " "duplicate frame from %s, packet dropped\n", ipaddr_txt); if(stats) { stats->rx_dropped++; } goto rcvleave; } /* * verify authenticator */ KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "encalg = %d, authalg = %d.\n", tdbp->tdb_encalg, tdbp->tdb_authalg); if(tdbp->tdb_authalg) { switch(tdbp->tdb_authalg) {#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 case AH_MD5: tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx; if(proto == IPPROTO_ESP) { MD5Update(&tctx.md5, (caddr_t)espp, ilen);#ifdef CONFIG_IPSEC_AH } else { ipo = *ipp; ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */ ipo.frag_off = 0; ipo.ttl = 0; ipo.check = 0; MD5Update(&tctx.md5, (caddr_t)&ipo, sizeof(struct iphdr)); MD5Update(&tctx.md5, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN); MD5Update(&tctx.md5, (caddr_t)zeroes, AHHMAC_HASHLEN); MD5Update(&tctx.md5, (caddr_t)dat + iphlen + ahhlen, len - iphlen - ahhlen);#endif /* CONFIG_IPSEC_AH */ } MD5Final(hash, &tctx.md5); tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx; MD5Update(&tctx.md5, hash, AHMD596_ALEN); MD5Final(hash, &tctx.md5); break;#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 case AH_SHA: tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx; if(proto == IPPROTO_ESP) { SHA1Update(&tctx.sha1, (caddr_t)espp, ilen);#ifdef CONFIG_IPSEC_AH } else { ipo = *ipp; ipo.tos = 0; ipo.frag_off = 0; ipo.ttl = 0; ipo.check = 0; SHA1Update(&tctx.sha1, (caddr_t)&ipo, sizeof(struct iphdr)); SHA1Update(&tctx.sha1, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN); SHA1Update(&tctx.sha1, (caddr_t)zeroes, AHHMAC_HASHLEN); SHA1Update(&tctx.sha1, (caddr_t)dat + iphlen + ahhlen, len - iphlen - ahhlen);#endif /* CONFIG_IPSEC_AH */ } SHA1Final(hash, &tctx.sha1); tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx; SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); SHA1Final(hash, &tctx.sha1); break;#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ case AH_NONE: break; } if(!authenticator) { tdbp->tdb_auth_errs += 1; spin_unlock(&tdb_lock); if(stats) { stats->rx_dropped++; } goto rcvleave; } if (memcmp(hash, authenticator, authlen)) { tdbp->tdb_auth_errs += 1; spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv & DB_RX_INAU, "klips_debug:ipsec_rcv: " "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n", ipaddr_txt, *(__u32*)&hash[0], *(__u32*)&hash[4], *(__u32*)&hash[8], *(__u32*)authenticator, *((__u32*)authenticator + 1), *((__u32*)authenticator + 2)); if(stats) { stats->rx_dropped++; } goto rcvleave; } else { KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv: " "authentication successful.\n"); } memset((caddr_t)&tctx, 0, sizeof(tctx)); memset(hash, 0, sizeof(hash)); } if (!ipsec_updatereplaywindow(tdbp, replay)) { tdbp->tdb_replaywin_errs += 1; spin_unlock(&tdb_lock); KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, "klips_debug:ipsec_rcv: " "duplicate frame from %s, packet dropped\n", ipaddr_txt); if(stats) { stats->rx_dropped++; } goto rcvleave; } switch(proto) {#ifdef CONFIG_IPSEC_ESP case IPPROTO_ESP: switch(tdbp->tdb_encalg) { case ESP_3DES: iv[0] = *((__u32 *)(espp->esp_iv) ); iv[1] = *((__u32 *)(espp->esp_iv) + 1); esphlen = sizeof(struct esp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -