]> The Tcpdump Group git mirrors - libpcap/commitdiff
Factor assert_atm() out.
authorDenis Ovsienko <[email protected]>
Fri, 21 Mar 2025 15:27:54 +0000 (15:27 +0000)
committerDenis Ovsienko <[email protected]>
Sat, 22 Mar 2025 16:17:16 +0000 (16:17 +0000)
Add another helper function for ATM keywords, replace 13 hard-coded
error messages with one parametrised message and spell the DLT name
correctly.

gencode.c

index f0d1f5563ca470d52906c6b6ca7a1b26fec7523a..e568488cfca615e45a7482ebce0cd617eba6f75c 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -947,6 +947,36 @@ dqkw(const unsigned id)
        return qual2kw("dir", id, map, sizeof(map) / sizeof(map[0]));
 }
 
+// ATM keywords
+static const char *
+atmkw(const unsigned id)
+{
+       const char * tokens[] = {
+               [A_METAC] = "metac",
+               [A_BCC] = "bcc",
+               [A_OAMF4SC] = "oamf4sc",
+               [A_OAMF4EC] = "oamf4ec",
+               [A_SC] = "sc",
+               [A_ILMIC] = "ilmic",
+               [A_OAM] = "oam",
+               [A_OAMF4] = "oamf4",
+               [A_LANE] = "lane",
+               // no keyword for A_SETUP
+               // no keyword for A_CALLPROCEED
+               // no keyword for A_CONNECT
+               // no keyword for A_CONNECTACK
+               // no keyword for A_RELEASE
+               // no keyword for A_RELEASE_DONE
+               [A_VPI] = "vpi",
+               [A_VCI] = "vci",
+               // no keyword for A_PROTOTYPE
+               // no keyword for A_MSGTYPE
+               [A_CONNECTMSG] = "connectmsg",
+               [A_METACONNECT] = "metaconnect",
+       };
+       return qual2kw("ATM keyword", id, tokens, sizeof(tokens) / sizeof(tokens[0]));
+}
+
 static PCAP_NORETURN_DEF void
 fail_kw_on_dlt(compiler_state_t *cstate, const char *keyword)
 {
@@ -961,6 +991,22 @@ assert_pflog(compiler_state_t *cstate, const char *kw)
                bpf_error(cstate, "'%s' supported only on PFLOG linktype", kw);
 }
 
+static void
+assert_atm(compiler_state_t *cstate, const char *kw)
+{
+       /*
+        * Belt and braces: init_linktype() sets either all of these struct
+        * members (for DLT_SUNATM) or none (otherwise).
+        */
+       if (cstate->linktype != DLT_SUNATM ||
+           ! cstate->is_atm ||
+           cstate->off_vpi == OFFSET_NOT_SET ||
+           cstate->off_vci == OFFSET_NOT_SET ||
+           cstate->off_proto == OFFSET_NOT_SET ||
+           cstate->off_payload == OFFSET_NOT_SET)
+               bpf_error(cstate, "'%s' supported only on SUNATM", kw);
+}
+
 #define ERRSTR_802_11_ONLY_KW "'%s' is valid for 802.11 syntax only"
 #define ERRSTR_INVALID_QUAL "'%s' is not a valid qualifier for '%s'"
 
