iptables目标CHECKSUM
生活随笔
收集整理的這篇文章主要介紹了
iptables目标CHECKSUM
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CHECKSUM目標幫助信息如下。
# iptables -j CHECKSUM -hCHECKSUM target options--checksum-fill Fill in packet checksum.如下配置策略,對目標端口68的UDP報文,計算其校驗和。
# iptables -A OUTPUT -t mangle -p udp --dport 68 -j CHECKSUM --checksum-fill # # sudo iptables -t mangle -L -n -v Chain OUTPUT (policy ACCEPT 78 packets, 10944 bytes)pkts bytes target prot opt in out source destination 0 0 CHECKSUM udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:68 CHECKSUM fillchecksum目標
函數xt_register_target注冊目標結構checksum_tg_reg。
static struct xt_target checksum_tg_reg __read_mostly = {.name = "CHECKSUM",.family = NFPROTO_UNSPEC, .target = checksum_tg,.targetsize = sizeof(struct xt_CHECKSUM_info),.table = "mangle",.checkentry = checksum_tg_check,.me = THIS_MODULE, }; static int __init checksum_tg_init(void) { return xt_register_target(&checksum_tg_reg);配置檢查函數如下,僅支持(–checksum-fill)一個命令選項,其它配置無效。
static int checksum_tg_check(const struct xt_tgchk_param *par) {const struct xt_CHECKSUM_info *einfo = par->targinfo;const struct ip6t_ip6 *i6 = par->entryinfo;const struct ipt_ip *i4 = par->entryinfo;if (einfo->operation & ~XT_CHECKSUM_OP_FILL) {pr_info_ratelimited("unsupported CHECKSUM operation %x\n",einfo->operation);return -EINVAL;}if (!einfo->operation)return -EINVAL;對于IPv4協議或者IPv6協議,檢查配置的四層協議是否為UDP,否則,輸出一次警告信息,但是仍然返回零,不報錯。
switch (par->family) {case NFPROTO_IPV4:if (i4->proto == IPPROTO_UDP &&(i4->invflags & XT_INV_PROTO) == 0)return 0;break;case NFPROTO_IPV6:if ((i6->flags & IP6T_F_PROTO) &&i6->proto == IPPROTO_UDP &&(i6->invflags & XT_INV_PROTO) == 0)return 0;break;} pr_warn_once("CHECKSUM should be avoided. If really needed, restrict with \"-p udp\" and only use in OUTPUT\n");return 0;對于校驗和沒有計算完成(僅計算了偽頭部),并且非GSO卸載的報文,由函數skb_checksum_help完成校驗和計算。
static unsigned int checksum_tg(struct sk_buff *skb, const struct xt_action_param *par) {if (skb->ip_summed == CHECKSUM_PARTIAL && !skb_is_gso(skb))skb_checksum_help(skb);return XT_CONTINUE;函數skb_checksum_help首先也是進行了以上的判斷,即校驗和是否已經計算完成,是不是GSO卸載報文。另外,如果報文有外部的使用者,將報文線性化。
int skb_checksum_help(struct sk_buff *skb) {__wsum csum;int ret = 0, offset;if (skb->ip_summed == CHECKSUM_COMPLETE)goto out_set_summed;if (unlikely(skb_shinfo(skb)->gso_size)) {skb_warn_bad_offload(skb);return -EINVAL;}/* Before computing a checksum, we should make sure no frag could* be modified by an external entity : checksum could be wrong.*/if (skb_has_shared_frag(skb)) {ret = __skb_linearize(skb);if (ret)goto out;}首先,取出需要計算校驗和的數據的偏移地址;其次,計算偏移地址到報文末尾的校驗和;最后,將得到的校驗和寫入報文位置csum_offset,此操作需要確保此位置可寫(校驗和為2個字節)。
offset = skb_checksum_start_offset(skb);BUG_ON(offset >= skb_headlen(skb));csum = skb_checksum(skb, offset, skb->len - offset, 0);offset += skb->csum_offset;BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));ret = skb_ensure_writable(skb, offset + sizeof(__sum16));if (ret) goto out;*(__sum16 *)(skb->data + offset) = csum_fold(csum) ?: CSUM_MANGLED_0; out_set_summed:skb->ip_summed = CHECKSUM_NONE; out:return ret;內核版本 5.10
總結
以上是生活随笔為你收集整理的iptables目标CHECKSUM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx 负载均衡502问题
- 下一篇: 发布个人项目jar包到maven中央仓库