/*
* txtproto_print() derived from original code by Hannes Gredler
- * (hannes@juniper.net):
+ * (hannes@gredler.at):
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "netdissect.h"
+#include "extract.h"
#include "ascii_strcasecmp.h"
#include "timeval-operations.h"
int32_t thiszone; /* seconds offset from gmt to local time */
+/* invalid string to print '(invalid)' for malformed or corrupted packets */
+const char istr[] = " (invalid)";
+
+#define TOKBUFSIZE 128
/*
- * timestamp display buffer size, the biggest size of both formats is needed
- * sizeof("0000000000.000000000") > sizeof("00:00:00.000000000")
+ * Print out a character, filtering out the non-printable ones
*/
-#define TS_BUF_SIZE sizeof("0000000000.000000000")
+void
+fn_print_char(netdissect_options *ndo, u_char c)
+{
+ if (!ND_ISASCII(c)) {
+ c = ND_TOASCII(c);
+ ND_PRINT("M-");
+ }
+ if (!ND_ISPRINT(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ ND_PRINT("^");
+ }
+ ND_PRINT("%c", c);
+}
-#define TOKBUFSIZE 128
+/*
+ * Print a null-terminated string, filtering out non-printable characters.
+ * DON'T USE IT with a pointer on the packet buffer because there is no
+ * truncation check. For this use, see the nd_printX() functions below.
+ */
+void
+fn_print_str(netdissect_options *ndo, const u_char *s)
+{
+ while (*s != '\0') {
+ fn_print_char(ndo, *s);
+ s++;
+ }
+}
/*
- * Print out a null-terminated filename (or other ascii string).
+ * Print out a null-terminated filename (or other ASCII string), part of
+ * the packet buffer.
* If ep is NULL, assume no truncation check is needed.
* Return true if truncated.
* Stop at ep (if given) or before the null char, whichever is first.
*/
int
-fn_print(netdissect_options *ndo,
- register const u_char *s, register const u_char *ep)
+nd_print(netdissect_options *ndo,
+ const u_char *s, const u_char *ep)
{
- register int ret;
- register u_char c;
+ int ret;
+ u_char c;
ret = 1; /* assume truncated */
while (ep == NULL || s < ep) {
- c = *s++;
+ c = EXTRACT_U_1(s);
+ s++;
if (c == '\0') {
ret = 0;
break;
}
- if (!ND_ISASCII(c)) {
- c = ND_TOASCII(c);
- ND_PRINT((ndo, "M-"));
+ fn_print_char(ndo, c);
+ }
+ return(ret);
+}
+
+/*
+ * Print out a null-terminated filename (or other ASCII string) from
+ * a fixed-length field in the packet buffer, or from what remains of
+ * the packet.
+ *
+ * n is the length of the fixed-length field, or the number of bytes
+ * remaining in the packet based on its on-the-network length.
+ *
+ * If ep is non-null, it should point just past the last captured byte
+ * of the packet, e.g. ndo->ndo_snapend. If ep is NULL, we assume no
+ * truncation check, other than the checks of the field length/remaining
+ * packet data length, is needed.
+ *
+ * Return the number of bytes of string processed, including the
+ * terminating null, if not truncated; as the terminating null is
+ * included in the count, and as there must be a terminating null,
+ * this will always be non-zero. Return 0 if truncated.
+ */
+u_int
+nd_printztn(netdissect_options *ndo,
+ const u_char *s, u_int n, const u_char *ep)
+{
+ u_int bytes;
+ u_char c;
+
+ bytes = 0;
+ for (;;) {
+ if (n == 0 || (ep != NULL && s >= ep)) {
+ /*
+ * Truncated. This includes "no null before we
+ * got to the end of the fixed-length buffer or
+ * the end of the packet".
+ *
+ * XXX - BOOTP says "null-terminated", which
+ * means the maximum length of the string, in
+ * bytes, is 1 less than the size of the buffer,
+ * as there must always be a terminating null.
+ */
+ bytes = 0;
+ break;
}
- if (!ND_ISPRINT(c)) {
- c ^= 0x40; /* DEL to ?, others to alpha */
- ND_PRINT((ndo, "^"));
+
+ c = EXTRACT_U_1(s);
+ s++;
+ bytes++;
+ n--;
+ if (c == '\0') {
+ /* End of string */
+ break;
}
- ND_PRINT((ndo, "%c", c));
+ fn_print_char(ndo, c);
}
- return(ret);
+ return(bytes);
}
/*
- * Print out a counted filename (or other ascii string).
+ * Print out a counted filename (or other ASCII string), part of
+ * the packet buffer.
* If ep is NULL, assume no truncation check is needed.
* Return true if truncated.
* Stop at ep (if given) or after n bytes, whichever is first.
*/
int
-fn_printn(netdissect_options *ndo,
- register const u_char *s, register u_int n, register const u_char *ep)
+nd_printn(netdissect_options *ndo,
+ const u_char *s, u_int n, const u_char *ep)
{
- register u_char c;
+ u_char c;
while (n > 0 && (ep == NULL || s < ep)) {
n--;
- c = *s++;
- if (!ND_ISASCII(c)) {
- c = ND_TOASCII(c);
- ND_PRINT((ndo, "M-"));
- }
- if (!ND_ISPRINT(c)) {
- c ^= 0x40; /* DEL to ?, others to alpha */
- ND_PRINT((ndo, "^"));
- }
- ND_PRINT((ndo, "%c", c));
+ c = EXTRACT_U_1(s);
+ s++;
+ fn_print_char(ndo, c);
}
return (n == 0) ? 0 : 1;
}
/*
- * Print out a null-padded filename (or other ascii string).
+ * Print out a null-padded filename (or other ASCII string), part of
+ * the packet buffer.
* If ep is NULL, assume no truncation check is needed.
* Return true if truncated.
* Stop at ep (if given) or after n bytes or before the null char,
* whichever is first.
*/
int
-fn_printzp(netdissect_options *ndo,
- register const u_char *s, register u_int n,
- register const u_char *ep)
+nd_printzp(netdissect_options *ndo,
+ const u_char *s, u_int n,
+ const u_char *ep)
{
- register int ret;
- register u_char c;
+ int ret;
+ u_char c;
ret = 1; /* assume truncated */
while (n > 0 && (ep == NULL || s < ep)) {
n--;
- c = *s++;
+ c = EXTRACT_U_1(s);
+ s++;
if (c == '\0') {
ret = 0;
break;
}
- if (!ND_ISASCII(c)) {
- c = ND_TOASCII(c);
- ND_PRINT((ndo, "M-"));
- }
- if (!ND_ISPRINT(c)) {
- c ^= 0x40; /* DEL to ?, others to alpha */
- ND_PRINT((ndo, "^"));
- }
- ND_PRINT((ndo, "%c", c));
+ fn_print_char(ndo, c);
}
return (n == 0) ? 0 : ret;
}
/*
- * Format the timestamp
+ * Print the timestamp as HH:MM:SS.FRAC.
*/
-static char *
-ts_format(netdissect_options *ndo
-#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
-_U_
-#endif
-, int sec, int usec, char *buf)
+static void
+ts_hmsfrac_print(netdissect_options *ndo, int sec, int usec)
{
- const char *format;
-
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
switch (ndo->ndo_tstamp_precision) {
case PCAP_TSTAMP_PRECISION_MICRO:
- format = "%02d:%02d:%02d.%06u";
+ ND_PRINT("%02d:%02d:%02d.%06u", sec / 3600, (sec % 3600) / 60,
+ sec % 60, usec);
break;
case PCAP_TSTAMP_PRECISION_NANO:
- format = "%02d:%02d:%02d.%09u";
+ ND_PRINT("%02d:%02d:%02d.%09u", sec / 3600, (sec % 3600) / 60,
+ sec % 60, usec);
break;
default:
- format = "%02d:%02d:%02d.{unknown}";
+ ND_PRINT("%02d:%02d:%02d.{unknown}", sec / 3600, (sec % 3600) / 60,
+ sec % 60);
break;
}
#else
- format = "%02d:%02d:%02d.%06u";
+ ND_PRINT("%02d:%02d:%02d.%06u", sec / 3600, (sec % 3600) / 60,
+ sec % 60, usec);
#endif
-
- snprintf(buf, TS_BUF_SIZE, format,
- sec / 3600, (sec % 3600) / 60, sec % 60, usec);
-
- return buf;
}
/*
- * Format the timestamp - Unix timeval style
+ * Print the timestamp - Unix timeval style, as SECS.FRAC.
*/
-static char *
-ts_unix_format(netdissect_options *ndo
-#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
-_U_
-#endif
-, int sec, int usec, char *buf)
+static void
+ts_unix_print(netdissect_options *ndo, int sec, int usec)
{
- const char *format;
-
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
switch (ndo->ndo_tstamp_precision) {
case PCAP_TSTAMP_PRECISION_MICRO:
- format = "%u.%06u";
+ ND_PRINT("%u.%06u", (unsigned)sec, (unsigned)usec);
break;
case PCAP_TSTAMP_PRECISION_NANO:
- format = "%u.%09u";
+ ND_PRINT("%u.%09u", (unsigned)sec, (unsigned)usec);
break;
default:
- format = "%u.{unknown}";
+ ND_PRINT("%u.{unknown}", (unsigned)sec);
break;
}
#else
- format = "%u.%06u";
+ ND_PRINT("%u.%06u", (unsigned)sec, (unsigned)usec);
#endif
-
- snprintf(buf, TS_BUF_SIZE, format,
- (unsigned)sec, (unsigned)usec);
-
- return buf;
}
/*
*/
void
ts_print(netdissect_options *ndo,
- register const struct timeval *tvp)
+ const struct timeval *tvp)
{
- register int s;
+ int s;
struct tm *tm;
time_t Time;
- char buf[TS_BUF_SIZE];
static struct timeval tv_ref;
struct timeval tv_result;
int negative_offset;
case 0: /* Default */
s = (tvp->tv_sec + thiszone) % 86400;
- ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec, buf)));
+ ts_hmsfrac_print(ndo, s, tvp->tv_usec);
+ ND_PRINT(" ");
break;
case 1: /* No time stamp */
break;
case 2: /* Unix timeval style */
- ND_PRINT((ndo, "%s ", ts_unix_format(ndo,
- tvp->tv_sec, tvp->tv_usec, buf)));
+ ts_unix_print(ndo, tvp->tv_sec, tvp->tv_usec);
+ ND_PRINT(" ");
break;
case 3: /* Microseconds/nanoseconds since previous packet */
else
netdissect_timevalsub(tvp, &tv_ref, &tv_result, nano_prec);
- ND_PRINT((ndo, (negative_offset ? "-" : " ")));
-
- ND_PRINT((ndo, "%s ", ts_format(ndo,
- tv_result.tv_sec, tv_result.tv_usec, buf)));
+ ND_PRINT((negative_offset ? "-" : " "));
+ ts_hmsfrac_print(ndo, tv_result.tv_sec, tv_result.tv_usec);
+ ND_PRINT(" ");
if (ndo->ndo_tflag == 3)
tv_ref = *tvp; /* set timestamp for previous packet */
Time = (tvp->tv_sec + thiszone) - s;
tm = gmtime (&Time);
if (!tm)
- ND_PRINT((ndo, "Date fail "));
- else
- ND_PRINT((ndo, "%04d-%02d-%02d %s ",
- tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
- ts_format(ndo, s, tvp->tv_usec, buf)));
+ ND_PRINT("Date fail ");
+ else {
+ ND_PRINT("%04d-%02d-%02d ",
+ tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
+ ts_hmsfrac_print(ndo, s, tvp->tv_usec);
+ ND_PRINT(" ");
+ }
break;
}
}
/*
- * Print a relative number of seconds (e.g. hold time, prune timer)
+ * Print an unsigned relative number of seconds (e.g. hold time, prune timer)
* in the form 5m1s. This does no truncation, so 32230861 seconds
* is represented as 1y1w1d1h1m1s.
*/
void
-relts_print(netdissect_options *ndo,
- int secs)
+unsigned_relts_print(netdissect_options *ndo,
+ uint32_t secs)
{
static const char *lengths[] = {"y", "w", "d", "h", "m", "s"};
- static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
+ static const u_int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
const char **l = lengths;
- const int *s = seconds;
+ const u_int *s = seconds;
if (secs == 0) {
- ND_PRINT((ndo, "0s"));
+ ND_PRINT("0s");
return;
}
- if (secs < 0) {
- ND_PRINT((ndo, "-"));
- secs = -secs;
- }
while (secs > 0) {
if (secs >= *s) {
- ND_PRINT((ndo, "%d%s", secs / *s, *l));
+ ND_PRINT("%u%s", secs / *s, *l);
secs -= (secs / *s) * *s;
}
s++;
}
}
+/*
+ * Print a signed relative number of seconds (e.g. hold time, prune timer)
+ * in the form 5m1s. This does no truncation, so 32230861 seconds
+ * is represented as 1y1w1d1h1m1s.
+ */
+void
+signed_relts_print(netdissect_options *ndo,
+ int32_t secs)
+{
+ if (secs < 0) {
+ ND_PRINT("-");
+ if (secs == INT32_MIN) {
+ /*
+ * -2^31; you can't fit its absolute value into
+ * a 32-bit signed integer.
+ *
+ * Just directly pass said absolute value to
+ * unsigned_relts_print() directly.
+ *
+ * (XXX - does ISO C guarantee that -(-2^n),
+ * when calculated and cast to an n-bit unsigned
+ * integer type, will have the value 2^n?)
+ */
+ unsigned_relts_print(ndo, 2147483648U);
+ } else {
+ /*
+ * We now know -secs will fit into an int32_t;
+ * negate it and pass that to unsigned_relts_print().
+ */
+ unsigned_relts_print(ndo, -secs);
+ }
+ return;
+ }
+ unsigned_relts_print(ndo, secs);
+}
+
+/* Print the truncated string */
+void nd_print_trunc(netdissect_options *ndo)
+{
+ ND_PRINT(" [|%s]", ndo->ndo_protocol);
+}
+
/*
* this is a generic routine for printing unknown data;
* we pass on the linefeed plus indentation string to
print_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,int len)
{
if (len < 0) {
- ND_PRINT((ndo,"%sDissector error: print_unknown_data called with negative length",
- ident));
+ ND_PRINT("%sDissector error: print_unknown_data called with negative length",
+ ident);
return(0);
}
if (ndo->ndo_snapend - cp < len)
len = ndo->ndo_snapend - cp;
if (len < 0) {
- ND_PRINT((ndo,"%sDissector error: print_unknown_data called with pointer past end of packet",
- ident));
+ ND_PRINT("%sDissector error: print_unknown_data called with pointer past end of packet",
+ ident);
return(0);
}
hex_print(ndo, ident,cp,len);
* Convert a token value to a string; use "fmt" if not found.
*/
const char *
-tok2strbuf(register const struct tok *lp, register const char *fmt,
- register u_int v, char *buf, size_t bufsize)
+tok2strbuf(const struct tok *lp, const char *fmt,
+ u_int v, char *buf, size_t bufsize)
{
if (lp != NULL) {
while (lp->s != NULL) {
if (fmt == NULL)
fmt = "#%d";
- (void)snprintf(buf, bufsize, fmt, v);
+ (void)nd_snprintf(buf, bufsize, fmt, v);
return (const char *)buf;
}
/*
* Convert a token value to a string; use "fmt" if not found.
+ * Uses tok2strbuf() on one of four local static buffers of size TOKBUFSIZE
+ * in round-robin fashion.
*/
const char *
-tok2str(register const struct tok *lp, register const char *fmt,
- register u_int v)
+tok2str(const struct tok *lp, const char *fmt,
+ u_int v)
{
static char buf[4][TOKBUFSIZE];
static int idx = 0;
/*
* Convert a bit token value to a string; use "fmt" if not found.
- * this is useful for parsing bitfields, the output strings are seperated
+ * this is useful for parsing bitfields, the output strings are separated
* if the s field is positive.
*/
static char *
-bittok2str_internal(register const struct tok *lp, register const char *fmt,
- register u_int v, const char *sep)
+bittok2str_internal(const struct tok *lp, const char *fmt,
+ u_int v, const char *sep)
{
- static char buf[256]; /* our stringbuffer */
- int buflen=0;
- register u_int rotbit; /* this is the bit we rotate through all bitpositions */
- register u_int tokval;
+ static char buf[1024+1]; /* our string buffer */
+ char *bufp = buf;
+ size_t space_left = sizeof(buf), string_size;
+ u_int rotbit; /* this is the bit we rotate through all bitpositions */
+ u_int tokval;
const char * sepstr = "";
while (lp != NULL && lp->s != NULL) {
*/
if (tokval == (v&rotbit)) {
/* ok we have found something */
- buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
- sepstr, lp->s);
+ if (space_left <= 1)
+ return (buf); /* only enough room left for NUL, if that */
+ string_size = strlcpy(bufp, sepstr, space_left);
+ if (string_size >= space_left)
+ return (buf); /* we ran out of room */
+ bufp += string_size;
+ space_left -= string_size;
+ if (space_left <= 1)
+ return (buf); /* only enough room left for NUL, if that */
+ string_size = strlcpy(bufp, lp->s, space_left);
+ if (string_size >= space_left)
+ return (buf); /* we ran out of room */
+ bufp += string_size;
+ space_left -= string_size;
sepstr = sep;
break;
}
lp++;
}
- if (buflen == 0)
+ if (bufp == buf)
/* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
- (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
+ (void)nd_snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
return (buf);
}
/*
* Convert a bit token value to a string; use "fmt" if not found.
- * this is useful for parsing bitfields, the output strings are not seperated.
+ * this is useful for parsing bitfields, the output strings are not separated.
*/
char *
-bittok2str_nosep(register const struct tok *lp, register const char *fmt,
- register u_int v)
+bittok2str_nosep(const struct tok *lp, const char *fmt,
+ u_int v)
{
return (bittok2str_internal(lp, fmt, v, ""));
}
/*
* Convert a bit token value to a string; use "fmt" if not found.
- * this is useful for parsing bitfields, the output strings are comma seperated.
+ * this is useful for parsing bitfields, the output strings are comma separated.
*/
char *
-bittok2str(register const struct tok *lp, register const char *fmt,
- register u_int v)
+bittok2str(const struct tok *lp, const char *fmt,
+ u_int v)
{
return (bittok2str_internal(lp, fmt, v, ", "));
}
* correct for bounds-checking.
*/
const char *
-tok2strary_internal(register const char **lp, int n, register const char *fmt,
- register int v)
+tok2strary_internal(const char **lp, int n, const char *fmt,
+ int v)
{
static char buf[TOKBUFSIZE];
return lp[v];
if (fmt == NULL)
fmt = "#%d";
- (void)snprintf(buf, sizeof(buf), fmt, v);
+ (void)nd_snprintf(buf, sizeof(buf), fmt, v);
return (buf);
}
return (prefix_len);
}
-#ifdef INET6
int
mask62plen(const u_char *mask)
{
}
return (cidr_len);
}
-#endif /* INET6 */
/*
* Routine to print out information for text-based protocols such as FTP,
size_t toklen = 0;
for (; idx < len; idx++) {
- if (!ND_TTEST(*(pptr + idx))) {
+ if (!ND_TTEST_1(pptr + idx)) {
/* ran past end of captured data */
return (0);
}
- if (!isascii(*(pptr + idx))) {
+ if (!isascii(EXTRACT_U_1(pptr + idx))) {
/* not an ASCII character */
return (0);
}
- if (isspace(*(pptr + idx))) {
+ if (isspace(EXTRACT_U_1(pptr + idx))) {
/* end of token */
break;
}
- if (!isprint(*(pptr + idx))) {
+ if (!isprint(EXTRACT_U_1(pptr + idx))) {
/* not part of a command token or response code */
return (0);
}
/* no room for this character and terminating '\0' */
return (0);
}
- tbuf[toklen] = *(pptr + idx);
+ tbuf[toklen] = EXTRACT_U_1(pptr + idx);
toklen++;
}
if (toklen == 0) {
* an end-of-line (CR or LF).
*/
for (; idx < len; idx++) {
- if (!ND_TTEST(*(pptr + idx))) {
+ if (!ND_TTEST_1(pptr + idx)) {
/* ran past end of captured data */
break;
}
- if (*(pptr + idx) == '\r' || *(pptr + idx) == '\n') {
+ if (EXTRACT_U_1(pptr + idx) == '\r' || EXTRACT_U_1(pptr + idx) == '\n') {
/* end of line */
break;
}
- if (!isascii(*(pptr + idx)) || !isprint(*(pptr + idx))) {
+ if (!isascii(EXTRACT_U_1(pptr + idx)) || !isprint(EXTRACT_U_1(pptr + idx))) {
/* not a printable ASCII character */
break;
}
- if (!isspace(*(pptr + idx))) {
+ if (!isspace(EXTRACT_U_1(pptr + idx))) {
/* beginning of next token */
break;
}
startidx = idx;
while (idx < len) {
- ND_TCHECK(*(pptr+idx));
- if (*(pptr+idx) == '\n') {
+ ND_TCHECK_1(pptr + idx);
+ if (EXTRACT_U_1(pptr + idx) == '\n') {
/*
* LF without CR; end of line.
* Skip the LF and print the line, with the
linelen = idx - startidx;
idx++;
goto print;
- } else if (*(pptr+idx) == '\r') {
+ } else if (EXTRACT_U_1(pptr + idx) == '\r') {
/* CR - any LF? */
if ((idx+1) >= len) {
/* not in this packet */
return (0);
}
- ND_TCHECK(*(pptr+idx+1));
- if (*(pptr+idx+1) == '\n') {
+ ND_TCHECK_1(pptr + idx + 1);
+ if (EXTRACT_U_1(pptr + idx + 1) == '\n') {
/*
* CR-LF; end of line.
* Skip the CR-LF and print the line, with
* it.
*/
return (0);
- } else if (!isascii(*(pptr+idx)) ||
- (!isprint(*(pptr+idx)) && *(pptr+idx) != '\t')) {
+ } else if (!isascii(EXTRACT_U_1(pptr + idx)) ||
+ (!isprint(EXTRACT_U_1(pptr + idx)) &&
+ EXTRACT_U_1(pptr + idx) != '\t')) {
/*
* Not a printable ASCII character and not a tab;
* treat this as if it were binary data, and
*/
trunc:
linelen = idx - startidx;
- ND_PRINT((ndo, "%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx,
- protoname));
+ ND_PRINT("%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx,
+ protoname);
return (0);
print:
- ND_PRINT((ndo, "%s%.*s", prefix, (int)linelen, pptr + startidx));
+ ND_PRINT("%s%.*s", prefix, (int)linelen, pptr + startidx);
return (idx);
}
u_int idx, eol;
u_char token[MAX_TOKEN+1];
const char *cmd;
- int is_reqresp = 0;
+ int print_this = 0;
const char *pnp;
if (cmds != NULL) {
/*
* This protocol has more than just request and
* response lines; see whether this looks like a
- * request or response.
+ * request or response and, if so, print it and,
+ * in verbose mode, print everything after it.
+ *
+ * This is for HTTP-like protocols, where we
+ * want to print requests and responses, but
+ * don't want to print continuations of request
+ * or response bodies in packets that don't
+ * contain the request or response line.
*/
idx = fetch_token(ndo, pptr, 0, len, token, sizeof(token));
if (idx != 0) {
while ((cmd = *cmds++) != NULL) {
if (ascii_strcasecmp((const char *)token, cmd) == 0) {
/* Yes. */
- is_reqresp = 1;
+ print_this = 1;
break;
}
}
if (isdigit(token[0]) && isdigit(token[1]) &&
isdigit(token[2]) && token[3] == '\0') {
/* Yes. */
- is_reqresp = 1;
+ print_this = 1;
}
}
}
} else {
/*
- * This protocol has only request and response lines
- * (e.g., FTP, where all the data goes over a
- * different connection); assume the payload is
- * a request or response.
+ * Either:
+ *
+ * 1) This protocol has only request and response lines
+ * (e.g., FTP, where all the data goes over a different
+ * connection); assume the payload is a request or
+ * response.
+ *
+ * or
+ *
+ * 2) This protocol is just text, so that we should
+ * always, at minimum, print the first line and,
+ * in verbose mode, print all lines.
*/
- is_reqresp = 1;
+ print_this = 1;
}
/* Capitalize the protocol name */
for (pnp = protoname; *pnp != '\0'; pnp++)
- ND_PRINT((ndo, "%c", toupper(*pnp)));
+ ND_PRINT("%c", toupper((u_char)*pnp));
- if (is_reqresp) {
+ if (print_this) {
/*
* In non-verbose mode, just print the protocol, followed
- * by the first line as the request or response info.
+ * by the first line.
*
* In verbose mode, print lines as text until we run out
* of characters or see something that's not a
* request or response; just print the length
* on the first line of the output.
*/
- ND_PRINT((ndo, ", length: %u", len));
+ ND_PRINT(", length: %u", len);
for (idx = 0;
idx < len && (eol = print_txt_line(ndo, protoname, "\n\t", pptr, idx, len)) != 0;
idx = eol)
}
}
-void
-safeputs(netdissect_options *ndo,
- const u_char *s, const u_int maxlen)
-{
- u_int idx = 0;
-
- while (*s && idx < maxlen) {
- safeputchar(ndo, *s);
- idx++;
- s++;
- }
-}
-
-void
-safeputchar(netdissect_options *ndo,
- const u_char c)
-{
- ND_PRINT((ndo, (c < 0x80 && ND_ISPRINT(c)) ? "%c" : "\\0x%02x", c));
-}
-
-#ifdef LBL_ALIGN
+#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
+ (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \
+ (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
+ (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
+ (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || \
+ defined(__vax__)
+/*
+ * The procesor natively handles unaligned loads, so just use memcpy()
+ * and memcmp(), to enable those optimizations.
+ *
+ * XXX - are those all the x86 tests we need?
+ * XXX - do we need to worry about ARMv1 through ARMv5, which didn't
+ * support unaligned loads, and, if so, do we need to worry about all
+ * of them, or just some of them, e.g. ARMv5?
+ * XXX - are those the only 68k tests we need not to generated
+ * unaligned accesses if the target is the 68000 or 68010?
+ * XXX - are there any tests we don't need, because some definitions are for
+ * compilers that also predefine the GCC symbols?
+ * XXX - do we need to test for both 32-bit and 64-bit versions of those
+ * architectures in all cases?
+ */
+#else
/*
- * Some compilers try to optimize memcpy(), using the alignment constraint
- * on the argument pointer type. by using this function, we try to avoid the
- * optimization.
+ * The processor doesn't natively handle unaligned loads,
+ * and the compiler might "helpfully" optimize memcpy()
+ * and memcmp(), when handed pointers that would normally
+ * be properly aligned, into sequences that assume proper
+ * alignment.
+ *
+ * Do copies and compares of possibly-unaligned data by
+ * calling routines that wrap memcpy() and memcmp(), to
+ * prevent that optimization.
*/
void
unaligned_memcpy(void *p, const void *q, size_t l)