/*
 * DF-0473 regression test: install a LEGITIMATE rule (module=0 BASIC,
 * opcode=0 ACCEPT) and confirm it is accepted.  Proves the fix does not
 * break normal rule installation.
 *
 * Build: cc -Wall -o add_legit add_legit.c
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define MY_IP_FW_X   49
#define MY_IP_FW_ADD 50
typedef struct { uint8_t opcode; uint8_t len; uint16_t arg1;
                 uint8_t module; uint8_t arg3; uint16_t arg2; } my_insn;
typedef struct { uint16_t opcode; uint16_t _pad; } my_x_header;
struct my_ioc_rule {
        uint16_t act_ofs, cmd_len, rulenum; uint8_t set, insert; uint32_t sets;
        uint64_t pcnt, bcnt; uint32_t timestamp; my_insn cmd;
};

int main(void) {
        int s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
        if (s < 0) { perror("socket raw [needs root]"); return 2; }
        unsigned char buf[sizeof(my_x_header) + sizeof(struct my_ioc_rule)];
        memset(buf, 0, sizeof(buf));
        my_x_header *xh = (my_x_header *)buf; xh->opcode = MY_IP_FW_ADD;
        struct my_ioc_rule *r = (struct my_ioc_rule *)(buf + sizeof(my_x_header));
        /* module=0 (BASIC), opcode=0 (ACCEPT) -- both in range, registered */
        r->cmd_len = 2; r->cmd.opcode = 0; r->cmd.len = 2; r->cmd.module = 0;
        int rc = setsockopt(s, IPPROTO_IP, MY_IP_FW_X, buf, sizeof(buf));
        printf("ADD_LEGIT_RULE rc=%d %s\n", rc,
               rc ? strerror(errno) : "(legitimate rule ACCEPTED)");
        return rc ? 1 : 0;
}
