The status are defined in an enum in status-exit-codes.h.
Moreover:
Use ndo_error() instead of ndo_warning() for malloc() errors in print-esp.c.
signature.h \
slcompress.h \
smb.h \
+ status-exit-codes.h \
strtoaddr.h \
tcp.h \
timeval-operations.h \
/*
* hash tables for whatever-to-name translations
*
- * ndo_error() called on strdup(3) failure
+ * ndo_error() called on strdup(3) failure with S_ERR_ND_MEM_ALLOC status
*/
#define HASHNAMESIZE 4096
p->name = strdup(hp->h_name);
if (p->name == NULL)
- (*ndo->ndo_error)(ndo,
- "ipaddr_string: strdup(hp->h_name)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ipaddr_string: strdup(hp->h_name)");
if (ndo->ndo_Nflag) {
/* Remove domain qualifications */
dotp = strchr(p->name, '.');
}
p->name = strdup(intoa(addr));
if (p->name == NULL)
- (*ndo->ndo_error)(ndo, "ipaddr_string: strdup(intoa(addr))");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ipaddr_string: strdup(intoa(addr))");
return (p->name);
}
p->name = strdup(hp->h_name);
if (p->name == NULL)
- (*ndo->ndo_error)(ndo,
- "ip6addr_string: strdup(hp->h_name)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ip6addr_string: strdup(hp->h_name)");
if (ndo->ndo_Nflag) {
/* Remove domain qualifications */
dotp = strchr(p->name, '.');
cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf));
p->name = strdup(cp);
if (p->name == NULL)
- (*ndo->ndo_error)(ndo, "ip6addr_string: strdup(cp)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ip6addr_string: strdup(cp)");
return (p->name);
}
tp->e_addr2 = k;
tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
if (tp->e_nxt == NULL)
- (*ndo->ndo_error)(ndo, "lookup_emem: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "lookup_emem: calloc");
return tp;
}
tp->bs_bytes = (u_char *) calloc(1, nlen);
if (tp->bs_bytes == NULL)
- (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "lookup_bytestring: calloc");
memcpy(tp->bs_bytes, bs, nlen);
tp->bs_nbytes = nlen;
tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp));
if (tp->bs_nxt == NULL)
- (*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "lookup_bytestring: calloc");
return tp;
}
tp->e_addr2 = k;
tp->e_nsap = (u_char *)malloc(nsap_length + 1);
if (tp->e_nsap == NULL)
- (*ndo->ndo_error)(ndo, "lookup_nsap: malloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "lookup_nsap: malloc");
tp->e_nsap[0] = (u_char)nsap_length; /* guaranteed < ISONSAP_MAX_LENGTH */
memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length);
tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
if (tp->e_nxt == NULL)
- (*ndo->ndo_error)(ndo, "lookup_nsap: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "lookup_nsap: calloc");
return tp;
}
tp->p_proto = j;
tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
if (tp->p_nxt == NULL)
- (*ndo->ndo_error)(ndo, "lookup_protoid: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "lookup_protoid: calloc");
return tp;
}
if (ether_ntohost(buf2, (const struct ether_addr *)ep) == 0) {
tp->e_name = strdup(buf2);
if (tp->e_name == NULL)
- (*ndo->ndo_error)(ndo,
- "etheraddr_string: strdup(buf2)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "etheraddr_string: strdup(buf2)");
return (tp->e_name);
}
}
*cp = '\0';
tp->e_name = strdup(buf);
if (tp->e_name == NULL)
- (*ndo->ndo_error)(ndo, "etheraddr_string: strdup(buf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "etheraddr_string: strdup(buf)");
return (tp->e_name);
}
tp->bs_name = strdup(buf);
if (tp->bs_name == NULL)
- (*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "le64addr_string: strdup(buf)");
return (tp->bs_name);
}
tp->bs_name = cp = (char *)malloc(len*3);
if (tp->bs_name == NULL)
- (*ndo->ndo_error)(ndo, "linkaddr_string: malloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "linkaddr_string: malloc");
*cp++ = hex[*ep >> 4];
*cp++ = hex[*ep++ & 0xf];
for (i = len-1; i > 0 ; --i) {
*cp++ = '\0';
tp->name = strdup(buf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo, "etherproto_string: strdup(buf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "etherproto_string: strdup(buf)");
return (tp->name);
}
tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx"));
if (cp == NULL)
- (*ndo->ndo_error)(ndo, "isonsap_string: malloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "isonsap_string: malloc");
for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) {
*cp++ = hex[*nsap >> 4];
(void)nd_snprintf(buf, sizeof(buf), "%u", i);
tp->name = strdup(buf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo, "tcpport_string: strdup(buf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "tcpport_string: strdup(buf)");
return (tp->name);
}
(void)nd_snprintf(buf, sizeof(buf), "%u", i);
tp->name = strdup(buf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo, "udpport_string: strdup(buf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "udpport_string: strdup(buf)");
return (tp->name);
}
*cp++ = '\0';
tp->name = strdup(buf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo, "ipxsap_string: strdup(buf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ipxsap_string: strdup(buf)");
return (tp->name);
}
} else
table->name = strdup(sv->s_name);
if (table->name == NULL)
- (*ndo->ndo_error)(ndo, "init_servarray: strdup");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "init_servarray: strdup");
table->addr = port;
table->nxt = newhnamemem(ndo);
tp = lookup_protoid(ndo, protoid);
tp->p_name = strdup(eproto_db[i].s);
if (tp->p_name == NULL)
- (*ndo->ndo_error)(ndo,
- "init_protoidarray: strdup(eproto_db[i].s)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "init_protoidarray: strdup(eproto_db[i].s)");
}
/* Hardwire some SNAP proto ID names */
for (pl = protoidlist; pl->name != NULL; ++pl) {
tp = lookup_emem(ndo, ep->addr);
tp->e_name = strdup(ep->name);
if (tp->e_name == NULL)
- (*ndo->ndo_error)(ndo,
- "init_etherarray: strdup(ep->addr)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "init_etherarray: strdup(ep->addr)");
}
(void)fclose(fp);
}
if (ether_ntohost(name, (const struct ether_addr *)el->addr) == 0) {
tp->e_name = strdup(name);
if (tp->e_name == NULL)
- (*ndo->ndo_error)(ndo,
- "init_etherarray: strdup(name)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "init_etherarray: strdup(name)");
continue;
}
#endif
num = 64;
ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
if (ptr == NULL)
- (*ndo->ndo_error)(ndo, "newhnamemem: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "newhnamemem: calloc");
}
--num;
p = ptr++;
num = 64;
ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
if (ptr == NULL)
- (*ndo->ndo_error)(ndo, "newh6namemem: calloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "newh6namemem: calloc");
}
--num;
p = ptr++;
#include "os-proto.h"
#endif
#include <sys/types.h>
+#include "status-exit-codes.h"
/*
* Data types corresponding to multi-byte integral values within data
PRINTFLIKE_FUNCPTR(2, 3);
/* pointer to function to output errors */
void NORETURN_FUNCPTR (*ndo_error)(netdissect_options *,
+ status_exit_codes_t status,
const char *fmt, ...)
- PRINTFLIKE_FUNCPTR(2, 3);
+ PRINTFLIKE_FUNCPTR(3, 4);
/* pointer to function to output warnings */
void (*ndo_warning)(netdissect_options *,
const char *fmt, ...)
tp->nxt = newhnamemem(ndo);
tp->name = strdup(nambuf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo,
- "ataddr_string: strdup(nambuf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ataddr_string: strdup(nambuf)");
}
fclose(fp);
}
tp2->name, athost);
tp->name = strdup(nambuf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo,
- "ataddr_string: strdup(nambuf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ataddr_string: strdup(nambuf)");
return (tp->name);
}
(void)nd_snprintf(nambuf, sizeof(nambuf), "%u", atnet);
tp->name = strdup(nambuf);
if (tp->name == NULL)
- (*ndo->ndo_error)(ndo, "ataddr_string: strdup(nambuf)");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "ataddr_string: strdup(nambuf)");
return (tp->name);
}
/* malloc() return used by the 'dnaddrtable' hash table: do not free() */
str = (char *)malloc(siz = sizeof("00.0000"));
if (str == NULL)
- (*ndo->ndo_error)(ndo, "dnnum_string: malloc");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "dnnum_string: malloc");
nd_snprintf(str, siz, "%u.%u", area, node);
return(str);
}
output_buffer_size = len + (block_size - len % block_size);
output_buffer = (u_char *)malloc(output_buffer_size);
if (output_buffer == NULL) {
- (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "can't allocate memory for decryption buffer");
EVP_CIPHER_CTX_free(ctx);
return 0;
}
nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
if (nsa == NULL)
- (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "esp_print_addsa: malloc");
*nsa = *sa;
else if (hex >= 'a' && hex <= 'f')
return (hex - 'a' + 10);
else {
- (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
+ (*ndo->ndo_error)(ndo, S_ERR_ND_ESP_SECRET,
+ "invalid hex digit %c in espsecret\n", hex);
return 0;
}
}
secretfile = fopen(filename, FOPEN_READ_TXT);
if (secretfile == NULL) {
- (*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n",
- filename, strerror(errno));
+ (*ndo->ndo_error)(ndo, S_ERR_ND_OPEN_FILE,
+ "print_esp: can't open %s: %s\n",
+ filename, strerror(errno));
return;
}
output_buffer_size = len + (block_size - len % block_size);
output_buffer = (u_char *)malloc(output_buffer_size);
if (output_buffer == NULL) {
- (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+ "esp_print: malloc decryption buffer");
EVP_CIPHER_CTX_free(ctx);
return -1;
}
calloc(1, sizeof(*th));
if (th->nxt == NULL)
(*ndo->ndo_error)(ndo,
- "tcp_print: calloc");
+ S_ERR_ND_MEM_ALLOC,
+ "tcp_print: calloc");
}
th->addr = tha;
if (rev)
calloc(1, sizeof(*th));
if (th->nxt == NULL)
(*ndo->ndo_error)(ndo,
- "tcp_print: calloc");
+ S_ERR_ND_MEM_ALLOC,
+ "tcp_print: calloc");
}
th->addr = tha;
if (rev)
u_int length);
static void NORETURN ndo_error(netdissect_options *ndo,
+ status_exit_codes_t status,
FORMAT_STRING(const char *fmt), ...)
- PRINTFLIKE(2, 3);
+ PRINTFLIKE(3, 4);
static void ndo_warning(netdissect_options *ndo,
FORMAT_STRING(const char *fmt), ...)
PRINTFLIKE(2, 3);
if (printer == NULL) {
dltname = pcap_datalink_val_to_name(type);
if (dltname != NULL)
- (*ndo->ndo_error)(ndo,
+ (*ndo->ndo_error)(ndo, S_ERR_ND_NO_PRINTER,
"packet printing is not supported for link type %s: use -w",
dltname);
else
- (*ndo->ndo_error)(ndo,
+ (*ndo->ndo_error)(ndo, S_ERR_ND_NO_PRINTER,
"packet printing is not supported for link type %d: use -w", type);
}
return printer;
/* VARARGS */
static void
-ndo_error(netdissect_options *ndo, const char *fmt, ...)
+ndo_error(netdissect_options *ndo, status_exit_codes_t status,
+ const char *fmt, ...)
{
va_list ap;
(void)fputc('\n', stderr);
}
nd_cleanup();
- exit(1);
+ exit(status);
/* NOTREACHED */
}
va_end(args);
if (ret < 0)
- ndo_error(ndo, "Unable to write output: %s", pcap_strerror(errno));
+ ndo_error(ndo, S_ERR_ND_WRITE_FILE,
+ "Unable to write output: %s", pcap_strerror(errno));
return (ret);
}
--- /dev/null
+/*
+ * Copyright (c) 2018 The TCPDUMP project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef status_exit_codes_h
+#define status_exit_codes_h
+
+/* S_ERR_ND_* are libnetdissect status */
+
+typedef enum {
+ S_SUCCESS = 0, /* not a libnetdissect status */
+ S_ERR_HOST_PROGRAM = 1, /* not a libnetdissect status */
+ S_ERR_ND_NO_PRINTER = 2,
+ S_ERR_ND_MEM_ALLOC = 3,
+ S_ERR_ND_OPEN_FILE = 4,
+ S_ERR_ND_WRITE_FILE = 5,
+ S_ERR_ND_ESP_SECRET = 6
+} status_exit_codes_t;
+
+#endif /* status_exit_codes_h */
if (fmt[-1] != '\n')
(void)fputc('\n', stderr);
}
- exit_tcpdump(1);
+ exit_tcpdump(S_ERR_HOST_PROGRAM);
/* NOTREACHED */
}
if (n_tstamp_types == 0) {
fprintf(stderr, "Time stamp type cannot be set for %s\n",
device);
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
}
fprintf(stderr, "Time stamp types for %s (use option -j to set):\n",
device);
}
}
pcap_free_tstamp_types(tstamp_types);
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
}
#endif
#ifdef HAVE_PCAP_FREE_DATALINKS
pcap_free_datalinks(dlts);
#endif
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
}
#ifdef HAVE_PCAP_FINDALLDEVS
printf("\n");
}
pcap_freealldevs(devlist);
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
}
#endif /* HAVE_PCAP_FINDALLDEVS */
printf("\n");
}
pcap_freealldevs(devlist);
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
}
#endif /* HAVE_PCAP_FINDALLDEVS */
if (chroot_dir && !username) {
fprintf(stderr, "%s: Chroot without dropping root is insecure\n",
program_name);
- exit_tcpdump(1);
+ exit_tcpdump(S_ERR_HOST_PROGRAM);
}
pw = getpwnam(username);
if (chroot(chroot_dir) != 0 || chdir ("/") != 0) {
fprintf(stderr, "%s: Couldn't chroot/chdir to '%.64s': %s\n",
program_name, chroot_dir, pcap_strerror(errno));
- exit_tcpdump(1);
+ exit_tcpdump(S_ERR_HOST_PROGRAM);
}
}
#ifdef HAVE_LIBCAP_NG
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
- exit_tcpdump(1);
+ exit_tcpdump(S_ERR_HOST_PROGRAM);
}
else {
fprintf(stderr, "dropped privs to %s\n", username);
else {
fprintf(stderr, "%s: Couldn't find user '%.32s'\n",
program_name, username);
- exit_tcpdump(1);
+ exit_tcpdump(S_ERR_HOST_PROGRAM);
}
#ifdef HAVE_LIBCAP_NG
/* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT any more. */
case 'h':
print_usage();
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
break;
case 'H':
case OPTION_VERSION:
print_version();
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
break;
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
default:
print_usage();
- exit_tcpdump(1);
+ exit_tcpdump(S_ERR_HOST_PROGRAM);
/* NOTREACHED */
}
pcap_close(pd);
free(cmdbuf);
pcap_freecode(&fcode);
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
}
#ifdef HAVE_CASPER
(void)fflush(stdout);
info(1);
}
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
#endif
}
filename,
pcap_strerror(errno));
#ifdef HAVE_FORK
- exit(1);
+ exit(S_ERR_HOST_PROGRAM);
#else
- _exit(1);
+ _exit(S_ERR_HOST_PROGRAM);
#endif
}
#else /* HAVE_FORK && HAVE_VFORK */
(void)fprintf(stderr, "Maximum file limit reached: %d\n",
Wflag);
info(1);
- exit_tcpdump(0);
+ exit_tcpdump(S_SUCCESS);
/* NOTREACHED */
}
if (dump_info->CurrentFileName != NULL)