* Parse arguments and assemble the microinstructions which make up a rule. * Rules are added into the 'rulebuf' and then copied in the correct order * into the actual rule. * * The syntax for a rule starts with the action, followed by * optional action parameters, and the various match patterns. * In the assembled microcode, the first opcode must be an O_PROBE_STATE * (generated if the rule
| 3803 | * |
| 3804 | */ |
| 3805 | static void |
| 3806 | compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate) |
| 3807 | { |
| 3808 | /* |
| 3809 | * rules are added into the 'rulebuf' and then copied in |
| 3810 | * the correct order into the actual rule. |
| 3811 | * Some things that need to go out of order (prob, action etc.) |
| 3812 | * go into actbuf[]. |
| 3813 | */ |
| 3814 | static uint32_t actbuf[255], cmdbuf[255]; |
| 3815 | int rblen, ablen, cblen; |
| 3816 | |
| 3817 | ipfw_insn *src, *dst, *cmd, *action, *prev=NULL; |
| 3818 | ipfw_insn *first_cmd; /* first match pattern */ |
| 3819 | |
| 3820 | struct ip_fw_rule *rule; |
| 3821 | |
| 3822 | /* |
| 3823 | * various flags used to record that we entered some fields. |
| 3824 | */ |
| 3825 | ipfw_insn *have_state = NULL; /* any state-related option */ |
| 3826 | int have_rstate = 0; |
| 3827 | ipfw_insn *have_log = NULL, *have_altq = NULL, *have_tag = NULL; |
| 3828 | ipfw_insn *have_skipcmd = NULL; |
| 3829 | size_t len; |
| 3830 | |
| 3831 | int i; |
| 3832 | |
| 3833 | int open_par = 0; /* open parenthesis ( */ |
| 3834 | |
| 3835 | /* proto is here because it is used to fetch ports */ |
| 3836 | u_char proto = IPPROTO_IP; /* default protocol */ |
| 3837 | |
| 3838 | double match_prob = 1; /* match probability, default is always match */ |
| 3839 | |
| 3840 | bzero(actbuf, sizeof(actbuf)); /* actions go here */ |
| 3841 | bzero(cmdbuf, sizeof(cmdbuf)); |
| 3842 | bzero(rbuf, *rbufsize); |
| 3843 | |
| 3844 | rule = (struct ip_fw_rule *)rbuf; |
| 3845 | cmd = (ipfw_insn *)cmdbuf; |
| 3846 | action = (ipfw_insn *)actbuf; |
| 3847 | |
| 3848 | rblen = *rbufsize / sizeof(uint32_t); |
| 3849 | rblen -= sizeof(struct ip_fw_rule) / sizeof(uint32_t); |
| 3850 | ablen = sizeof(actbuf) / sizeof(actbuf[0]); |
| 3851 | cblen = sizeof(cmdbuf) / sizeof(cmdbuf[0]); |
| 3852 | cblen -= F_INSN_SIZE(ipfw_insn_u32) + 1; |
| 3853 | |
| 3854 | #define CHECK_RBUFLEN(len) { CHECK_LENGTH(rblen, len); rblen -= len; } |
| 3855 | #define CHECK_ACTLEN CHECK_LENGTH(ablen, action->len) |
| 3856 | |
| 3857 | av++; |
| 3858 | |
| 3859 | /* [rule N] -- Rule number optional */ |
| 3860 | if (av[0] && isdigit(**av)) { |
| 3861 | rule->rulenum = atoi(*av); |
| 3862 | av++; |
no test coverage detected