@@ -9771,13 +9817,19 @@ gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield,
 {
        struct block *b0;
 
+       /*
+        * This check is a no-op for A_MSGTYPE so long as the only incoming
+        * code path is from gen_atmmulti_abbrev(), which makes the same
+        * check first; also for A_PROTOTYPE so long as the only incoming code
+        * paths are from gen_atmtype_abbrev(), which makes the same check
+        * first, or from gen_llc_internal() or gen_linktype(), which restrict
+        * it to DLT_SUNATM.
+        */
+       assert_atm(cstate, atmkw(atmfield));
+
        switch (atmfield) {
 
        case A_VPI:
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'vpi' supported only on raw ATM");
-               if (cstate->off_vpi == OFFSET_NOT_SET)
-                       abort();
                if (jvalue > UINT8_MAX)
                        bpf_error(cstate, "VPI value %u > %u", jvalue, UINT8_MAX);
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B,
@@ -9785,10 +9837,6 @@ gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield,
                break;
 
        case A_VCI:
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'vci' supported only on raw ATM");
-               if (cstate->off_vci == OFFSET_NOT_SET)
-                       abort();
                if (jvalue > UINT16_MAX)
                        bpf_error(cstate, "VCI value %u > %u", jvalue, UINT16_MAX);
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H,
@@ -9796,15 +9844,11 @@ gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield,
                break;
 
        case A_PROTOTYPE:
-               if (cstate->off_proto == OFFSET_NOT_SET)
-                       abort();        /* XXX - this isn't on FreeBSD */
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B,
                    0x0fU, jtype, reverse, jvalue);
                break;
 
        case A_MSGTYPE:
-               if (cstate->off_payload == OFFSET_NOT_SET)
-                       abort();
                b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS, BPF_B,
                    0xffffffffU, jtype, reverse, jvalue);
                break;
@@ -9874,19 +9918,17 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
        if (setjmp(cstate->top_ctx))
                return (NULL);
 
+       assert_atm(cstate, atmkw(type));
+
        switch (type) {
 
        case A_METAC:
                /* Get all packets in Meta signalling Circuit */
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'metac' supported only on raw ATM");
                b1 = gen_atmtype_metac(cstate);
                break;
 
        case A_BCC:
                /* Get all packets in Broadcast Circuit*/
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'bcc' supported only on raw ATM");
                b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
                b1 = gen_atmfield_code_internal(cstate, A_VCI, 2, BPF_JEQ, 0);
                gen_and(b0, b1);
@@ -9894,8 +9936,6 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
 
        case A_OAMF4SC:
                /* Get all cells in Segment OAM F4 circuit*/
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'oam4sc' supported only on raw ATM");
                b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
                b1 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
                gen_and(b0, b1);
@@ -9903,8 +9943,6 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
 
        case A_OAMF4EC:
                /* Get all cells in End-to-End OAM F4 Circuit*/
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'oam4ec' supported only on raw ATM");
                b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
                b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
                gen_and(b0, b1);
@@ -9912,15 +9950,11 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
 
        case A_SC:
                /*  Get all packets in connection Signalling Circuit */
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'sc' supported only on raw ATM");
                b1 = gen_atmtype_sc(cstate);
                break;
 
        case A_ILMIC:
                /* Get all packets in ILMI Circuit */
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'ilmic' supported only on raw ATM");
                b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
                b1 = gen_atmfield_code_internal(cstate, A_VCI, 16, BPF_JEQ, 0);
                gen_and(b0, b1);
@@ -9928,8 +9962,6 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
 
        case A_LANE:
                /* Get all LANE packets */
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'lane' supported only on raw ATM");
                b1 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
 
                /*
@@ -10238,11 +10270,11 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
        if (setjmp(cstate->top_ctx))
                return (NULL);
 
+       assert_atm(cstate, atmkw(type));
+
        switch (type) {
 
        case A_OAM:
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'oam' supported only on raw ATM");
                /* OAM F4 type */
                b0 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
                b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
@@ -10252,8 +10284,6 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
                break;
 
        case A_OAMF4:
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'oamf4' supported only on raw ATM");
                /* OAM F4 type */
                b0 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
                b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
@@ -10267,8 +10297,6 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
                 * Get Q.2931 signalling messages for switched
                 * virtual connection
                 */
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'connectmsg' supported only on raw ATM");
                b0 = gen_msg_abbrev(cstate, A_SETUP);
                b1 = gen_msg_abbrev(cstate, A_CALLPROCEED);
                gen_or(b0, b1);
@@ -10285,8 +10313,6 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
                break;
 
        case A_METACONNECT:
-               if (!cstate->is_atm)
-                       bpf_error(cstate, "'metaconnect' supported only on raw ATM");
                b0 = gen_msg_abbrev(cstate, A_SETUP);
                b1 = gen_msg_abbrev(cstate, A_CALLPROCEED);
                gen_or(b0, b1);