#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.96 2005-04-25 16:14:43 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.109 2007-01-29 09:59:42 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "interface.h"
+char * ts_format(register int, register int);
+
/*
- * Print out a filename (or other ascii string).
+ * Print out a null-terminated filename (or other ascii string).
* If ep is NULL, assume no truncation check is needed.
* Return true if truncated.
*/
return (n == 0) ? 0 : 1;
}
+/*
+ * Print out a null-padded filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_printzp(register const u_char *s, register u_int n,
+ register const u_char *ep)
+{
+ register int ret;
+ register u_char c;
+
+ ret = 1; /* assume truncated */
+ while (n > 0 && (ep == NULL || s < ep)) {
+ n--;
+ c = *s++;
+ if (c == '\0') {
+ ret = 0;
+ break;
+ }
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ return (n == 0) ? 0 : ret;
+}
+
+/*
+ * Format the timestamp
+ */
+char *
+ts_format(register int sec, register int usec)
+{
+ static char buf[sizeof("00:00:00.000000")];
+ (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u",
+ sec / 3600, (sec % 3600) / 60, sec % 60, usec);
+
+ return buf;
+}
+
/*
* Print the timestamp
*/
time_t Time;
static unsigned b_sec;
static unsigned b_usec;
+ int d_usec;
+ int d_sec;
switch (tflag) {
case 0: /* Default */
s = (tvp->tv_sec + thiszone) % 86400;
- (void)printf("%02d:%02d:%02d.%06u ",
- s / 3600, (s % 3600) / 60, s % 60,
- (unsigned)tvp->tv_usec);
+ (void)printf("%s ", ts_format(s, tvp->tv_usec));
break;
case 1: /* No time stamp */
break;
case 3: /* Microseconds since previous packet */
+ case 5: /* Microseconds since first packet */
if (b_sec == 0) {
- printf("000000 ");
- } else {
- int d_usec = tvp->tv_usec - b_usec;
- int d_sec = tvp->tv_sec - b_sec;
-
- while (d_usec < 0) {
- d_usec += 1000000;
- d_sec--;
- }
- if (d_sec)
- printf("%d. ", d_sec);
- printf("%06d ", d_usec);
- }
- b_sec = tvp->tv_sec;
- b_usec = tvp->tv_usec;
+ /* init timestamp for first packet */
+ b_usec = tvp->tv_usec;
+ b_sec = tvp->tv_sec;
+ }
+
+ d_usec = tvp->tv_usec - b_usec;
+ d_sec = tvp->tv_sec - b_sec;
+
+ while (d_usec < 0) {
+ d_usec += 1000000;
+ d_sec--;
+ }
+
+ (void)printf("%s ", ts_format(d_sec, d_usec));
+
+ if (tflag == 3) { /* set timestamp for last packet */
+ b_sec = tvp->tv_sec;
+ b_usec = tvp->tv_usec;
+ }
break;
case 4: /* Default + Date*/
if (!tm)
printf("Date fail ");
else
- printf("%04d-%02d-%02d ",
- tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
- printf("%02d:%02d:%02d.%06u ",
- s / 3600, (s % 3600) / 60, s % 60, (unsigned)tvp->tv_usec);
+ printf("%04d-%02d-%02d %s ",
+ tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+ ts_format(s, tvp->tv_usec));
break;
}
}
int
print_unknown_data(const u_char *cp,const char *ident,int len)
{
+ if (len < 0) {
+ printf("%sDissector error: print_unknown_data called with negative length",
+ ident);
+ return(0);
+ }
+ if (snapend - cp < len)
+ len = snapend - cp;
+ if (len < 0) {
+ printf("%sDissector error: print_unknown_data called with pointer past end of packet",
+ ident);
+ return(0);
+ }
hex_print(ident,cp,len);
return(1); /* everything is ok */
}
/*
* 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 seperated
+ * if the s field is positive.
*/
-char *
-bittok2str(register const struct tok *lp, register const char *fmt,
- register int v)
+static char *
+bittok2str_internal(register const struct tok *lp, register const char *fmt,
+ register int v, register int sep)
{
static char buf[256]; /* our stringbuffer */
int buflen=0;
register int rotbit; /* this is the bit we rotate through all bitpositions */
register int tokval;
- while (lp->s != NULL && lp != NULL) {
+ while (lp != NULL && lp->s != NULL) {
tokval=lp->v; /* load our first value */
rotbit=1;
while (rotbit != 0) {
*/
if (tokval == (v&rotbit)) {
/* ok we have found something */
- buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s, ",lp->s);
+ buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
+ lp->s, sep ? ", " : "");
break;
}
rotbit=rotbit<<1; /* no match - lets shift and try again */
lp++;
}
+ /* user didn't want string seperation - no need to cut off trailing seperators */
+ if (!sep) {
+ return (buf);
+ }
+
if (buflen != 0) { /* did we find anything */
/* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */
buf[buflen-2] = '\0';
}
}
+/*
+ * 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.
+ */
+char *
+bittok2str_nosep(register const struct tok *lp, register const char *fmt,
+ register int v)
+{
+ return (bittok2str_internal(lp, fmt, v, 0));
+}
+
+/*
+ * 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.
+ */
+char *
+bittok2str(register const struct tok *lp, register const char *fmt,
+ register int v)
+{
+ return (bittok2str_internal(lp, fmt, v, 1));
+}
+
/*
* Convert a value to a string using an array; the macro
* tok2strary() in <interface.h> is the public interface to
*/
int
-mask2plen (u_int32_t mask)
+mask2plen(u_int32_t mask)
{
u_int32_t bitmasks[33] = {
0x00000000,
return (prefix_len);
}
+#ifdef INET6
+int
+mask62plen(const u_char *mask)
+{
+ u_char bitmasks[9] = {
+ 0x00,
+ 0x80, 0xc0, 0xe0, 0xf0,
+ 0xf8, 0xfc, 0xfe, 0xff
+ };
+ int byte;
+ int cidr_len = 0;
+
+ for (byte = 0; byte < 16; byte++) {
+ u_int bits;
+
+ for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) {
+ if (mask[byte] == bitmasks[bits]) {
+ cidr_len += bits;
+ break;
+ }
+ }
+
+ if (mask[byte] != 0xff)
+ break;
+ }
+ return (cidr_len);
+}
+#endif /* INET6 */
+
/* VARARGS */
void
error(const char *fmt, ...)
}
void
-safeputs(const char *s)
+safeputs(const char *s, int maxlen)
{
- while (*s) {
+ int idx = 0;
+
+ while (*s && idx < maxlen) {
safeputchar(*s);
+ idx++;
s++;
}
}
if (ch < 0x80 && isprint(ch))
printf("%c", ch);
else
- printf("\\%03o", ch);
+ printf("\\0x%02x", ch);
}