📄 nf_conntrack_proto_sctp.c
字号:
&& !(sh->vtag == conntrack->proto.sctp.vtag [1 - CTINFO2DIR(ctinfo)])) { write_unlock_bh(&sctp_lock); return -1; } } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) { /* Sec 8.5.1 (C) */ if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) && !(sh->vtag == conntrack->proto.sctp.vtag [1 - CTINFO2DIR(ctinfo)] && (sch->flags & 1))) { write_unlock_bh(&sctp_lock); return -1; } } else if (sch->type == SCTP_CID_COOKIE_ECHO) { /* Sec 8.5.1 (D) */ if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { write_unlock_bh(&sctp_lock); return -1; } } oldsctpstate = conntrack->proto.sctp.state; newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type); /* Invalid */ if (newconntrack == SCTP_CONNTRACK_MAX) { pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u " "conntrack=%u\n", CTINFO2DIR(ctinfo), sch->type, oldsctpstate); write_unlock_bh(&sctp_lock); return -1; } /* If it is an INIT or an INIT ACK note down the vtag */ if (sch->type == SCTP_CID_INIT || sch->type == SCTP_CID_INIT_ACK) { sctp_inithdr_t _inithdr, *ih; ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t), sizeof(_inithdr), &_inithdr); if (ih == NULL) { write_unlock_bh(&sctp_lock); return -1; } pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !CTINFO2DIR(ctinfo)); conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag; } conntrack->proto.sctp.state = newconntrack; if (oldsctpstate != newconntrack) nf_conntrack_event_cache(IPCT_PROTOINFO, skb); write_unlock_bh(&sctp_lock); } nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]); if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY && newconntrack == SCTP_CONNTRACK_ESTABLISHED) { pr_debug("Setting assured bit\n"); set_bit(IPS_ASSURED_BIT, &conntrack->status); nf_conntrack_event_cache(IPCT_STATUS, skb); } return NF_ACCEPT;}/* Called when a new connection for this protocol found. */static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb, unsigned int dataoff){ enum sctp_conntrack newconntrack; sctp_sctphdr_t _sctph, *sh; sctp_chunkhdr_t _sch, *sch; u_int32_t offset, count; char map[256 / sizeof (char)] = {0}; sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); if (sh == NULL) return 0; if (do_basic_checks(conntrack, skb, dataoff, map) != 0) return 0; /* If an OOTB packet has any of these chunks discard (Sec 8.4) */ if ((test_bit (SCTP_CID_ABORT, (void *)map)) || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)) || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) { return 0; } newconntrack = SCTP_CONNTRACK_MAX; for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { /* Don't need lock here: this conntrack not in circulation yet */ newconntrack = new_state(IP_CT_DIR_ORIGINAL, SCTP_CONNTRACK_NONE, sch->type); /* Invalid: delete conntrack */ if (newconntrack == SCTP_CONNTRACK_NONE || newconntrack == SCTP_CONNTRACK_MAX) { pr_debug("nf_conntrack_sctp: invalid new deleting.\n"); return 0; } /* Copy the vtag into the state info */ if (sch->type == SCTP_CID_INIT) { if (sh->vtag == 0) { sctp_inithdr_t _inithdr, *ih; ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t), sizeof(_inithdr), &_inithdr); if (ih == NULL) return 0; pr_debug("Setting vtag %x for new conn\n", ih->init_tag); conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = ih->init_tag; } else { /* Sec 8.5.1 (A) */ return 0; } } /* If it is a shutdown ack OOTB packet, we expect a return shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ else { pr_debug("Setting vtag %x for new conn OOTB\n", sh->vtag); conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag; } conntrack->proto.sctp.state = newconntrack; } return 1;}#ifdef CONFIG_SYSCTLstatic unsigned int sctp_sysctl_table_users;static struct ctl_table_header *sctp_sysctl_header;static struct ctl_table sctp_sysctl_table[] = { { .procname = "nf_conntrack_sctp_timeout_closed", .data = &nf_ct_sctp_timeout_closed, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_cookie_wait", .data = &nf_ct_sctp_timeout_cookie_wait, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_cookie_echoed", .data = &nf_ct_sctp_timeout_cookie_echoed, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_established", .data = &nf_ct_sctp_timeout_established, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_shutdown_sent", .data = &nf_ct_sctp_timeout_shutdown_sent, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_shutdown_recd", .data = &nf_ct_sctp_timeout_shutdown_recd, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", .data = &nf_ct_sctp_timeout_shutdown_ack_sent, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .ctl_name = 0 }};#ifdef CONFIG_NF_CONNTRACK_PROC_COMPATstatic struct ctl_table sctp_compat_sysctl_table[] = { { .procname = "ip_conntrack_sctp_timeout_closed", .data = &nf_ct_sctp_timeout_closed, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_cookie_wait", .data = &nf_ct_sctp_timeout_cookie_wait, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_cookie_echoed", .data = &nf_ct_sctp_timeout_cookie_echoed, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_established", .data = &nf_ct_sctp_timeout_established, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_shutdown_sent", .data = &nf_ct_sctp_timeout_shutdown_sent, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_shutdown_recd", .data = &nf_ct_sctp_timeout_shutdown_recd, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent", .data = &nf_ct_sctp_timeout_shutdown_ack_sent, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .ctl_name = 0 }};#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */#endifstatic struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { .l3proto = PF_INET, .l4proto = IPPROTO_SCTP, .name = "sctp", .pkt_to_tuple = sctp_pkt_to_tuple, .invert_tuple = sctp_invert_tuple, .print_tuple = sctp_print_tuple, .print_conntrack = sctp_print_conntrack, .packet = sctp_packet, .new = sctp_new, .me = THIS_MODULE,#ifdef CONFIG_SYSCTL .ctl_table_users = &sctp_sysctl_table_users, .ctl_table_header = &sctp_sysctl_header, .ctl_table = sctp_sysctl_table,#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT .ctl_compat_table = sctp_compat_sysctl_table,#endif#endif};static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { .l3proto = PF_INET6, .l4proto = IPPROTO_SCTP, .name = "sctp", .pkt_to_tuple = sctp_pkt_to_tuple, .invert_tuple = sctp_invert_tuple, .print_tuple = sctp_print_tuple, .print_conntrack = sctp_print_conntrack, .packet = sctp_packet, .new = sctp_new, .me = THIS_MODULE,#ifdef CONFIG_SYSCTL .ctl_table_users = &sctp_sysctl_table_users, .ctl_table_header = &sctp_sysctl_header, .ctl_table = sctp_sysctl_table,#endif};int __init nf_conntrack_proto_sctp_init(void){ int ret; ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4); if (ret) { printk("nf_conntrack_l4proto_sctp4: protocol register failed\n"); goto out; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6); if (ret) { printk("nf_conntrack_l4proto_sctp6: protocol register failed\n"); goto cleanup_sctp4; } return ret; cleanup_sctp4: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); out: return ret;}void __exit nf_conntrack_proto_sctp_fini(void){ nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);}module_init(nf_conntrack_proto_sctp_init);module_exit(nf_conntrack_proto_sctp_fini);MODULE_LICENSE("GPL");MODULE_AUTHOR("Kiran Kumar Immidi");MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");MODULE_ALIAS("ip_conntrack_proto_sctp");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -