]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-resp.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-resp.c
index 1d24b58e660e6de691603f6cc4557c3dd5b15e40..1cefbaccda53e3ba1ab191f9d43c2ed21e3fb157 100644 (file)
 
 /* \summary: REdis Serialization Protocol (RESP) printer */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <config.h>
 
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
 #include "netdissect.h"
 #include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
 
 #include "extract.h"
 
-static const char tstr[] = " [|RESP]";
 
 /*
- * For information regarding RESP, see: http://redis.io/topics/protocol
+ * For information regarding RESP, see: https://redis.io/topics/protocol
  */
 
 #define RESP_SIMPLE_STRING    '+'
@@ -54,13 +48,12 @@ static const char tstr[] = " [|RESP]";
 #define RESP_BULK_STRING      '$'
 #define RESP_ARRAY            '*'
 
-#define resp_print_empty(ndo)            ND_PRINT((ndo, " empty"))
-#define resp_print_null(ndo)             ND_PRINT((ndo, " null"))
-#define resp_print_length_too_large(ndo) ND_PRINT((ndo, " length too large"))
-#define resp_print_length_negative(ndo)  ND_PRINT((ndo, " length negative and not -1"))
-#define resp_print_invalid(ndo)          ND_PRINT((ndo, " invalid"))
+#define resp_print_empty(ndo)            ND_PRINT(" empty")
+#define resp_print_null(ndo)             ND_PRINT(" null")
+#define resp_print_length_too_large(ndo) ND_PRINT(" length too large")
+#define resp_print_length_negative(ndo)  ND_PRINT(" length negative and not -1")
+#define resp_print_invalid(ndo)          ND_PRINT(" invalid")
 
-void       resp_print(netdissect_options *, const u_char *, u_int);
 static int resp_parse(netdissect_options *, const u_char *, int);
 static int resp_print_string_error_integer(netdissect_options *, const u_char *, int);
 static int resp_print_simple_string(netdissect_options *, const u_char *, int);
