📄 fc_ipclassifier.cc
字号:
/* * fc_ipclassifier.cc -- click-fastclassifier functions for IPFilter and * IPClassifier * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2000 Mazu Networks, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/straccum.hh>#include "click-fastclassifier.hh"// magic constants imported from Click itself#define IPCLASSIFIER_TRANSP_FAKE_OFFSET 64static voidwrite_checked_body(const Classifier_Program &c, StringAccum &source){ source << " const unsigned *ip_data = (const unsigned *)p->ip_header();\n\ const unsigned *transp_data = (const unsigned *)p->transport_header();\n\ int l = p->length() + " << IPCLASSIFIER_TRANSP_FAKE_OFFSET << " - p->transport_header_offset();\n"; source << " assert(l < " << c.safe_length << ");\n"; for (int i = 0; i < c.program.size(); i++) { const Classifier_Insn &e = c.program[i]; int want_l = e.offset + 4; if (!e.mask.c[3]) { want_l--; if (!e.mask.c[2]) { want_l--; if (!e.mask.c[1]) want_l--; } } bool switched = (e.yes == i + 1); int branch1 = (switched ? e.no : e.yes); int branch2 = (switched ? e.yes : e.no); source << " lstep_" << i << ":\n"; int offset; String datavar; String length_check; if (e.offset >= IPCLASSIFIER_TRANSP_FAKE_OFFSET) { offset = (e.offset - IPCLASSIFIER_TRANSP_FAKE_OFFSET)/4; datavar = "transp_data"; length_check = "l < " + String(want_l); } else { offset = e.offset/4; datavar = "ip_data"; length_check = "false"; } if (want_l >= c.safe_length) { branch2 = e.no; goto output_branch2; } if (switched) source << " if (" << length_check << " || (" << datavar << "[" << offset << "] & " << e.mask.u << "U) != " << e.value.u << "U)"; else source << " if (!(" << length_check << ") && (" << datavar << "[" << offset << "] & " << e.mask.u << "U) == " << e.value.u << "U)"; if (branch1 <= -c.noutputs) source << " {\n p->kill();\n return;\n }\n"; else if (branch1 <= 0) source << " {\n output(" << -branch1 << ").push(p);\n return;\n }\n"; else source << "\n goto lstep_" << branch1 << ";\n"; output_branch2: if (branch2 <= -c.noutputs) source << " p->kill();\n return;\n"; else if (branch2 <= 0) source << " output(" << -branch2 << ").push(p);\n return;\n"; else if (branch2 != i + 1) source << " goto lstep_" << branch2 << ";\n"; }}static voidwrite_unchecked_body(const Classifier_Program &c, StringAccum &source){ source << " const unsigned *ip_data = (const unsigned *)p->ip_header();\n\ const unsigned *transp_data = (const unsigned *)p->transport_header();\n"; for (int i = 0; i < c.program.size(); i++) { const Classifier_Insn &e = c.program[i]; bool switched = (e.yes == i + 1); int branch1 = (switched ? e.no : e.yes); int branch2 = (switched ? e.yes : e.no); source << " step_" << i << ":\n"; int offset; String datavar; if (e.offset >= IPCLASSIFIER_TRANSP_FAKE_OFFSET) offset = (e.offset - IPCLASSIFIER_TRANSP_FAKE_OFFSET)/4, datavar = "transp_data"; else offset = e.offset/4, datavar = "ip_data"; if (switched) source << " if ((" << datavar << "[" << offset << "] & " << e.mask.u << "U) != " << e.value.u << "U)"; else source << " if ((" << datavar << "[" << offset << "] & " << e.mask.u << "U) == " << e.value.u << "U)"; if (branch1 <= -c.noutputs) source << " {\n p->kill();\n return;\n }\n"; else if (branch1 <= 0) source << " {\n output(" << -branch1 << ").push(p);\n return;\n }\n"; else source << "\n goto step_" << branch1 << ";\n"; if (branch2 <= -c.noutputs) source << " p->kill();\n return;\n"; else if (branch2 <= 0) source << " output(" << -branch2 << ").push(p);\n return;\n"; else if (branch2 != i + 1) source << " goto step_" << branch2 << ";\n"; }}static voidwrite_push_body(const Classifier_Program &c, StringAccum &source){ if (c.safe_length >= IPCLASSIFIER_TRANSP_FAKE_OFFSET) source << "\ if (p->length() + " << IPCLASSIFIER_TRANSP_FAKE_OFFSET << " - p->transport_header_offset() < " << c.safe_length << ")\n\ length_checked_push(p);\n\ else\n\ length_unchecked_push(p);\n"; else source << " length_unchecked_push(p);\n";}extern "C" voidadd_fast_classifiers_2(){ add_classifier_type("IPClassifier", IPCLASSIFIER_TRANSP_FAKE_OFFSET, 0, write_checked_body, write_unchecked_body, write_push_body); add_classifier_type("IPFilter", IPCLASSIFIER_TRANSP_FAKE_OFFSET, 0, write_checked_body, write_unchecked_body, write_push_body);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -