12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
22892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*
23892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * txtproto_print() derived from original code by Hannes Gredler
24892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * (hannes@juniper.net):
25892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes *
26892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Redistribution and use in source and binary forms, with or without
27892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * modification, are permitted provided that: (1) source code
28892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * distributions retain the above copyright notice and this paragraph
29892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * in its entirety, and (2) distributions including binary code include
30892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * the above copyright notice and this paragraph in its entirety in
31892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * the documentation or other materials provided with the distribution.
32892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
33892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
34892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * FOR A PARTICULAR PURPOSE.
36892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes */
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
42e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include <netdissect-stdinc.h>
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <sys/stat.h>
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_FCNTL_H
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <fcntl.h>
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
49e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include <ctype.h>
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdarg.h>
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdlib.h>
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
55e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include "netdissect.h"
56e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include "ascii_strcasecmp.h"
57e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include "timeval-operations.h"
58e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
59e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesint32_t thiszone;		/* seconds offset from gmt to local time */
60e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/* invalid string to print '(invalid)' for malformed or corrupted packets */
61e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesconst char istr[] = " (invalid)";
62e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
63e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/*
64e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * timestamp display buffer size, the biggest size of both formats is needed
65e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * sizeof("0000000000.000000000") > sizeof("00:00:00.000000000")
66e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes */
67e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#define TS_BUF_SIZE sizeof("0000000000.000000000")
68e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
69e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#define TOKBUFSIZE 128
70e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
71e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/*
72e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Print out a character, filtering out the non-printable ones
73e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes */
74e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesvoid
75e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesfn_print_char(netdissect_options *ndo, u_char c)
76e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes{
77e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	if (!ND_ISASCII(c)) {
78e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		c = ND_TOASCII(c);
79e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "M-"));
80e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	}
81e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	if (!ND_ISPRINT(c)) {
82e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		c ^= 0x40;	/* DEL to ?, others to alpha */
83e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "^"));
84e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	}
85e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	ND_PRINT((ndo, "%c", c));
86e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes}
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print out a null-terminated filename (or other ascii string).
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * If ep is NULL, assume no truncation check is needed.
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Return true if truncated.
92e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Stop at ep (if given) or before the null char, whichever is first.
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
95892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfn_print(netdissect_options *ndo,
96892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes         register const u_char *s, register const u_char *ep)
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register int ret;
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_char c;
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ret = 1;			/* assume truncated */
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (ep == NULL || s < ep) {
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		c = *s++;
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (c == '\0') {
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ret = 0;
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
10853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ND_ISASCII(c)) {
10953f17a9db278d33517d9888dd77848f554522a38JP Abgrall			c = ND_TOASCII(c);
110892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "M-"));
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
11253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ND_ISPRINT(c)) {
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			c ^= 0x40;	/* DEL to ?, others to alpha */
114892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "^"));
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
116892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%c", c));
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return(ret);
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
122e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Print out a null-terminated filename (or other ascii string) from
123e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * a fixed-length buffer.
124e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * If ep is NULL, assume no truncation check is needed.
125e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Return the number of bytes of string processed, including the
126e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * terminating null, if not truncated.  Return 0 if truncated.
127e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes */
128e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesu_int
129e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesfn_printztn(netdissect_options *ndo,
130e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes         register const u_char *s, register u_int n, register const u_char *ep)
131e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes{
132e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register u_int bytes;
133e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	register u_char c;
134e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
135e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	bytes = 0;
136e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	for (;;) {
137e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (n == 0 || (ep != NULL && s >= ep)) {
138e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			/*
139e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * Truncated.  This includes "no null before we
140e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * got to the end of the fixed-length buffer".
141e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 *
142e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * XXX - BOOTP says "null-terminated", which
143e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * means the maximum length of the string, in
144e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * bytes, is 1 less than the size of the buffer,
145e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * as there must always be a terminating null.
146e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 */
147e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			bytes = 0;
148e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			break;
149e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		}
150e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
151e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		c = *s++;
152e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		bytes++;
153e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		n--;
154e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (c == '\0') {
155e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			/* End of string */
156e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			break;
157e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		}
158e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (!ND_ISASCII(c)) {
159e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			c = ND_TOASCII(c);
160e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			ND_PRINT((ndo, "M-"));
161e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		}
162e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (!ND_ISPRINT(c)) {
163e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			c ^= 0x40;	/* DEL to ?, others to alpha */
164e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			ND_PRINT((ndo, "^"));
165e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		}
166e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "%c", c));
167e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	}
168e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	return(bytes);
169e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes}
170e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
171e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/*
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print out a counted filename (or other ascii string).
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * If ep is NULL, assume no truncation check is needed.
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Return true if truncated.
175e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Stop at ep (if given) or after n bytes, whichever is first.
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
178892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfn_printn(netdissect_options *ndo,
179892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          register const u_char *s, register u_int n, register const u_char *ep)
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_char c;
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (n > 0 && (ep == NULL || s < ep)) {
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		n--;
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		c = *s++;
18653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ND_ISASCII(c)) {
18753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			c = ND_TOASCII(c);
188892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "M-"));
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
19053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ND_ISPRINT(c)) {
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			c ^= 0x40;	/* DEL to ?, others to alpha */
192892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "^"));
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
194892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%c", c));
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (n == 0) ? 0 : 1;
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print out a null-padded filename (or other ascii string).
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * If ep is NULL, assume no truncation check is needed.
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Return true if truncated.
203e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Stop at ep (if given) or after n bytes or before the null char,
204e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * whichever is first.
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
207892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfn_printzp(netdissect_options *ndo,
208892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           register const u_char *s, register u_int n,
209892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           register const u_char *ep)
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register int ret;
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_char c;
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ret = 1;			/* assume truncated */
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (n > 0 && (ep == NULL || s < ep)) {
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		n--;
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		c = *s++;
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (c == '\0') {
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ret = 0;
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
22253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ND_ISASCII(c)) {
22353f17a9db278d33517d9888dd77848f554522a38JP Abgrall			c = ND_TOASCII(c);
224892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "M-"));
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
22653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (!ND_ISPRINT(c)) {
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			c ^= 0x40;	/* DEL to ?, others to alpha */
228892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "^"));
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
230892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "%c", c));
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (n == 0) ? 0 : ret;
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
23653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Format the timestamp
23753f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
238892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic char *
239892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughests_format(netdissect_options *ndo
240892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
241892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes_U_
242892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#endif
243e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes, int sec, int usec, char *buf)
24453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
245892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	const char *format;
246892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
247892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
248892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	switch (ndo->ndo_tstamp_precision) {
249892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
250892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	case PCAP_TSTAMP_PRECISION_MICRO:
251892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		format = "%02d:%02d:%02d.%06u";
252892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		break;
253892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
254892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	case PCAP_TSTAMP_PRECISION_NANO:
255892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		format = "%02d:%02d:%02d.%09u";
256892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		break;
257892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
258892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	default:
259e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		format = "%02d:%02d:%02d.{unknown}";
260892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		break;
261892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
262892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#else
263892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	format = "%02d:%02d:%02d.%06u";
264892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#endif
265892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
266e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	snprintf(buf, TS_BUF_SIZE, format,
267892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 sec / 3600, (sec % 3600) / 60, sec % 60, usec);
26853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
26953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return buf;
27053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
27153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
27253f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
273e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Format the timestamp - Unix timeval style
274e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes */
275e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesstatic char *
276e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughests_unix_format(netdissect_options *ndo
277e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION
278e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes_U_
279e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#endif
280e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes, int sec, int usec, char *buf)
281e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes{
282e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const char *format;
283e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
284e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
285e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	switch (ndo->ndo_tstamp_precision) {
286e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
287e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	case PCAP_TSTAMP_PRECISION_MICRO:
288e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		format = "%u.%06u";
289e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		break;
290e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
291e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	case PCAP_TSTAMP_PRECISION_NANO:
292e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		format = "%u.%09u";
293e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		break;
294e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
295e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	default:
296e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		format = "%u.{unknown}";
297e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		break;
298e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	}
299e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#else
300e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	format = "%u.%06u";
301e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#endif
302e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
303e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	snprintf(buf, TS_BUF_SIZE, format,
304e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		 (unsigned)sec, (unsigned)usec);
305e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
306e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	return buf;
307e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes}
308e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
309e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/*
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print the timestamp
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
313892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughests_print(netdissect_options *ndo,
314892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes         register const struct timeval *tvp)
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register int s;
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct tm *tm;
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	time_t Time;
319e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	char buf[TS_BUF_SIZE];
320e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	static struct timeval tv_ref;
321e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	struct timeval tv_result;
322e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	int negative_offset;
323e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	int nano_prec;
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
325892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	switch (ndo->ndo_tflag) {
3262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case 0: /* Default */
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		s = (tvp->tv_sec + thiszone) % 86400;
329e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec, buf)));
3302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case 1: /* No time stamp */
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case 2: /* Unix timeval style */
336e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "%s ", ts_unix_format(ndo,
337e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			  tvp->tv_sec, tvp->tv_usec, buf)));
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
340e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	case 3: /* Microseconds/nanoseconds since previous packet */
341e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        case 5: /* Microseconds/nanoseconds since first packet */
342e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
343e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		switch (ndo->ndo_tstamp_precision) {
344e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		case PCAP_TSTAMP_PRECISION_MICRO:
345e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			nano_prec = 0;
346e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			break;
347e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		case PCAP_TSTAMP_PRECISION_NANO:
348e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			nano_prec = 1;
349e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			break;
350e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		default:
351e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			nano_prec = 0;
352e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			break;
353e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		}
354e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#else
355e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		nano_prec = 0;
356e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#endif
357e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (!(netdissect_timevalisset(&tv_ref)))
358e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			tv_ref = *tvp; /* set timestamp for first packet */
35953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
360e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		negative_offset = netdissect_timevalcmp(tvp, &tv_ref, <);
361e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (negative_offset)
362e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			netdissect_timevalsub(&tv_ref, tvp, &tv_result, nano_prec);
363e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		else
364e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			netdissect_timevalsub(tvp, &tv_ref, &tv_result, nano_prec);
365892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
366e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, (negative_offset ? "-" : " ")));
36753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
368e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "%s ", ts_format(ndo,
369e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			  tv_result.tv_sec, tv_result.tv_usec, buf)));
37053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
371e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (ndo->ndo_tflag == 3)
372e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			tv_ref = *tvp; /* set timestamp for previous packet */
3732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
375e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	case 4: /* Default + Date */
3762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		s = (tvp->tv_sec + thiszone) % 86400;
3772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		Time = (tvp->tv_sec + thiszone) - s;
3782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		tm = gmtime (&Time);
3792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!tm)
380892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Date fail  "));
3812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else
382892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%04d-%02d-%02d %s ",
38353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
384e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                               ts_format(ndo, s, tvp->tv_usec, buf)));
3852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
390e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Print an unsigned relative number of seconds (e.g. hold time, prune timer)
3912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in the form 5m1s.  This does no truncation, so 32230861 seconds
3922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * is represented as 1y1w1d1h1m1s.
3932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
3942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
395e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesunsigned_relts_print(netdissect_options *ndo,
396e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                     uint32_t secs)
3972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static const char *lengths[] = {"y", "w", "d", "h", "m", "s"};
399e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	static const u_int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
4002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const char **l = lengths;
401e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const u_int *s = seconds;
4022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (secs == 0) {
404892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "0s"));
4052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
4062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
4072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (secs > 0) {
4082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (secs >= *s) {
409892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "%d%s", secs / *s, *l));
4102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			secs -= (secs / *s) * *s;
4112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		s++;
4132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		l++;
4142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
4152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
4162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
418e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * Print a signed relative number of seconds (e.g. hold time, prune timer)
419e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * in the form 5m1s.  This does no truncation, so 32230861 seconds
420e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * is represented as 1y1w1d1h1m1s.
421e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes */
422e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesvoid
423e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughessigned_relts_print(netdissect_options *ndo,
424e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                   int32_t secs)
425e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes{
426e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	if (secs < 0) {
427e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "-"));
428e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		if (secs == INT32_MIN) {
429e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			/*
430e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * -2^31; you can't fit its absolute value into
431e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * a 32-bit signed integer.
432e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 *
433e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * Just directly pass said absolute value to
434e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * unsigned_relts_print() directly.
435e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 *
436e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * (XXX - does ISO C guarantee that -(-2^n),
437e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * when calculated and cast to an n-bit unsigned
438e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * integer type, will have the value 2^n?)
439e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 */
440e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			unsigned_relts_print(ndo, 2147483648U);
441e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		} else {
442e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			/*
443e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * We now know -secs will fit into an int32_t;
444e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 * negate it and pass that to unsigned_relts_print().
445e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			 */
446e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes			unsigned_relts_print(ndo, -secs);
447e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		}
448e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		return;
449e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	}
450e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	unsigned_relts_print(ndo, secs);
451e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes}
452e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
453e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/*
4542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *  this is a generic routine for printing unknown data;
4552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *  we pass on the linefeed plus indentation string to
4562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *  get a proper output - returns 0 on error
4572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
4582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
460892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprint_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,int len)
4612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
4622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 0) {
463892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          ND_PRINT((ndo,"%sDissector error: print_unknown_data called with negative length",
464892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    ident));
4652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return(0);
4662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
467892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_snapend - cp < len)
468892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		len = ndo->ndo_snapend - cp;
4692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 0) {
470892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          ND_PRINT((ndo,"%sDissector error: print_unknown_data called with pointer past end of packet",
471892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    ident));
4722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return(0);
4732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
474892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        hex_print(ndo, ident,cp,len);
4752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return(1); /* everything is ok */
4762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
4772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
4792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Convert a token value to a string; use "fmt" if not found.
4802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
4812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectconst char *
4822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttok2strbuf(register const struct tok *lp, register const char *fmt,
483892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	   register u_int v, char *buf, size_t bufsize)
4842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
4852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (lp != NULL) {
4862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		while (lp->s != NULL) {
4872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (lp->v == v)
4882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				return (lp->s);
4892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			++lp;
4902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
4912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
4922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (fmt == NULL)
4932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		fmt = "#%d";
4942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(void)snprintf(buf, bufsize, fmt, v);
4962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (const char *)buf;
4972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
4982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
5002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Convert a token value to a string; use "fmt" if not found.
5012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
5022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectconst char *
5032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttok2str(register const struct tok *lp, register const char *fmt,
504892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	register u_int v)
5052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
506e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	static char buf[4][TOKBUFSIZE];
5072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static int idx = 0;
5082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	char *ret;
5092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ret = buf[idx];
5112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	idx = (idx+1) & 3;
5122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0]));
5132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
5162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Convert a bit token value to a string; use "fmt" if not found.
51753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * this is useful for parsing bitfields, the output strings are seperated
51853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * if the s field is positive.
5192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
52053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic char *
52153f17a9db278d33517d9888dd77848f554522a38JP Abgrallbittok2str_internal(register const struct tok *lp, register const char *fmt,
522892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	   register u_int v, const char *sep)
5232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
5242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        static char buf[256]; /* our stringbuffer */
5252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        int buflen=0;
526892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        register u_int rotbit; /* this is the bit we rotate through all bitpositions */
527892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        register u_int tokval;
528892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        const char * sepstr = "";
5292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
53053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (lp != NULL && lp->s != NULL) {
5312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            tokval=lp->v;   /* load our first value */
5322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            rotbit=1;
5332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            while (rotbit != 0) {
5342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /*
5352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 * lets AND the rotating bit with our token value
5362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 * and see if we have got a match
5372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 */
5382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (tokval == (v&rotbit)) {
5392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    /* ok we have found something */
54053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
541892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                     sepstr, lp->s);
542892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    sepstr = sep;
5432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    break;
5442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
5452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                rotbit=rotbit<<1; /* no match - lets shift and try again */
5462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            }
5472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            lp++;
5482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
5492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
550892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (buflen == 0)
5512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
552892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
553892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        return (buf);
5542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
55753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Convert a bit token value to a string; use "fmt" if not found.
55853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * this is useful for parsing bitfields, the output strings are not seperated.
55953f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
56053f17a9db278d33517d9888dd77848f554522a38JP Abgrallchar *
56153f17a9db278d33517d9888dd77848f554522a38JP Abgrallbittok2str_nosep(register const struct tok *lp, register const char *fmt,
562892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	   register u_int v)
56353f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
564892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    return (bittok2str_internal(lp, fmt, v, ""));
56553f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
56653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
56753f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
56853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Convert a bit token value to a string; use "fmt" if not found.
56953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * this is useful for parsing bitfields, the output strings are comma seperated.
57053f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
57153f17a9db278d33517d9888dd77848f554522a38JP Abgrallchar *
57253f17a9db278d33517d9888dd77848f554522a38JP Abgrallbittok2str(register const struct tok *lp, register const char *fmt,
573892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	   register u_int v)
57453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
575892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    return (bittok2str_internal(lp, fmt, v, ", "));
57653f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
57753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
57853f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
5792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Convert a value to a string using an array; the macro
580e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes * tok2strary() in <netdissect.h> is the public interface to
5812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this function and ensures that the second argument is
5822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * correct for bounds-checking.
5832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
5842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectconst char *
5852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttok2strary_internal(register const char **lp, int n, register const char *fmt,
5862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register int v)
5872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
588e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	static char buf[TOKBUFSIZE];
5892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (v >= 0 && v < n && lp[v] != NULL)
5912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return lp[v];
5922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (fmt == NULL)
5932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		fmt = "#%d";
5942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(void)snprintf(buf, sizeof(buf), fmt, v);
5952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (buf);
5962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
5992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Convert a 32-bit netmask to prefixlen if possible
6002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the function returns the prefix-len; if plen == -1
6012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * then conversion was not possible;
6022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
6032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint
605892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesmask2plen(uint32_t mask)
6062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
607892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint32_t bitmasks[33] = {
6082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0x00000000,
6092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
6102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
6112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
6122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
6132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
6142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
6152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
6162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
6172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	};
6182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int prefix_len = 32;
6192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* let's see if we can transform the mask into a prefixlen */
6212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (prefix_len >= 0) {
6222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (bitmasks[prefix_len] == mask)
6232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
6242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		prefix_len--;
6252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
6262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (prefix_len);
6272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
6282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
62953f17a9db278d33517d9888dd77848f554522a38JP Abgrallint
63053f17a9db278d33517d9888dd77848f554522a38JP Abgrallmask62plen(const u_char *mask)
63153f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
63253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	u_char bitmasks[9] = {
63353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		0x00,
63453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		0x80, 0xc0, 0xe0, 0xf0,
63553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		0xf8, 0xfc, 0xfe, 0xff
63653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	};
63753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int byte;
63853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	int cidr_len = 0;
63953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
64053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	for (byte = 0; byte < 16; byte++) {
64153f17a9db278d33517d9888dd77848f554522a38JP Abgrall		u_int bits;
64253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
64353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) {
64453f17a9db278d33517d9888dd77848f554522a38JP Abgrall			if (mask[byte] == bitmasks[bits]) {
64553f17a9db278d33517d9888dd77848f554522a38JP Abgrall				cidr_len += bits;
64653f17a9db278d33517d9888dd77848f554522a38JP Abgrall				break;
64753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			}
64853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
64953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
65053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (mask[byte] != 0xff)
65153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			break;
65253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
65353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return (cidr_len);
65453f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
65553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
656892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*
657892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Routine to print out information for text-based protocols such as FTP,
658892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * HTTP, SMTP, RTSP, SIP, ....
659892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes */
660892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define MAX_TOKEN	128
661892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
662892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*
663892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Fetch a token from a packet, starting at the specified index,
664892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * and return the length of the token.
665892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes *
666892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Returns 0 on error; yes, this is indistinguishable from an empty
667892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * token, but an "empty token" isn't a valid token - it just means
668892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * either a space character at the beginning of the line (this
669892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * includes a blank line) or no more tokens remaining on the line.
670892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes */
671892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int
672892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len,
673892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    u_char *tbuf, size_t tbuflen)
674892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
675892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	size_t toklen = 0;
676892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
677892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	for (; idx < len; idx++) {
678892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ND_TTEST(*(pptr + idx))) {
679892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* ran past end of captured data */
680892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			return (0);
681892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
682892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!isascii(*(pptr + idx))) {
683892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* not an ASCII character */
684892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			return (0);
685892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
686892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (isspace(*(pptr + idx))) {
687892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* end of token */
688892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			break;
689892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
690892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!isprint(*(pptr + idx))) {
691892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* not part of a command token or response code */
692892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			return (0);
693892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
694892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (toklen + 2 > tbuflen) {
695892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* no room for this character and terminating '\0' */
696892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			return (0);
697892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
698892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		tbuf[toklen] = *(pptr + idx);
699892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		toklen++;
700892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
701892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (toklen == 0) {
702892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		/* no token */
703892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return (0);
704892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
705892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	tbuf[toklen] = '\0';
706892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
707892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	/*
708892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	 * Skip past any white space after the token, until we see
709892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	 * an end-of-line (CR or LF).
710892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	 */
711892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	for (; idx < len; idx++) {
712892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ND_TTEST(*(pptr + idx))) {
713892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* ran past end of captured data */
714892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			break;
715892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
716892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (*(pptr + idx) == '\r' || *(pptr + idx) == '\n') {
717892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* end of line */
718892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			break;
719892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
720892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!isascii(*(pptr + idx)) || !isprint(*(pptr + idx))) {
721892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* not a printable ASCII character */
722892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			break;
723892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
724892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!isspace(*(pptr + idx))) {
725892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* beginning of next token */
726892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			break;
727892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
728892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
729892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	return (idx);
730892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes}
731892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
732892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*
733892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Scan a buffer looking for a line ending - LF or CR-LF.
734892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Return the index of the character after the line ending or 0 if
735892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * we encounter a non-ASCII or non-printable character or don't find
736892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * the line ending.
737892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes */
738892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic u_int
739892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprint_txt_line(netdissect_options *ndo, const char *protoname,
740892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    const char *prefix, const u_char *pptr, u_int idx, u_int len)
741892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
742892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int startidx;
743892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int linelen;
744892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
745892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	startidx = idx;
746892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	while (idx < len) {
747892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_TCHECK(*(pptr+idx));
748892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (*(pptr+idx) == '\n') {
749892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/*
750892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * LF without CR; end of line.
751892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * Skip the LF and print the line, with the
752892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * exception of the LF.
753892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 */
754892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			linelen = idx - startidx;
755892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			idx++;
756892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			goto print;
757892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		} else if (*(pptr+idx) == '\r') {
758892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* CR - any LF? */
759892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if ((idx+1) >= len) {
760892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				/* not in this packet */
761892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				return (0);
762892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			}
763892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_TCHECK(*(pptr+idx+1));
764892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (*(pptr+idx+1) == '\n') {
765892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				/*
766892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				 * CR-LF; end of line.
767892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				 * Skip the CR-LF and print the line, with
768892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				 * the exception of the CR-LF.
769892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				 */
770892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				linelen = idx - startidx;
771892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				idx += 2;
772892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				goto print;
773892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			}
774892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
775892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/*
776892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * CR followed by something else; treat this
777892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * as if it were binary data, and don't print
778892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * it.
779892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 */
780892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			return (0);
781892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		} else if (!isascii(*(pptr+idx)) ||
782892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    (!isprint(*(pptr+idx)) && *(pptr+idx) != '\t')) {
783892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/*
784892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * Not a printable ASCII character and not a tab;
785892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * treat this as if it were binary data, and
786892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * don't print it.
787892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 */
788892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			return (0);
789892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
790892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		idx++;
791892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
792892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
793892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	/*
794892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	 * All printable ASCII, but no line ending after that point
795892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	 * in the buffer; treat this as if it were truncated.
796892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	 */
797892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughestrunc:
798892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	linelen = idx - startidx;
799892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx,
800892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    protoname));
801892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	return (0);
802892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
803892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesprint:
804892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s%.*s", prefix, (int)linelen, pptr + startidx));
805892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	return (idx);
806892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes}
807892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
808892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesvoid
809892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughestxtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
810892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    const char *protoname, const char **cmds, u_int flags)
811892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
812892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int idx, eol;
813892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_char token[MAX_TOKEN+1];
814892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	const char *cmd;
815892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	int is_reqresp = 0;
816892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	const char *pnp;
817892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
818892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (cmds != NULL) {
819892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		/*
820892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * This protocol has more than just request and
821892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * response lines; see whether this looks like a
822892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * request or response.
823892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 */
824892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		idx = fetch_token(ndo, pptr, 0, len, token, sizeof(token));
825892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (idx != 0) {
826892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/* Is this a valid request name? */
827892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			while ((cmd = *cmds++) != NULL) {
828e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes				if (ascii_strcasecmp((const char *)token, cmd) == 0) {
829892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					/* Yes. */
830892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					is_reqresp = 1;
831892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					break;
832892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				}
833892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			}
834892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
835892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/*
836892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * No - is this a valid response code (3 digits)?
837892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 *
838892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * Is this token the response code, or is the next
839892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * token the response code?
840892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 */
841892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (flags & RESP_CODE_SECOND_TOKEN) {
842892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				/*
843892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				 * Next token - get it.
844892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				 */
845892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				idx = fetch_token(ndo, pptr, idx, len, token,
846892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				    sizeof(token));
847892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			}
848892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (idx != 0) {
849892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				if (isdigit(token[0]) && isdigit(token[1]) &&
850892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				    isdigit(token[2]) && token[3] == '\0') {
851892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					/* Yes. */
852892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes					is_reqresp = 1;
853892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				}
854892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			}
855892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
856892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	} else {
857892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		/*
858892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * This protocol has only request and response lines
859892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * (e.g., FTP, where all the data goes over a
860892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * different connection); assume the payload is
861892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * a request or response.
862892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 */
863892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		is_reqresp = 1;
864892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
865892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
866892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	/* Capitalize the protocol name */
867892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	for (pnp = protoname; *pnp != '\0'; pnp++)
868e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		ND_PRINT((ndo, "%c", toupper((u_char)*pnp)));
869892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
870892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (is_reqresp) {
871892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		/*
872892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * In non-verbose mode, just print the protocol, followed
873892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * by the first line as the request or response info.
874892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 *
875892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * In verbose mode, print lines as text until we run out
876892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * of characters or see something that's not a
877892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * printable-ASCII line.
878892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 */
879892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (ndo->ndo_vflag) {
880892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/*
881892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * We're going to print all the text lines in the
882892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * request or response; just print the length
883892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * on the first line of the output.
884892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 */
885892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, ", length: %u", len));
886892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			for (idx = 0;
887892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    idx < len && (eol = print_txt_line(ndo, protoname, "\n\t", pptr, idx, len)) != 0;
888892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			    idx = eol)
889892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				;
890892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		} else {
891892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			/*
892892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 * Just print the first text line.
893892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			 */
894892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			print_txt_line(ndo, protoname, ": ", pptr, 0, len);
895892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
896892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
897892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes}
898892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
8992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
900892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughessafeputs(netdissect_options *ndo,
901892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes         const u_char *s, const u_int maxlen)
9022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
903892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	u_int idx = 0;
90453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
9052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (*s && idx < maxlen) {
906892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		safeputchar(ndo, *s);
907892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		idx++;
9082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		s++;
9092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
9102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
9112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
913892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughessafeputchar(netdissect_options *ndo,
914892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            const u_char c)
9152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
916892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, (c < 0x80 && ND_ISPRINT(c)) ? "%c" : "\\0x%02x", c));
91753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
91853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
91953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef LBL_ALIGN
92053f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
92153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Some compilers try to optimize memcpy(), using the alignment constraint
92253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * on the argument pointer type.  by using this function, we try to avoid the
92353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * optimization.
92453f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
92553f17a9db278d33517d9888dd77848f554522a38JP Abgrallvoid
92653f17a9db278d33517d9888dd77848f554522a38JP Abgrallunaligned_memcpy(void *p, const void *q, size_t l)
92753f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
92853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	memcpy(p, q, l);
92953f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
93053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
93153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* As with memcpy(), so with memcmp(). */
93253f17a9db278d33517d9888dd77848f554522a38JP Abgrallint
93353f17a9db278d33517d9888dd77848f554522a38JP Abgrallunaligned_memcmp(const void *p, const void *q, size_t l)
93453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
93553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return (memcmp(p, q, l));
9362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
93753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
938e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
939