@@ -90,8 +83,9 @@ static int resp_get_length(netdissect_options *, const u_char *, int, const u_ch
 #define FIND_CRLF(_ptr, _len)                   \
     for (;;) {                                  \
         LCHECK2(_len, 2);                       \
-        ND_TCHECK_2(_ptr);                   \
-        if (*_ptr == '\r' && *(_ptr+1) == '\n') \
+        ND_TCHECK_2(_ptr);                      \
+        if (GET_U_1(_ptr) == '\r' &&            \
+            GET_U_1(_ptr+1) == '\n')            \
             break;                              \
         _ptr++;                                 \
         _len--;                                 \
@@ -116,8 +110,8 @@ static int resp_get_length(netdissect_options *, const u_char *, int, const u_ch
 #define FIND_CR_OR_LF(_ptr, _len)           \
     for (;;) {                              \
         LCHECK(_len);                       \
-        ND_TCHECK(*_ptr);                   \
-        if (*_ptr == '\r' || *_ptr == '\n') \
+        if (GET_U_1(_ptr) == '\r' ||        \
+            GET_U_1(_ptr) == '\n')          \
             break;                          \
         _ptr++;                             \
         _len--;                             \
@@ -136,7 +130,7 @@ static int resp_get_length(netdissect_options *, const u_char *, int, const u_ch
             /*                                   \
              * Have we hit the end of data?      \
              */                                  \
-            if (_len == 0 || !ND_TTEST(*_ptr)) { \
+            if (_len == 0 || !ND_TTEST_1(_ptr)) {\
                 /*                               \
                  * Yes.  Have we seen a \r       \
                  * or \n?                        \
@@ -152,7 +146,8 @@ static int resp_get_length(netdissect_options *, const u_char *, int, const u_ch
                  */                              \
                 goto trunc;                      \
             }                                    \
-            if (*_ptr != '\r' && *_ptr != '\n')  \
+            if (GET_U_1(_ptr) != '\r' &&         \
+                GET_U_1(_ptr) != '\n')           \
                 break;                           \
             _found_cr_or_lf = 1;                 \
             _ptr++;                              \
@@ -186,6 +181,9 @@ static int resp_get_length(netdissect_options *, const u_char *, int, const u_ch
  * TEST_RET_LEN
  * If ret_len is < 0, jump to the trunc tag which returns (-1)
  * and 'bubbles up' to printing tstr. Otherwise, return ret_len.
+ *
+ * Note that using this macro with a semicolon at the end emits a warning from
+ * Sun C about an unreachable statement (the semicolon is the statement).
  */
 #define TEST_RET_LEN(rl) \
     if (rl < 0) { goto trunc; } else { return rl; }
@@ -204,21 +202,20 @@ static int resp_get_length(netdissect_options *, const u_char *, int, const u_ch
  * Assumes the data has already been verified as present.
  */
 #define RESP_PRINT_SEGMENT(_ndo, _bp, _len)            \
-    ND_PRINT((_ndo, " \""));                           \
-    if (fn_printn(_ndo, _bp, _len, _ndo->ndo_snapend)) \
+    ND_PRINT(" \"");                                   \
+    if (nd_printn(_ndo, _bp, _len, _ndo->ndo_snapend)) \
         goto trunc;                                    \
-    fn_print_char(_ndo, '"');
+    ND_PRINT("\"");
 
 void
 resp_print(netdissect_options *ndo, const u_char *bp, u_int length)
 {
-    int ret_len = 0, length_cur = length;
+    int ret_len = 0;
 
-    if(!bp || length <= 0)
-        return;
+    ndo->ndo_protocol = "resp";
 
-    ND_PRINT((ndo, ": RESP"));
-    while (length_cur > 0) {
+    ND_PRINT(": RESP");
+    while (length != 0) {
         /*
          * This block supports redis pipelining.
          * For example, multiple operations can be pipelined within the same string:
@@ -228,16 +225,16 @@ resp_print(netdissect_options *ndo, const u_char *bp, u_int length)
          * In order to handle this case, we must try and parse 'bp' until
          * 'length' bytes have been processed or we reach a trunc condition.
          */
-        ret_len = resp_parse(ndo, bp, length_cur);
+        ret_len = resp_parse(ndo, bp, length);
         TEST_RET_LEN_NORETURN(ret_len);
         bp += ret_len;
-        length_cur -= ret_len;
+        length -= ret_len;
     }
 
     return;
 
 trunc:
-    ND_PRINT((ndo, "%s", tstr));
+    nd_print_trunc(ndo);
 }
 
 static int
@@ -247,8 +244,7 @@ resp_parse(netdissect_options *ndo, const u_char *bp, int length)
     int ret_len;
 
     LCHECK2(length, 1);
-    ND_TCHECK_1(bp);
-    op = EXTRACT_U_1(bp);
+    op = GET_U_1(bp);
 
     /* bp now points to the op, so these routines must skip it */
     switch(op) {
@@ -265,7 +261,7 @@ resp_parse(netdissect_options *ndo, const u_char *bp, int length)
      * including invalid packet errors; that's what we want, as
      * we have to give up on further parsing in that case.
      */
-    TEST_RET_LEN(ret_len);
+    TEST_RET_LEN(ret_len) // without a semicolon
 
 trunc:
     return (-1);
@@ -311,11 +307,11 @@ resp_print_string_error_integer(netdissect_options *ndo, const u_char *bp, int l
      * preceding the \r\n.  That includes the opcode, so don't print
      * that.
      */
-    len = (bp_ptr - bp);
+    len = ND_BYTES_BETWEEN(bp, bp_ptr);
     RESP_PRINT_SEGMENT(ndo, bp, len);
     ret_len = 1 /*<opcode>*/ + len /*<string>*/ + 2 /*<CRLF>*/;
 
-    TEST_RET_LEN(ret_len);
+    TEST_RET_LEN(ret_len) // without a semicolon
 
 trunc:
     return (-1);
@@ -434,9 +430,9 @@ resp_print_inline(netdissect_options *ndo, const u_char *bp, int length) {
 
     /*
      * Found it; bp_ptr points to the \r or \n, so bp_ptr - bp is the
-     * Length of the line text that preceeds it.  Print it.
+     * Length of the line text that precedes it.  Print it.
      */
-    len = (bp_ptr - bp);
+    len = ND_BYTES_BETWEEN(bp, bp_ptr);
     RESP_PRINT_SEGMENT(ndo, bp, len);
 
     /*
@@ -464,10 +460,9 @@ resp_get_length(netdissect_options *ndo, const u_char *bp, int len, const u_char
 
     if (len == 0)
         goto trunc;
-    ND_TCHECK_1(bp);
     too_large = 0;
     neg = 0;
-    if (EXTRACT_U_1(bp) == '-') {
+    if (GET_U_1(bp) == '-') {
         neg = 1;
         bp++;
         len--;
@@ -478,8 +473,7 @@ resp_get_length(netdissect_options *ndo, const u_char *bp, int len, const u_char
     for (;;) {
         if (len == 0)
             goto trunc;
-        ND_TCHECK_1(bp);
-        c = EXTRACT_U_1(bp);
+        c = GET_U_1(bp);
         if (!(c >= '0' && c <= '9')) {
             if (!saw_digit) {
                 bp++;
@@ -508,7 +502,7 @@ resp_get_length(netdissect_options *ndo, const u_char *bp, int len, const u_char
      * OK, we found a non-digit character.  It should be a \r, followed
      * by a \n.
      */
-    if (EXTRACT_U_1(bp) != '\r') {
+    if (GET_U_1(bp) != '\r') {
         bp++;
         goto invalid;
     }
@@ -516,8 +510,7 @@ resp_get_length(netdissect_options *ndo, const u_char *bp, int len, const u_char
     len--;
     if (len == 0)
         goto trunc;
-    ND_TCHECK_1(bp);
-    if (EXTRACT_U_1(bp) != '\n') {
+    if (GET_U_1(bp) != '\n') {
         bp++;
         goto invalid;
     }