summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-11-01 22:11:18 +0000
committerdim <dim@FreeBSD.org>2010-11-01 22:11:18 +0000
commit04d5797c20a5e7f5811ee5653a8bd4fa9300325d (patch)
tree45cdf1680ec076c4c54b758b1c55a767bb75694b /usr.sbin
parent2b41f57ec24828271cbc72256afbf6947f14fac0 (diff)
parent71407681fdd1b75689f0d0a1e99666c0b45dfc6a (diff)
downloadFreeBSD-src-04d5797c20a5e7f5811ee5653a8bd4fa9300325d.zip
FreeBSD-src-04d5797c20a5e7f5811ee5653a8bd4fa9300325d.tar.gz
Sync: merge r214353 through r214648 from ^/head.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c332
-rw-r--r--usr.sbin/config/main.c27
-rw-r--r--usr.sbin/mfiutil/mfi_config.c91
-rw-r--r--usr.sbin/mfiutil/mfi_drive.c56
-rw-r--r--usr.sbin/mfiutil/mfi_evt.c32
-rw-r--r--usr.sbin/mfiutil/mfi_flash.c23
-rw-r--r--usr.sbin/mfiutil/mfi_patrol.c52
-rw-r--r--usr.sbin/mfiutil/mfi_show.c60
-rw-r--r--usr.sbin/mfiutil/mfi_volume.c40
-rwxr-xr-xusr.sbin/pc-sysinstall/backend-query/disk-info.sh2
-rw-r--r--usr.sbin/rtadvd/rtadvd.conf.54
-rw-r--r--usr.sbin/tcpdump/tcpdump/Makefile8
-rw-r--r--usr.sbin/tcpdump/tcpdump/config.h93
-rw-r--r--usr.sbin/tcpdump/tcpdump/tcpdump.11722
14 files changed, 2122 insertions, 420 deletions
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c
index 33f7b2d..e75b55e 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c
@@ -56,19 +56,15 @@
struct processor_entry {
int32_t index;
const struct asn_oid *frwId;
- int32_t load;
+ int32_t load; /* average cpu usage */
+ int32_t sample_cnt; /* number of usage samples */
+ int32_t cur_sample_idx; /* current valid sample */
TAILQ_ENTRY(processor_entry) link;
u_char cpu_no; /* which cpu, counted from 0 */
- pid_t idle_pid; /* PID of idle process for this CPU */
/* the samples from the last minute, as required by MIB */
double samples[MAX_CPU_SAMPLES];
-
- /* current sample to fill in next time, must be < MAX_CPU_SAMPLES */
- uint32_t cur_sample_idx;
-
- /* number of useful samples */
- uint32_t sample_cnt;
+ long states[MAX_CPU_SAMPLES][CPUSTATES];
};
TAILQ_HEAD(processor_tbl, processor_entry);
@@ -82,65 +78,78 @@ static int32_t detected_processor_count;
/* sysctlbyname(hw.ncpu) */
static int hw_ncpu;
-/* sysctlbyname(kern.{ccpu,fscale}) */
-static fixpt_t ccpu;
-static int fscale;
-
-/* tick of PDU where we have refreshed the processor table last */
-static uint64_t proctbl_tick;
+/* sysctlbyname(kern.cp_times) */
+static int cpmib[2];
+static size_t cplen;
/* periodic timer used to get cpu load stats */
static void *cpus_load_timer;
-/*
- * Average the samples. The entire algorithm seems to be wrong XXX.
+/**
+ * Returns the CPU usage of a given processor entry.
+ *
+ * It needs at least two cp_times "tick" samples to calculate a delta and
+ * thus, the usage over the sampling period.
*/
static int
get_avg_load(struct processor_entry *e)
{
- u_int i;
- double sum = 0.0;
+ u_int i, oldest;
+ long delta = 0;
+ double usage = 0.0;
assert(e != NULL);
- if (e->sample_cnt == 0)
+ /* Need two samples to perform delta calculation. */
+ if (e->sample_cnt <= 1)
return (0);
- for (i = 0; i < e->sample_cnt; i++)
- sum += e->samples[i];
-
- return ((int)floor((double)sum/(double)e->sample_cnt));
-}
+ /* Oldest usable index, we wrap around. */
+ if (e->sample_cnt == MAX_CPU_SAMPLES)
+ oldest = (e->cur_sample_idx + 1) % MAX_CPU_SAMPLES;
+ else
+ oldest = 0;
-/*
- * Stolen from /usr/src/bin/ps/print.c. The idle process should never
- * be swapped out :-)
- */
-static double
-processor_getpcpu(struct kinfo_proc *ki_p)
-{
-
- if (ccpu == 0 || fscale == 0)
- return (0.0);
-
-#define fxtofl(fixpt) ((double)(fixpt) / fscale)
- return (100.0 * fxtofl(ki_p->ki_pctcpu) /
- (1.0 - exp(ki_p->ki_swtime * log(fxtofl(ccpu)))));
+ /* Sum delta for all states. */
+ for (i = 0; i < CPUSTATES; i++) {
+ delta += e->states[e->cur_sample_idx][i];
+ delta -= e->states[oldest][i];
+ }
+ if (delta == 0)
+ return 0;
+
+ /* Take idle time from the last element and convert to
+ * percent usage by contrasting with total ticks delta. */
+ usage = (double)(e->states[e->cur_sample_idx][CPUSTATES-1] -
+ e->states[oldest][CPUSTATES-1]) / delta;
+ usage = 100 - (usage * 100);
+ HRDBG("CPU no. %d, delta ticks %ld, pct usage %.2f", e->cpu_no,
+ delta, usage);
+
+ return ((int)(usage));
}
/**
- * Save a new sample
+ * Save a new sample to proc entry and get the average usage.
+ *
+ * Samples are stored in a ringbuffer from 0..(MAX_CPU_SAMPLES-1)
*/
static void
-save_sample(struct processor_entry *e, struct kinfo_proc *kp)
+save_sample(struct processor_entry *e, long *cp_times)
{
+ int i;
- e->samples[e->cur_sample_idx] = 100.0 - processor_getpcpu(kp);
- e->load = get_avg_load(e);
e->cur_sample_idx = (e->cur_sample_idx + 1) % MAX_CPU_SAMPLES;
+ for (i = 0; cp_times != NULL && i < CPUSTATES; i++)
+ e->states[e->cur_sample_idx][i] = cp_times[i];
- if (++e->sample_cnt > MAX_CPU_SAMPLES)
+ e->sample_cnt++;
+ if (e->sample_cnt > MAX_CPU_SAMPLES)
e->sample_cnt = MAX_CPU_SAMPLES;
+
+ HRDBG("sample count for CPU no. %d went to %d", e->cpu_no, e->sample_cnt);
+ e->load = get_avg_load(e);
+
}
/**
@@ -178,8 +187,9 @@ proc_create_entry(u_int cpu_no, struct device_map_entry *map)
entry->index = map->hrIndex;
entry->load = 0;
+ entry->sample_cnt = 0;
+ entry->cur_sample_idx = -1;
entry->cpu_no = (u_char)cpu_no;
- entry->idle_pid = 0;
entry->frwId = &oid_zeroDotZero; /* unknown id FIXME */
INSERT_OBJECT_INT(entry, &processor_tbl);
@@ -191,64 +201,11 @@ proc_create_entry(u_int cpu_no, struct device_map_entry *map)
}
/**
- * Get the PIDs for the idle processes of the CPUs.
- */
-static void
-processor_get_pids(void)
-{
- struct kinfo_proc *plist, *kp;
- int i;
- int nproc;
- int cpu;
- int nchars;
- struct processor_entry *entry;
-
- plist = kvm_getprocs(hr_kd, KERN_PROC_ALL, 0, &nproc);
- if (plist == NULL || nproc < 0) {
- syslog(LOG_ERR, "hrProcessor: kvm_getprocs() failed: %m");
- return;
- }
-
- for (i = 0, kp = plist; i < nproc; i++, kp++) {
- if (!IS_KERNPROC(kp))
- continue;
-
- if (strcmp(kp->ki_comm, "idle") == 0) {
- /* single processor system */
- cpu = 0;
- } else if (sscanf(kp->ki_comm, "idle: cpu%d%n", &cpu, &nchars)
- == 1 && (u_int)nchars == strlen(kp->ki_comm)) {
- /* MP system */
- } else
- /* not an idle process */
- continue;
-
- HRDBG("'%s' proc with pid %d is on CPU #%d (last on #%d)",
- kp->ki_comm, kp->ki_pid, kp->ki_oncpu, kp->ki_lastcpu);
-
- TAILQ_FOREACH(entry, &processor_tbl, link)
- if (entry->cpu_no == kp->ki_lastcpu)
- break;
-
- if (entry == NULL) {
- /* create entry on non-ACPI systems */
- if ((entry = proc_create_entry(cpu, NULL)) == NULL)
- continue;
-
- detected_processor_count++;
- }
-
- entry->idle_pid = kp->ki_pid;
- HRDBG("CPU no. %d with SNMP index=%d has idle PID %d",
- entry->cpu_no, entry->index, entry->idle_pid);
-
- save_sample(entry, kp);
- }
-}
-
-/**
* Scan the device map table for CPUs and create an entry into the
- * processor table for each CPU. Then fetch the idle PIDs for all CPUs.
+ * processor table for each CPU.
+ *
+ * Make sure that the number of processors announced by the kernel hw.ncpu
+ * is equal to the number of processors we have found in the device table.
*/
static void
create_proc_table(void)
@@ -256,6 +213,7 @@ create_proc_table(void)
struct device_map_entry *map;
struct processor_entry *entry;
int cpu_no;
+ size_t len;
detected_processor_count = 0;
@@ -265,7 +223,7 @@ create_proc_table(void)
* If not, no entries will be present in the hrProcessor Table.
*
* For non-ACPI system the processors are not in the device table,
- * therefor insert them when getting the idle pids. XXX
+ * therefore insert them after checking hw.ncpu.
*/
STAILQ_FOREACH(map, &device_map, link)
if (strncmp(map->name_key, "cpu", strlen("cpu")) == 0 &&
@@ -283,9 +241,34 @@ create_proc_table(void)
detected_processor_count++;
}
- HRDBG("%d CPUs detected", detected_processor_count);
+ len = sizeof(hw_ncpu);
+ if (sysctlbyname("hw.ncpu", &hw_ncpu, &len, NULL, 0) == -1 ||
+ len != sizeof(hw_ncpu)) {
+ syslog(LOG_ERR, "hrProcessorTable: sysctl(hw.ncpu) failed");
+ hw_ncpu = 0;
+ }
+
+ HRDBG("%d CPUs detected via device table; hw.ncpu is %d",
+ detected_processor_count, hw_ncpu);
+
+ /* XXX Can happen on non-ACPI systems? Create entries by hand. */
+ for (; detected_processor_count < hw_ncpu; detected_processor_count++)
+ proc_create_entry(detected_processor_count, NULL);
+
+ len = 2;
+ if (sysctlnametomib("kern.cp_times", cpmib, &len)) {
+ syslog(LOG_ERR, "hrProcessorTable: sysctlnametomib(kern.cp_times) failed");
+ cpmib[0] = 0;
+ cpmib[1] = 0;
+ cplen = 0;
+ } else if (sysctl(cpmib, 2, NULL, &len, NULL, 0)) {
+ syslog(LOG_ERR, "hrProcessorTable: sysctl(kern.cp_times) length query failed");
+ cplen = 0;
+ } else {
+ cplen = len / sizeof(long);
+ }
+ HRDBG("%zu entries for kern.cp_times", cplen);
- processor_get_pids();
}
/**
@@ -307,78 +290,6 @@ free_proc_table(void)
}
/**
- * Init the things for hrProcessorTable.
- * Scan the device table for processor entries.
- */
-void
-init_processor_tbl(void)
-{
- size_t len;
-
- /* get various parameters from the kernel */
- len = sizeof(ccpu);
- if (sysctlbyname("kern.ccpu", &ccpu, &len, NULL, 0) == -1) {
- syslog(LOG_ERR, "hrProcessorTable: sysctl(kern.ccpu) failed");
- ccpu = 0;
- }
-
- len = sizeof(fscale);
- if (sysctlbyname("kern.fscale", &fscale, &len, NULL, 0) == -1) {
- syslog(LOG_ERR, "hrProcessorTable: sysctl(kern.fscale) failed");
- fscale = 0;
- }
-
- /* create the initial processor table */
- create_proc_table();
-}
-
-/**
- * Finalization routine for hrProcessorTable.
- * It destroys the lists and frees any allocated heap memory.
- */
-void
-fini_processor_tbl(void)
-{
-
- if (cpus_load_timer != NULL) {
- timer_stop(cpus_load_timer);
- cpus_load_timer = NULL;
- }
-
- free_proc_table();
-}
-
-/**
- * Make sure that the number of processors announced by the kernel hw.ncpu
- * is equal to the number of processors we have found in the device table.
- * If they differ rescan the device table.
- */
-static void
-processor_refill_tbl(void)
-{
-
- HRDBG("hw_ncpu=%d detected_processor_count=%d", hw_ncpu,
- detected_processor_count);
-
- if (hw_ncpu <= 0) {
- size_t size = sizeof(hw_ncpu);
-
- if (sysctlbyname("hw.ncpu", &hw_ncpu, &size, NULL, 0) == -1 ||
- size != sizeof(hw_ncpu)) {
- syslog(LOG_ERR, "hrProcessorTable: "
- "sysctl(hw.ncpu) failed: %m");
- hw_ncpu = 0;
- return;
- }
- }
-
- if (hw_ncpu != detected_processor_count) {
- free_proc_table();
- create_proc_table();
- }
-}
-
-/**
* Refresh all values in the processor table. We call this once for
* every PDU that accesses the table.
*/
@@ -386,37 +297,23 @@ static void
refresh_processor_tbl(void)
{
struct processor_entry *entry;
- int need_pids;
- struct kinfo_proc *plist;
- int nproc;
+ size_t size;
- processor_refill_tbl();
+ long pcpu_cp_times[cplen];
+ memset(pcpu_cp_times, 0, sizeof(pcpu_cp_times));
- need_pids = 0;
- TAILQ_FOREACH(entry, &processor_tbl, link) {
- if (entry->idle_pid <= 0) {
- need_pids = 1;
- continue;
- }
+ size = cplen * sizeof(long);
+ if (sysctl(cpmib, 2, pcpu_cp_times, &size, NULL, 0) == -1 &&
+ !(errno == ENOMEM && size >= cplen * sizeof(long))) {
+ syslog(LOG_ERR, "hrProcessorTable: sysctl(kern.cp_times) failed");
+ return;
+ }
+ TAILQ_FOREACH(entry, &processor_tbl, link) {
assert(hr_kd != NULL);
-
- plist = kvm_getprocs(hr_kd, KERN_PROC_PID,
- entry->idle_pid, &nproc);
- if (plist == NULL || nproc != 1) {
- syslog(LOG_ERR, "%s: missing item with "
- "PID = %d for CPU #%d\n ", __func__,
- entry->idle_pid, entry->cpu_no);
- need_pids = 1;
- continue;
- }
- save_sample(entry, plist);
+ save_sample(entry, &pcpu_cp_times[entry->cpu_no * CPUSTATES]);
}
- if (need_pids == 1)
- processor_get_pids();
-
- proctbl_tick = this_tick;
}
/**
@@ -451,6 +348,36 @@ start_processor_tbl(struct lmodule *mod)
}
/**
+ * Init the things for hrProcessorTable.
+ * Scan the device table for processor entries.
+ */
+void
+init_processor_tbl(void)
+{
+
+ /* create the initial processor table */
+ create_proc_table();
+ /* and get first samples */
+ refresh_processor_tbl();
+}
+
+/**
+ * Finalization routine for hrProcessorTable.
+ * It destroys the lists and frees any allocated heap memory.
+ */
+void
+fini_processor_tbl(void)
+{
+
+ if (cpus_load_timer != NULL) {
+ timer_stop(cpus_load_timer);
+ cpus_load_timer = NULL;
+ }
+
+ free_proc_table();
+}
+
+/**
* Access routine for the processor table.
*/
int
@@ -460,9 +387,6 @@ op_hrProcessorTable(struct snmp_context *ctx __unused,
{
struct processor_entry *entry;
- if (this_tick != proctbl_tick)
- refresh_processor_tbl();
-
switch (curr_op) {
case SNMP_OP_GETNEXT:
diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c
index b59bba4..b1d4b5d 100644
--- a/usr.sbin/config/main.c
+++ b/usr.sbin/config/main.c
@@ -108,7 +108,6 @@ main(int argc, char **argv)
struct stat buf;
int ch, len;
char *p;
- char xxx[MAXPATHLEN];
char *kernfile;
int printmachine;
@@ -218,32 +217,6 @@ main(int argc, char **argv)
} else if (!S_ISDIR(buf.st_mode))
errx(EXIT_FAILURE, "%s isn't a directory", p);
- /*
- * make symbolic links in compilation directory
- * for "sys" (to make genassym.c work along with #include <sys/xxx>)
- * and similarly for "machine".
- */
- if (*srcdir == '\0')
- (void)snprintf(xxx, sizeof(xxx), "../../include");
- else
- (void)snprintf(xxx, sizeof(xxx), "%s/%s/include",
- srcdir, machinename);
- (void) unlink(path("machine"));
- (void) symlink(xxx, path("machine"));
- if (strcmp(machinename, machinearch) != 0) {
- /*
- * make symbolic links in compilation directory for
- * machinearch, if it is different than machinename.
- */
- if (*srcdir == '\0')
- (void)snprintf(xxx, sizeof(xxx), "../../../%s/include",
- machinearch);
- else
- (void)snprintf(xxx, sizeof(xxx), "%s/%s/include",
- srcdir, machinearch);
- (void) unlink(path(machinearch));
- (void) symlink(xxx, path(machinearch));
- }
configfile(); /* put config file into kernel*/
options(); /* make options .h files */
makefile(); /* build Makefile */
diff --git a/usr.sbin/mfiutil/mfi_config.c b/usr.sbin/mfiutil/mfi_config.c
index 2837694..fc03aa7 100644
--- a/usr.sbin/mfiutil/mfi_config.c
+++ b/usr.sbin/mfiutil/mfi_config.c
@@ -29,12 +29,12 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#ifdef DEBUG
#include <sys/sysctl.h>
#endif
-#include <sys/errno.h>
#include <err.h>
+#include <errno.h>
#include <libutil.h>
#ifdef DEBUG
#include <stdint.h>
@@ -52,8 +52,6 @@ static void dump_config(int fd, struct mfi_config_data *config);
static int add_spare(int ac, char **av);
static int remove_spare(int ac, char **av);
-#define powerof2(x) ((((x)-1)&(x))==0)
-
static long
dehumanize(const char *value)
{
@@ -151,13 +149,14 @@ static int
clear_config(int ac, char **av)
{
struct mfi_ld_list list;
- int ch, fd;
+ int ch, error, fd;
u_int i;
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (!mfi_reconfig_supported()) {
@@ -167,8 +166,9 @@ clear_config(int ac, char **av)
}
if (mfi_ld_get_list(fd, &list, NULL) < 0) {
+ error = errno;
warn("Failed to get volume list");
- return (errno);
+ return (error);
}
for (i = 0; i < list.ld_count; i++) {
@@ -189,8 +189,9 @@ clear_config(int ac, char **av)
}
if (mfi_dcmd_command(fd, MFI_DCMD_CFG_CLEAR, NULL, 0, NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to clear configuration");
- return (errno);
+ return (error);
}
printf("mfi%d: Configuration cleared\n", mfi_unit);
@@ -335,8 +336,9 @@ parse_array(int fd, int raid_type, char *array_str, struct array_info *info)
return (error);
if (mfi_pd_get_info(fd, device_id, pinfo, NULL) < 0) {
+ error = errno;
warn("Failed to fetch drive info for drive %s", cp);
- return (errno);
+ return (error);
}
if (pinfo->fw_state != MFI_PD_STATE_UNCONFIGURED_GOOD) {
@@ -548,8 +550,9 @@ create_volume(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (!mfi_reconfig_supported()) {
@@ -660,8 +663,9 @@ create_volume(int ac, char **av)
* array and volume identifiers.
*/
if (mfi_config_read(fd, &config) < 0) {
+ error = errno;
warn("Failed to read configuration");
- return (errno);
+ return (error);
}
p = (char *)config->array;
state.array_ref = 0xffff;
@@ -745,14 +749,14 @@ create_volume(int ac, char **av)
#ifdef DEBUG
if (dump)
dump_config(fd, config);
- else
#endif
/* Send the new config to the controller. */
if (mfi_dcmd_command(fd, MFI_DCMD_CFG_ADD, config, config_size,
NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to add volume");
- return (errno);
+ return (error);
}
/* Clean up. */
@@ -774,7 +778,7 @@ static int
delete_volume(int ac, char **av)
{
struct mfi_ld_info info;
- int fd;
+ int error, fd;
uint8_t target_id, mbox[4];
/*
@@ -799,8 +803,9 @@ delete_volume(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (!mfi_reconfig_supported()) {
@@ -810,13 +815,15 @@ delete_volume(int ac, char **av)
}
if (mfi_lookup_volume(fd, av[1], &target_id) < 0) {
+ error = errno;
warn("Invalid volume %s", av[1]);
- return (errno);
+ return (error);
}
if (mfi_ld_get_info(fd, target_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to get info for volume %d", target_id);
- return (errno);
+ return (error);
}
if (mfi_volume_busy(fd, target_id)) {
@@ -828,8 +835,9 @@ delete_volume(int ac, char **av)
mbox_store_ldref(mbox, &info.ld_config.properties.ld);
if (mfi_dcmd_command(fd, MFI_DCMD_LD_DELETE, NULL, 0, mbox,
sizeof(mbox), NULL) < 0) {
+ error = errno;
warn("Failed to delete volume");
- return (errno);
+ return (error);
}
close(fd);
@@ -858,8 +866,9 @@ add_spare(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -867,8 +876,9 @@ add_spare(int ac, char **av)
return (error);
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch drive info");
- return (errno);
+ return (error);
}
if (info.fw_state != MFI_PD_STATE_UNCONFIGURED_GOOD) {
@@ -878,14 +888,16 @@ add_spare(int ac, char **av)
if (ac > 2) {
if (mfi_lookup_volume(fd, av[2], &target_id) < 0) {
+ error = errno;
warn("Invalid volume %s", av[2]);
- return (errno);
+ return (error);
}
}
if (mfi_config_read(fd, &config) < 0) {
+ error = errno;
warn("Failed to read configuration");
- return (errno);
+ return (error);
}
spare = malloc(sizeof(struct mfi_spare) + sizeof(uint16_t) *
@@ -939,8 +951,9 @@ add_spare(int ac, char **av)
if (mfi_dcmd_command(fd, MFI_DCMD_CFG_MAKE_SPARE, spare,
sizeof(struct mfi_spare) + sizeof(uint16_t) * spare->array_count,
NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to assign spare");
- return (errno);
+ return (error);
}
close(fd);
@@ -964,8 +977,9 @@ remove_spare(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -974,8 +988,9 @@ remove_spare(int ac, char **av)
/* Get the info for this drive. */
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u", device_id);
- return (errno);
+ return (error);
}
if (info.fw_state != MFI_PD_STATE_HOT_SPARE) {
@@ -986,8 +1001,9 @@ remove_spare(int ac, char **av)
mbox_store_pdref(mbox, &info.ref);
if (mfi_dcmd_command(fd, MFI_DCMD_CFG_REMOVE_SPARE, NULL, 0, mbox,
sizeof(mbox), NULL) < 0) {
+ error = errno;
warn("Failed to delete spare");
- return (errno);
+ return (error);
}
close(fd);
@@ -1093,7 +1109,7 @@ static int
debug_config(int ac, char **av)
{
struct mfi_config_data *config;
- int fd;
+ int error, fd;
if (ac != 1) {
warnx("debug: extra arguments");
@@ -1102,14 +1118,16 @@ debug_config(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
/* Get the config from the controller. */
if (mfi_config_read(fd, &config) < 0) {
+ error = errno;
warn("Failed to get config");
- return (errno);
+ return (error);
}
/* Dump out the configuration. */
@@ -1127,7 +1145,7 @@ dump(int ac, char **av)
struct mfi_config_data *config;
char buf[64];
size_t len;
- int fd;
+ int error, fd;
if (ac != 1) {
warnx("dump: extra arguments");
@@ -1136,23 +1154,26 @@ dump(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
/* Get the stashed copy of the last dcmd from the driver. */
snprintf(buf, sizeof(buf), "dev.mfi.%d.debug_command", mfi_unit);
if (sysctlbyname(buf, NULL, &len, NULL, 0) < 0) {
+ error = errno;
warn("Failed to read debug command");
- if (errno == ENOENT)
- errno = EOPNOTSUPP;
- return (errno);
+ if (error == ENOENT)
+ error = EOPNOTSUPP;
+ return (error);
}
config = malloc(len);
if (sysctlbyname(buf, config, &len, NULL, 0) < 0) {
+ error = errno;
warn("Failed to read debug command");
- return (errno);
+ return (error);
}
dump_config(fd, config);
free(config);
diff --git a/usr.sbin/mfiutil/mfi_drive.c b/usr.sbin/mfiutil/mfi_drive.c
index 5a57c09..75c4a53 100644
--- a/usr.sbin/mfiutil/mfi_drive.c
+++ b/usr.sbin/mfiutil/mfi_drive.c
@@ -79,10 +79,11 @@ int
mfi_lookup_drive(int fd, char *drive, uint16_t *device_id)
{
struct mfi_pd_list *list;
- uint8_t encl, slot;
long val;
+ int error;
u_int i;
char *cp;
+ uint8_t encl, slot;
/* Look for a raw device id first. */
val = strtol(drive, &cp, 0);
@@ -118,8 +119,9 @@ mfi_lookup_drive(int fd, char *drive, uint16_t *device_id)
slot = val;
if (mfi_pd_get_list(fd, &list, NULL) < 0) {
+ error = errno;
warn("Failed to fetch drive list");
- return (errno);
+ return (error);
}
for (i = 0; i < list->count; i++) {
@@ -302,8 +304,9 @@ drive_set_state(char *drive, uint16_t new_state)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, drive, &device_id);
@@ -312,8 +315,9 @@ drive_set_state(char *drive, uint16_t new_state)
/* Get the info for this drive. */
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u", device_id);
- return (errno);
+ return (error);
}
/* Try to change the state. */
@@ -327,9 +331,10 @@ drive_set_state(char *drive, uint16_t new_state)
mbox[5] = new_state >> 8;
if (mfi_dcmd_command(fd, MFI_DCMD_PD_STATE_SET, NULL, 0, mbox, 6,
NULL) < 0) {
+ error = errno;
warn("Failed to set drive %u to %s", device_id,
mfi_pdstate(new_state));
- return (errno);
+ return (error);
}
close(fd);
@@ -395,8 +400,9 @@ start_rebuild(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -405,13 +411,14 @@ start_rebuild(int ac, char **av)
/* Get the info for this drive. */
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u", device_id);
- return (errno);
+ return (error);
}
/* Check the state, must be REBUILD. */
if (info.fw_state != MFI_PD_STATE_REBUILD) {
- warn("Drive %d is not in the REBUILD state", device_id);
+ warnx("Drive %d is not in the REBUILD state", device_id);
return (EINVAL);
}
@@ -419,8 +426,9 @@ start_rebuild(int ac, char **av)
mbox_store_pdref(&mbox[0], &info.ref);
if (mfi_dcmd_command(fd, MFI_DCMD_PD_REBUILD_START, NULL, 0, mbox, 4,
NULL) < 0) {
+ error = errno;
warn("Failed to start rebuild on drive %u", device_id);
- return (errno);
+ return (error);
}
close(fd);
@@ -444,8 +452,9 @@ abort_rebuild(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -454,8 +463,9 @@ abort_rebuild(int ac, char **av)
/* Get the info for this drive. */
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u", device_id);
- return (errno);
+ return (error);
}
/* Check the state, must be REBUILD. */
@@ -468,8 +478,9 @@ abort_rebuild(int ac, char **av)
mbox_store_pdref(&mbox[0], &info.ref);
if (mfi_dcmd_command(fd, MFI_DCMD_PD_REBUILD_ABORT, NULL, 0, mbox, 4,
NULL) < 0) {
+ error = errno;
warn("Failed to abort rebuild on drive %u", device_id);
- return (errno);
+ return (error);
}
close(fd);
@@ -492,8 +503,9 @@ drive_progress(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -502,8 +514,9 @@ drive_progress(int ac, char **av)
/* Get the info for this drive. */
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u", device_id);
- return (errno);
+ return (error);
}
close(fd);
@@ -551,8 +564,9 @@ drive_clear(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -561,16 +575,18 @@ drive_clear(int ac, char **av)
/* Get the info for this drive. */
if (mfi_pd_get_info(fd, device_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u", device_id);
- return (errno);
+ return (error);
}
mbox_store_pdref(&mbox[0], &info.ref);
if (mfi_dcmd_command(fd, opcode, NULL, 0, mbox, 4, NULL) < 0) {
+ error = errno;
warn("Failed to %s clear on drive %u",
opcode == MFI_DCMD_PD_CLEAR_START ? "start" : "stop",
device_id);
- return (errno);
+ return (error);
}
close(fd);
@@ -604,8 +620,9 @@ drive_locate(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
error = mfi_lookup_drive(fd, av[1], &device_id);
@@ -617,10 +634,11 @@ drive_locate(int ac, char **av)
mbox[2] = 0;
mbox[3] = 0;
if (mfi_dcmd_command(fd, opcode, NULL, 0, mbox, 4, NULL) < 0) {
+ error = errno;
warn("Failed to %s locate on drive %u",
opcode == MFI_DCMD_PD_LOCATE_START ? "start" : "stop",
device_id);
- return (errno);
+ return (error);
}
close(fd);
diff --git a/usr.sbin/mfiutil/mfi_evt.c b/usr.sbin/mfiutil/mfi_evt.c
index d553dae..31c5ec3 100644
--- a/usr.sbin/mfiutil/mfi_evt.c
+++ b/usr.sbin/mfiutil/mfi_evt.c
@@ -32,7 +32,6 @@
#include <sys/types.h>
#include <sys/errno.h>
#include <err.h>
-//#include <libutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
@@ -67,7 +66,7 @@ static int
show_logstate(int ac, char **av)
{
struct mfi_evt_log_state info;
- int fd;
+ int error, fd;
if (ac != 1) {
warnx("show logstate: extra arguments");
@@ -76,13 +75,15 @@ show_logstate(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_event_get_info(fd, &info, NULL) < 0) {
+ error = errno;
warn("Failed to get event log info");
- return (errno);
+ return (error);
}
printf("mfi%d Event Log Sequence Numbers:\n", mfi_unit);
@@ -536,18 +537,20 @@ show_events(int ac, char **av)
ssize_t size;
uint32_t seq, start, stop;
uint8_t status;
- int ch, fd, num_events, verbose;
+ int ch, error, fd, num_events, verbose;
u_int i;
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_event_get_info(fd, &info, NULL) < 0) {
+ error = errno;
warn("Failed to get event log info");
- return (errno);
+ return (error);
}
/* Default settings. */
@@ -565,14 +568,16 @@ show_events(int ac, char **av)
switch (ch) {
case 'c':
if (parse_class(optarg, &filter.members.class) < 0) {
+ error = errno;
warn("Error parsing event class");
- return (errno);
+ return (error);
}
break;
case 'l':
if (parse_locale(optarg, &filter.members.locale) < 0) {
+ error = errno;
warn("Error parsing event locale");
- return (errno);
+ return (error);
}
break;
case 'n':
@@ -608,20 +613,23 @@ show_events(int ac, char **av)
return (EINVAL);
}
if (ac > 0 && parse_seq(&info, av[0], &start) < 0) {
+ error = errno;
warn("Error parsing starting sequence number");
- return (errno);
+ return (error);
}
if (ac > 1 && parse_seq(&info, av[1], &stop) < 0) {
+ error = errno;
warn("Error parsing ending sequence number");
- return (errno);
+ return (error);
}
list = malloc(size);
for (seq = start;;) {
if (mfi_get_events(fd, list, num_events, filter, seq,
&status) < 0) {
+ error = errno;
warn("Failed to fetch events");
- return (errno);
+ return (error);
}
if (status == MFI_STAT_NOT_FOUND) {
if (seq == start)
diff --git a/usr.sbin/mfiutil/mfi_flash.c b/usr.sbin/mfiutil/mfi_flash.c
index 5dd93f1..87bdaca 100644
--- a/usr.sbin/mfiutil/mfi_flash.c
+++ b/usr.sbin/mfiutil/mfi_flash.c
@@ -72,16 +72,18 @@ display_firmware(struct mfi_info_component *comp)
fw_time_width, comp->build_time);
}
-static void
+static int
display_pending_firmware(int fd)
{
struct mfi_ctrl_info info;
struct mfi_info_component header;
+ int error;
u_int i;
if (mfi_ctrl_get_info(fd, &info, NULL) < 0) {
+ error = errno;
warn("Failed to get controller info");
- return;
+ return (error);
}
printf("mfi%d Pending Firmware Images:\n", mfi_unit);
@@ -97,6 +99,8 @@ display_pending_firmware(int fd)
display_firmware(&header);
for (i = 0; i < info.pending_image_component_count; i++)
display_firmware(&info.pending_image_component[i]);
+
+ return (0);
}
static void
@@ -117,7 +121,7 @@ flash_adapter(int ac, char **av)
size_t nread;
char *buf;
struct stat sb;
- int fd, flash;
+ int error, fd, flash;
uint8_t mbox[4], status;
if (ac != 2) {
@@ -127,13 +131,15 @@ flash_adapter(int ac, char **av)
flash = open(av[1], O_RDONLY);
if (flash < 0) {
+ error = errno;
warn("flash: Failed to open %s", av[1]);
- return (errno);
+ return (error);
}
if (fstat(flash, &sb) < 0) {
+ error = errno;
warn("fstat(%s)", av[1]);
- return (errno);
+ return (error);
}
if (sb.st_size % 1024 != 0 || sb.st_size > 0x7fffffff) {
warnx("Invalid flash file size");
@@ -142,8 +148,9 @@ flash_adapter(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
/* First, ask the firmware to allocate space for the flash file. */
@@ -190,10 +197,10 @@ flash_adapter(int ac, char **av)
return (ENXIO);
}
printf("finished\n");
- display_pending_firmware(fd);
+ error = display_pending_firmware(fd);
close(fd);
- return (0);
+ return (error);
}
MFI_COMMAND(top, flash, flash_adapter);
diff --git a/usr.sbin/mfiutil/mfi_patrol.c b/usr.sbin/mfiutil/mfi_patrol.c
index b8da2ae..6980bec 100644
--- a/usr.sbin/mfiutil/mfi_patrol.c
+++ b/usr.sbin/mfiutil/mfi_patrol.c
@@ -62,11 +62,13 @@ mfi_get_time(int fd, uint32_t *at)
static int
patrol_get_props(int fd, struct mfi_pr_properties *prop)
{
+ int error;
if (mfi_dcmd_command(fd, MFI_DCMD_PR_GET_PROPERTIES, prop,
sizeof(*prop), NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to get patrol read properties");
- return (-1);
+ return (error);
}
return (0);
}
@@ -81,19 +83,21 @@ show_patrol(int ac, char **av)
char label[16];
time_t now;
uint32_t at;
- int fd;
+ int error, fd;
u_int i;
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
time(&now);
mfi_get_time(fd, &at);
- if (patrol_get_props(fd, &prop) < 0)
- return (errno);
+ error = patrol_get_props(fd, &prop);
+ if (error)
+ return (error);
printf("Operation Mode: ");
switch (prop.op_mode) {
case MFI_PR_OPMODE_AUTO:
@@ -122,8 +126,9 @@ show_patrol(int ac, char **av)
if (mfi_dcmd_command(fd, MFI_DCMD_PR_GET_STATUS, &status,
sizeof(status), NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to get patrol read properties");
- return (errno);
+ return (error);
}
printf("Runs Completed: %u\n", status.num_iteration);
printf("Current State: ");
@@ -146,8 +151,9 @@ show_patrol(int ac, char **av)
}
if (status.state == MFI_PR_STATE_ACTIVE) {
if (mfi_pd_get_list(fd, &list, NULL) < 0) {
+ error = errno;
warn("Failed to get drive list");
- return (errno);
+ return (error);
}
for (i = 0; i < list->count; i++) {
@@ -156,9 +162,10 @@ show_patrol(int ac, char **av)
if (mfi_pd_get_info(fd, list->addr[i].device_id, &info,
NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u",
list->addr[i].device_id);
- return (errno);
+ return (error);
}
if (info.prog_info.active & MFI_PD_PROGRESS_PATROL) {
snprintf(label, sizeof(label), " Drive %u",
@@ -178,18 +185,20 @@ MFI_COMMAND(show, patrol, show_patrol);
static int
start_patrol(int ac, char **av)
{
- int fd;
+ int error, fd;
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_dcmd_command(fd, MFI_DCMD_PR_START, NULL, 0, NULL, 0, NULL) <
0) {
+ error = errno;
warn("Failed to start patrol read");
- return (errno);
+ return (error);
}
close(fd);
@@ -201,18 +210,20 @@ MFI_COMMAND(start, patrol, start_patrol);
static int
stop_patrol(int ac, char **av)
{
- int fd;
+ int error, fd;
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_dcmd_command(fd, MFI_DCMD_PR_STOP, NULL, 0, NULL, 0, NULL) <
0) {
+ error = errno;
warn("Failed to stop patrol read");
- return (errno);
+ return (error);
}
close(fd);
@@ -227,10 +238,10 @@ patrol_config(int ac, char **av)
struct mfi_pr_properties prop;
long val;
time_t now;
+ int error, fd;
uint32_t at, next_exec, exec_freq;
char *cp;
uint8_t op_mode;
- int fd;
exec_freq = 0; /* GCC too stupid */
next_exec = 0;
@@ -272,12 +283,14 @@ patrol_config(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
- if (patrol_get_props(fd, &prop) < 0)
- return (errno);
+ error = patrol_get_props(fd, &prop);
+ if (error)
+ return (error);
prop.op_mode = op_mode;
if (op_mode == MFI_PR_OPMODE_AUTO) {
if (ac > 2)
@@ -294,8 +307,9 @@ patrol_config(int ac, char **av)
}
if (mfi_dcmd_command(fd, MFI_DCMD_PR_SET_PROPERTIES, &prop,
sizeof(prop), NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to set patrol read properties");
- return (errno);
+ return (error);
}
close(fd);
diff --git a/usr.sbin/mfiutil/mfi_show.c b/usr.sbin/mfiutil/mfi_show.c
index abd1110..0cc1633 100644
--- a/usr.sbin/mfiutil/mfi_show.c
+++ b/usr.sbin/mfiutil/mfi_show.c
@@ -54,7 +54,7 @@ show_adapter(int ac, char **av)
{
struct mfi_ctrl_info info;
char stripe[5];
- int fd, comma;
+ int error, fd, comma;
if (ac != 1) {
warnx("show adapter: extra arguments");
@@ -63,13 +63,15 @@ show_adapter(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_ctrl_get_info(fd, &info, NULL) < 0) {
+ error = errno;
warn("Failed to get controller info");
- return (errno);
+ return (error);
}
printf("mfi%d Adapter:\n", mfi_unit);
printf(" Product Name: %.80s\n", info.product_name);
@@ -137,7 +139,7 @@ show_battery(int ac, char **av)
struct mfi_bbu_capacity_info cap;
struct mfi_bbu_design_info design;
uint8_t status;
- int fd;
+ int error, fd;
if (ac != 1) {
warnx("show battery: extra arguments");
@@ -146,8 +148,9 @@ show_battery(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_dcmd_command(fd, MFI_DCMD_BBU_GET_CAPACITY_INFO, &cap,
@@ -156,14 +159,16 @@ show_battery(int ac, char **av)
printf("mfi%d: No battery present\n", mfi_unit);
return (0);
}
+ error = errno;
warn("Failed to get capacity info");
- return (errno);
+ return (error);
}
if (mfi_dcmd_command(fd, MFI_DCMD_BBU_GET_DESIGN_INFO, &design,
sizeof(design), NULL, 0, NULL) < 0) {
+ error = errno;
warn("Failed to get design info");
- return (errno);
+ return (error);
}
printf("mfi%d: Battery State:\n", mfi_unit);
@@ -242,7 +247,7 @@ show_config(int ac, char **av)
struct mfi_pd_info pinfo;
uint16_t device_id;
char *p;
- int fd, i, j;
+ int error, fd, i, j;
if (ac != 1) {
warnx("show config: extra arguments");
@@ -251,14 +256,16 @@ show_config(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
/* Get the config from the controller. */
if (mfi_config_read(fd, &config) < 0) {
+ error = errno;
warn("Failed to get config");
- return (errno);
+ return (error);
}
/* Dump out the configuration. */
@@ -337,8 +344,8 @@ show_volumes(int ac, char **av)
{
struct mfi_ld_list list;
struct mfi_ld_info info;
+ int error, fd;
u_int i, len, state_len;
- int fd;
if (ac != 1) {
warnx("show volumes: extra arguments");
@@ -347,14 +354,16 @@ show_volumes(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
/* Get the logical drive list from the controller. */
if (mfi_ld_get_list(fd, &list, NULL) < 0) {
+ error = errno;
warn("Failed to get volume list");
- return (errno);
+ return (error);
}
/* List the volumes. */
@@ -376,9 +385,10 @@ show_volumes(int ac, char **av)
for (i = 0; i < list.ld_count; i++) {
if (mfi_ld_get_info(fd, list.ld_list[i].ld.v.target_id, &info,
NULL) < 0) {
+ error = errno;
warn("Failed to get info for volume %d",
list.ld_list[i].ld.v.target_id);
- return (errno);
+ return (error);
}
printf("%6s ",
mfi_volume_name(fd, list.ld_list[i].ld.v.target_id));
@@ -416,7 +426,7 @@ show_drives(int ac, char **av)
struct mfi_pd_list *list;
struct mfi_pd_info info;
u_int i, len, state_len;
- int fd;
+ int error, fd;
if (ac != 1) {
warnx("show drives: extra arguments");
@@ -425,13 +435,15 @@ show_drives(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_pd_get_list(fd, &list, NULL) < 0) {
+ error = errno;
warn("Failed to get drive list");
- return (errno);
+ return (error);
}
/* Walk the list of drives to determine width of state column. */
@@ -442,9 +454,10 @@ show_drives(int ac, char **av)
if (mfi_pd_get_info(fd, list->addr[i].device_id, &info,
NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u",
list->addr[i].device_id);
- return (errno);
+ return (error);
}
len = strlen(mfi_pdstate(info.fw_state));
if (len > state_len)
@@ -462,9 +475,10 @@ show_drives(int ac, char **av)
/* Fetch details for this drive. */
if (mfi_pd_get_info(fd, list->addr[i].device_id, &info,
NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for drive %u",
list->addr[i].device_id);
- return (errno);
+ return (error);
}
print_pd(&info, state_len, 1);
@@ -511,7 +525,7 @@ show_firmware(int ac, char **av)
{
struct mfi_ctrl_info info;
struct mfi_info_component header;
- int fd;
+ int error, fd;
u_int i;
if (ac != 1) {
@@ -521,13 +535,15 @@ show_firmware(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_ctrl_get_info(fd, &info, NULL) < 0) {
+ error = errno;
warn("Failed to get controller info");
- return (errno);
+ return (error);
}
if (info.package_version[0] != '\0')
diff --git a/usr.sbin/mfiutil/mfi_volume.c b/usr.sbin/mfiutil/mfi_volume.c
index b3f4a76..967a314 100644
--- a/usr.sbin/mfiutil/mfi_volume.c
+++ b/usr.sbin/mfiutil/mfi_volume.c
@@ -114,6 +114,7 @@ static int
update_cache_policy(int fd, struct mfi_ld_props *props, uint8_t new_policy,
uint8_t mask)
{
+ int error;
uint8_t changes, policy;
policy = (props->default_cache_policy & ~mask) | new_policy;
@@ -140,8 +141,9 @@ update_cache_policy(int fd, struct mfi_ld_props *props, uint8_t new_policy,
props->default_cache_policy = policy;
if (mfi_ld_set_props(fd, props) < 0) {
+ error = errno;
warn("Failed to set volume properties");
- return (errno);
+ return (error);
}
return (0);
}
@@ -160,18 +162,21 @@ volume_cache(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_lookup_volume(fd, av[1], &target_id) < 0) {
+ error = errno;
warn("Invalid volume: %s", av[1]);
- return (errno);
+ return (error);
}
if (mfi_ld_get_props(fd, target_id, &props) < 0) {
+ error = errno;
warn("Failed to fetch volume properties");
- return (errno);
+ return (error);
}
if (ac == 2) {
@@ -298,8 +303,8 @@ volume_cache(int ac, char **av)
}
props.disk_cache_policy = policy;
if (mfi_ld_set_props(fd, &props) < 0) {
- warn("Failed to set volume properties");
error = errno;
+ warn("Failed to set volume properties");
}
}
} else {
@@ -317,7 +322,7 @@ static int
volume_name(int ac, char **av)
{
struct mfi_ld_props props;
- int fd;
+ int error, fd;
uint8_t target_id;
if (ac != 3) {
@@ -332,18 +337,21 @@ volume_name(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_lookup_volume(fd, av[1], &target_id) < 0) {
+ error = errno;
warn("Invalid volume: %s", av[1]);
- return (errno);
+ return (error);
}
if (mfi_ld_get_props(fd, target_id, &props) < 0) {
+ error = errno;
warn("Failed to fetch volume properties");
- return (errno);
+ return (error);
}
printf("mfi%u volume %s name changed from \"%s\" to \"%s\"\n", mfi_unit,
@@ -351,8 +359,9 @@ volume_name(int ac, char **av)
bzero(props.name, sizeof(props.name));
strcpy(props.name, av[2]);
if (mfi_ld_set_props(fd, &props) < 0) {
+ error = errno;
warn("Failed to set volume properties");
- return (errno);
+ return (error);
}
close(fd);
@@ -365,7 +374,7 @@ static int
volume_progress(int ac, char **av)
{
struct mfi_ld_info info;
- int fd;
+ int error, fd;
uint8_t target_id;
if (ac != 2) {
@@ -376,20 +385,23 @@ volume_progress(int ac, char **av)
fd = mfi_open(mfi_unit);
if (fd < 0) {
+ error = errno;
warn("mfi_open");
- return (errno);
+ return (error);
}
if (mfi_lookup_volume(fd, av[1], &target_id) < 0) {
+ error = errno;
warn("Invalid volume: %s", av[1]);
- return (errno);
+ return (error);
}
/* Get the info for this drive. */
if (mfi_ld_get_info(fd, target_id, &info, NULL) < 0) {
+ error = errno;
warn("Failed to fetch info for volume %s",
mfi_volume_name(fd, target_id));
- return (errno);
+ return (error);
}
/* Display any of the active events. */
diff --git a/usr.sbin/pc-sysinstall/backend-query/disk-info.sh b/usr.sbin/pc-sysinstall/backend-query/disk-info.sh
index 8c55fce..adaeaa5 100755
--- a/usr.sbin/pc-sysinstall/backend-query/disk-info.sh
+++ b/usr.sbin/pc-sysinstall/backend-query/disk-info.sh
@@ -28,6 +28,7 @@
# Query a disk for partitions and display them
#############################################################################
+. ${PROGDIR}/backend/functions.sh
. ${PROGDIR}/backend/functions-disk.sh
DISK="${1}"
@@ -57,4 +58,3 @@ echo "heads=${HEADS}"
echo "sectors=${SECS}"
echo "size=${MB}"
echo "type=${CTYPE}"
-
diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5
index dcc73cc..81ffa70 100644
--- a/usr.sbin/rtadvd/rtadvd.conf.5
+++ b/usr.sbin/rtadvd/rtadvd.conf.5
@@ -109,7 +109,7 @@ The default value is 64.
(str or num) A 8-bit flags field in router advertisement message header.
This field can be specified either as a case-sensitive string or as an
integer.
-A sting consists of characters each of which corresponds to a
+A string consists of characters each of which corresponds to a
particular flag bit(s).
An integer should be the logical OR of all enabled bits.
Bit 7
@@ -201,7 +201,7 @@ The default value is 64.
(str or num) A 8-bit flags field in prefix information option.
This field can be specified either as a case-sensitive string or as an
integer.
-A sting consists of characters each of which corresponds to a
+A string consists of characters each of which corresponds to a
particular flag bit(s).
An integer should be the logical OR of all enabled bits.
Bit 7
diff --git a/usr.sbin/tcpdump/tcpdump/Makefile b/usr.sbin/tcpdump/tcpdump/Makefile
index c296943..eef16c7 100644
--- a/usr.sbin/tcpdump/tcpdump/Makefile
+++ b/usr.sbin/tcpdump/tcpdump/Makefile
@@ -15,9 +15,9 @@ SRCS = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c \
print-cfm.c print-chdlc.c print-cip.c print-cnfp.c print-dccp.c \
print-decnet.c print-domain.c print-dtp.c print-dvmrp.c print-enc.c \
print-egp.c print-eap.c print-eigrp.c \
- print-esp.c print-ether.c print-fddi.c print-fr.c \
+ print-esp.c print-ether.c print-fddi.c print-forces.c print-fr.c \
print-gre.c print-hsrp.c print-icmp.c print-igmp.c \
- print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c \
+ print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c print-ipnet.c \
print-ipx.c print-isakmp.c print-isoclns.c print-juniper.c print-krb.c \
print-l2tp.c print-lane.c print-ldp.c print-lldp.c print-llc.c \
print-lmp.c print-lspping.c \
@@ -33,7 +33,7 @@ SRCS = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c \
print-timed.c print-token.c print-udld.c print-udp.c print-vjc.c \
print-vqp.c print-vrrp.c print-vtp.c \
print-wb.c print-zephyr.c setsignal.c tcpdump.c util.c \
- print-smb.c smbutil.c \
+ print-smb.c signature.c smbutil.c \
version.c
CLEANFILES+= version.c
@@ -56,7 +56,7 @@ LDADD= -ll -lpcap
DPADD+= ${LIBCRYPTO}
LDADD+= -lcrypto
CFLAGS+= -I${DESTDIR}/usr/include/openssl
-CFLAGS+= -DHAVE_LIBCRYPTO -DHAVE_RC5_H -DHAVE_CAST_H -DHAVE_OPENSSL_EVP_H
+CFLAGS+= -DHAVE_LIBCRYPTO -DHAVE_OPENSSL_EVP_H
.endif
.if ${MK_PF} != "no"
diff --git a/usr.sbin/tcpdump/tcpdump/config.h b/usr.sbin/tcpdump/tcpdump/config.h
index b7b85a5..1637405 100644
--- a/usr.sbin/tcpdump/tcpdump/config.h
+++ b/usr.sbin/tcpdump/tcpdump/config.h
@@ -1,14 +1,11 @@
/* $FreeBSD$ */
/* This is an edited copy of the config.h generated by configure. */
-/* config.h. Generated by configure. */
+/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* "generated automatically" means DO NOT MAKE CHANGES TO config.h.in --
* make them to acconfig.h and rerun autoheader */
-/* Define if you have SSLeay 0.9.0b with the buggy cast128. */
-/* #undef HAVE_BUGGY_CAST128 */
-
/* Define if you enable IPv6 support */
/* See Makefile */
/* #undef INET6 */
@@ -16,23 +13,12 @@
/* Define if you enable support for the libsmi. */
/* #undef LIBSMI */
-/* Define if you have the <smi.h> header file. */
-/* #undef HAVE_SMI_H */
-
/* define if you have struct __res_state_ext */
/* #undef HAVE_RES_STATE_EXT */
/* define if your struct __res_state has the nsort member */
/* #undef HAVE_NEW_RES_STATE */
-/*
- * define if struct ether_header.ether_dhost is a struct with ether_addr_octet
- */
-/* #undef ETHER_HEADER_HAS_EA */
-
-/* define if struct ether_arp contains arp_xsha */
-/* #undef ETHER_ARP_HAS_X */
-
/* define if you have the addrinfo function. */
#define HAVE_ADDRINFO 1
@@ -48,18 +34,9 @@
/* define if INADDRSZ is defined (XXX not used!) */
#define HAVE_INADDRSZ 1
-/* define if this is a development version, to use additional prototypes. */
-/* #undef HAVE_OS_PROTO_H */
-
-/* define if <unistd.h> defines __P() */
-/* #undef HAVE_PORTABLE_PROTOTYPE */
-
/* define if RES_USE_INET6 is defined */
#define HAVE_RES_USE_INET6 1
-/* define if struct sockaddr has the sa_len member */
-#define HAVE_SOCKADDR_SA_LEN 1
-
/* define if you have struct sockaddr_storage */
#define HAVE_SOCKADDR_STORAGE 1
@@ -96,18 +73,6 @@
/* define if you have getrpcbynumber() */
#define HAVE_GETRPCBYNUMBER 1
-/* define if unaligned memory accesses fail */
-/* #undef LBL_ALIGN */
-
-/* The successful return value from signal (?)XXX */
-#define RETSIGVAL
-
-/* Define this on IRIX */
-/* #undef _BSD_SIGNALS */
-
-/* For HP/UX ANSI compiler? */
-/* #undef _HPUX_SOURCE */
-
/* AIX hack. */
/* #undef _SUN */
@@ -120,14 +85,6 @@
/* Whether or not to include the possibly-buggy SMB printer */
#define TCPDUMP_DO_SMB 1
-/* Long story short: aclocal.m4 depends on autoconf 2.13
- * implementation details wrt "const"; newer versions
- * have different implementation details so for now we
- * put "const" here. This may cause duplicate definitions
- * in config.h but that should be OK since they're the same.
- */
-/* #undef const */
-
/* Define if you have the dnet_htoa function. */
/* #undef HAVE_DNET_HTOA */
@@ -156,9 +113,6 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
-/* Define to 1 if you have the `getaddrinfo' function. */
-#define HAVE_GETADDRINFO 1
-
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
@@ -195,9 +149,18 @@
/* See Makefile */
/* #undef HAVE_OPENSSL_EVP_H 1 */
+/* if there's an os_proto.h for this platform, to use additional prototypes */
+/* #undef HAVE_OS_PROTO_H */
+
+/* Define to 1 if you have the <pcap/bluetooth.h> header file. */
+/* #undef HAVE_PCAP_BLUETOOTH_H */
+
/* Define to 1 if you have the `pcap_breakloop' function. */
#define HAVE_PCAP_BREAKLOOP 1
+/* Define to 1 if you have the `pcap_create' function. */
+#define HAVE_PCAP_CREATE 1
+
/* Define to 1 if you have the `pcap_dump_flush' function. */
#define HAVE_PCAP_DUMP_FLUSH 1
@@ -210,6 +173,9 @@
/* Define to 1 if you have the `pcap_lib_version' function. */
#define HAVE_PCAP_LIB_VERSION 1
+/* Define to 1 if you have the <pcap/usb.h> header file. */
+/* #undef HAVE_PCAP_USB_H */
+
/* Define to 1 if you have the `pfopen' function. */
/* #undef HAVE_PFOPEN */
@@ -231,6 +197,9 @@
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
+/* if struct sockaddr has the sa_len member */
+#define HAVE_SOCKADDR_SA_LEN 1
+
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
@@ -285,6 +254,9 @@
/* define if your compiler has __attribute__ */
#define HAVE___ATTRIBUTE__ 1
+/* if unaligned access fails */
+/* #undef LBL_ALIGN */
+
/* Define to 1 if netinet/ether.h declares `ether_ntohost' */
/* #undef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */
@@ -309,21 +281,23 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
+/* return value of signal handlers */
+#define RETSIGVAL
+
/* The size of `char', as computed by sizeof. */
-#define SIZEOF_CHAR 1
+#undef SIZEOF_CHAR
/* The size of `int', as computed by sizeof. */
-#define SIZEOF_INT 4
+#undef SIZEOF_INT
/* The size of `long', as computed by sizeof. */
-/* XXX: This is wrong, but possibly unused */
-#define SIZEOF_LONG 4
+#undef SIZEOF_LONG
/* The size of `long long', as computed by sizeof. */
-#define SIZEOF_LONG_LONG 8
+#undef SIZEOF_LONG_LONG
/* The size of `short', as computed by sizeof. */
-#define SIZEOF_SHORT 2
+#undef SIZEOF_SHORT
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -331,6 +305,19 @@
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
+/* get BSD semantics on Irix */
+/* #undef _BSD_SIGNALS */
+
+/* needed on HP-UX */
+/* #undef _HPUX_SOURCE */
+
+/* define if your compiler allows __attribute__((format)) to be applied to
+ function pointers */
+#define __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS 1
+
+/* to handle Ultrix compilers that don't support const in prototypes */
+/* #undef const */
+
/* Define as token for inline if inlining supported */
#define inline inline
diff --git a/usr.sbin/tcpdump/tcpdump/tcpdump.1 b/usr.sbin/tcpdump/tcpdump/tcpdump.1
new file mode 100644
index 0000000..20f492f
--- /dev/null
+++ b/usr.sbin/tcpdump/tcpdump/tcpdump.1
@@ -0,0 +1,1722 @@
+.\" $FreeBSD$
+.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1.in,v 1.2 2008-11-09 23:35:03 mcr Exp $ (LBL)
+.\"
+.\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $
+.\"
+.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
+.\" The Regents of the University of California. All rights reserved.
+.\" 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, (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, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" 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.
+.\"
+.TH TCPDUMP 1 "05 March 2009"
+.SH NAME
+tcpdump \- dump traffic on a network
+.SH SYNOPSIS
+.na
+.B tcpdump
+[
+.B \-AbdDefIKlLnNOpqRStuUvxX
+] [
+.B \-B
+.I buffer_size
+] [
+.B \-c
+.I count
+]
+.br
+.ti +8
+[
+.B \-C
+.I file_size
+] [
+.B \-G
+.I rotate_seconds
+] [
+.B \-F
+.I file
+]
+.br
+.ti +8
+[
+.B \-i
+.I interface
+]
+[
+.B \-m
+.I module
+]
+[
+.B \-M
+.I secret
+]
+.br
+.ti +8
+[
+.B \-r
+.I file
+]
+[
+.B \-s
+.I snaplen
+]
+[
+.B \-T
+.I type
+]
+[
+.B \-w
+.I file
+]
+.br
+.ti +8
+[
+.B \-W
+.I filecount
+]
+.br
+.ti +8
+[
+.B \-E
+.I spi@ipaddr algo:secret,...
+]
+.br
+.ti +8
+[
+.B \-y
+.I datalinktype
+]
+[
+.B \-z
+.I postrotate-command
+]
+[
+.B \-Z
+.I user
+]
+.ti +8
+[
+.I expression
+]
+.br
+.ad
+.SH DESCRIPTION
+.LP
+\fITcpdump\fP prints out a description of the contents of packets on a
+network interface that match the boolean \fIexpression\fP. It can also
+be run with the
+.B \-w
+flag, which causes it to save the packet data to a file for later
+analysis, and/or with the
+.B \-r
+flag, which causes it to read from a saved packet file rather than to
+read packets from a network interface. In all cases, only packets that
+match
+.I expression
+will be processed by
+.IR tcpdump .
+.LP
+.I Tcpdump
+will, if not run with the
+.B \-c
+flag, continue capturing packets until it is interrupted by a SIGINT
+signal (generated, for example, by typing your interrupt character,
+typically control-C) or a SIGTERM signal (typically generated with the
+.BR kill (1)
+command); if run with the
+.B \-c
+flag, it will capture packets until it is interrupted by a SIGINT or
+SIGTERM signal or the specified number of packets have been processed.
+.LP
+When
+.I tcpdump
+finishes capturing packets, it will report counts of:
+.IP
+packets ``captured'' (this is the number of packets that
+.I tcpdump
+has received and processed);
+.IP
+packets ``received by filter'' (the meaning of this depends on the OS on
+which you're running
+.IR tcpdump ,
+and possibly on the way the OS was configured - if a filter was
+specified on the command line, on some OSes it counts packets regardless
+of whether they were matched by the filter expression and, even if they
+were matched by the filter expression, regardless of whether
+.I tcpdump
+has read and processed them yet, on other OSes it counts only packets that were
+matched by the filter expression regardless of whether
+.I tcpdump
+has read and processed them yet, and on other OSes it counts only
+packets that were matched by the filter expression and were processed by
+.IR tcpdump );
+.IP
+packets ``dropped by kernel'' (this is the number of packets that were
+dropped, due to a lack of buffer space, by the packet capture mechanism
+in the OS on which
+.I tcpdump
+is running, if the OS reports that information to applications; if not,
+it will be reported as 0).
+.LP
+On platforms that support the SIGINFO signal, such as most BSDs
+(including Mac OS X) and Digital/Tru64 UNIX, it will report those counts
+when it receives a SIGINFO signal (generated, for example, by typing
+your ``status'' character, typically control-T, although on some
+platforms, such as Mac OS X, the ``status'' character is not set by
+default, so you must set it with
+.BR stty (1)
+in order to use it) and will continue capturing packets.
+.LP
+Reading packets from a network interface may require that you have
+special privileges; see the
+.B pcap (3PCAP)
+man page for details. Reading a saved packet file doesn't require
+special privileges.
+.SH OPTIONS
+.TP
+.B \-A
+Print each packet (minus its link level header) in ASCII. Handy for
+capturing web pages.
+.TP
+.B \-b
+Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN
+notation.
+.TP
+.B \-B
+Set the operating system capture buffer size to \fIbuffer_size\fP.
+.TP
+.B \-c
+Exit after receiving \fIcount\fP packets.
+.TP
+.B \-C
+Before writing a raw packet to a savefile, check whether the file is
+currently larger than \fIfile_size\fP and, if so, close the current
+savefile and open a new one. Savefiles after the first savefile will
+have the name specified with the
+.B \-w
+flag, with a number after it, starting at 1 and continuing upward.
+The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes,
+not 1,048,576 bytes).
+.TP
+.B \-d
+Dump the compiled packet-matching code in a human readable form to
+standard output and stop.
+.TP
+.B \-dd
+Dump packet-matching code as a
+.B C
+program fragment.
+.TP
+.B \-ddd
+Dump packet-matching code as decimal numbers (preceded with a count).
+.TP
+.B \-D
+Print the list of the network interfaces available on the system and on
+which
+.I tcpdump
+can capture packets. For each network interface, a number and an
+interface name, possibly followed by a text description of the
+interface, is printed. The interface name or the number can be supplied
+to the
+.B \-i
+flag to specify an interface on which to capture.
+.IP
+This can be useful on systems that don't have a command to list them
+(e.g., Windows systems, or UNIX systems lacking
+.BR "ifconfig \-a" );
+the number can be useful on Windows 2000 and later systems, where the
+interface name is a somewhat complex string.
+.IP
+The
+.B \-D
+flag will not be supported if
+.I tcpdump
+was built with an older version of
+.I libpcap
+that lacks the
+.B pcap_findalldevs()
+function.
+.TP
+.B \-e
+Print the link-level header on each dump line.
+.TP
+.B \-E
+Use \fIspi@ipaddr algo:secret\fP for decrypting IPsec ESP packets that
+are addressed to \fIaddr\fP and contain Security Parameter Index value
+\fIspi\fP. This combination may be repeated with comma or newline seperation.
+.IP
+Note that setting the secret for IPv4 ESP packets is supported at this time.
+.IP
+Algorithms may be
+\fBdes-cbc\fP,
+\fB3des-cbc\fP,
+\fBblowfish-cbc\fP,
+\fBrc3-cbc\fP,
+\fBcast128-cbc\fP, or
+\fBnone\fP.
+The default is \fBdes-cbc\fP.
+The ability to decrypt packets is only present if \fItcpdump\fP was compiled
+with cryptography enabled.
+.IP
+\fIsecret\fP is the ASCII text for ESP secret key.
+If preceeded by 0x, then a hex value will be read.
+.IP
+The option assumes RFC2406 ESP, not RFC1827 ESP.
+The option is only for debugging purposes, and
+the use of this option with a true `secret' key is discouraged.
+By presenting IPsec secret key onto command line
+you make it visible to others, via
+.IR ps (1)
+and other occasions.
+.IP
+In addition to the above syntax, the syntax \fIfile name\fP may be used
+to have tcpdump read the provided file in. The file is opened upon
+receiving the first ESP packet, so any special permissions that tcpdump
+may have been given should already have been given up.
+.TP
+.B \-f
+Print `foreign' IPv4 addresses numerically rather than symbolically
+(this option is intended to get around serious brain damage in
+Sun's NIS server \(em usually it hangs forever translating non-local
+internet numbers).
+.IP
+The test for `foreign' IPv4 addresses is done using the IPv4 address and
+netmask of the interface on which capture is being done. If that
+address or netmask are not available, available, either because the
+interface on which capture is being done has no address or netmask or
+because the capture is being done on the Linux "any" interface, which
+can capture on more than one interface, this option will not work
+correctly.
+.TP
+.B \-F
+Use \fIfile\fP as input for the filter expression.
+An additional expression given on the command line is ignored.
+.TP
+.B \-G
+If specified, rotates the dump file specified with the
+.B \-w
+option every \fIrotate_seconds\fP seconds.
+Savefiles will have the name specified by
+.B \-w
+which should include a time format as defined by
+.BR strftime (3).
+If no time format is specified, each new file will overwrite the previous.
+.IP
+If used in conjunction with the
+.B \-C
+option, filenames will take the form of `\fIfile\fP<count>'.
+.TP
+.B \-i
+Listen on \fIinterface\fP.
+If unspecified, \fItcpdump\fP searches the system interface list for the
+lowest numbered, configured up interface (excluding loopback).
+Ties are broken by choosing the earliest match.
+.IP
+On Linux systems with 2.2 or later kernels, an
+.I interface
+argument of ``any'' can be used to capture packets from all interfaces.
+Note that captures on the ``any'' device will not be done in promiscuous
+mode.
+.IP
+If the
+.B \-D
+flag is supported, an interface number as printed by that flag can be
+used as the
+.I interface
+argument.
+.TP
+.B \-I
+Put the interface in "monitor mode"; this is supported only on IEEE
+802.11 Wi-Fi interfaces, and supported only on some operating systems.
+.IP
+Note that in monitor mode the adapter might disassociate from the
+network with which it's associated, so that you will not be able to use
+any wireless networks with that adapter. This could prevent accessing
+files on a network server, or resolving host names or network addresses,
+if you are capturing in monitor mode and are not connected to another
+network with another adapter.
+.IP
+This flag will affect the output of the
+.B \-L
+flag. If
+.B \-I
+isn't specified, only those link-layer types available when not in
+monitor mode will be shown; if
+.B \-I
+is specified, only those link-layer types available when in monitor mode
+will be shown.
+.TP
+.B \-K
+Don't attempt to verify IP, TCP, or UDP checksums. This is useful for
+interfaces that perform some or all of those checksum calculation in
+hardware; otherwise, all outgoing TCP checksums will be flagged as bad.
+.TP
+.B \-l
+Make stdout line buffered.
+Useful if you want to see the data
+while capturing it.
+E.g.,
+.br
+``tcpdump\ \ \-l\ \ |\ \ tee dat'' or
+``tcpdump\ \ \-l \ \ > dat\ \ &\ \ tail\ \ \-f\ \ dat''.
+.TP
+.B \-L
+List the known data link types for the interface, in the specified mode,
+and exit. The list of known data link types may be dependent on the
+specified mode; for example, on some platforms, a Wi-Fi interface might
+support one set of data link types when not in monitor mode (for
+example, it might support only fake Ethernet headers, or might support
+802.11 headers but not support 802.11 headers with radio information)
+and another set of data link types when in monitor mode (for example, it
+might support 802.11 headers, or 802.11 headers with radio information,
+only in monitor mode).
+.TP
+.B \-m
+Load SMI MIB module definitions from file \fImodule\fR.
+This option
+can be used several times to load several MIB modules into \fItcpdump\fP.
+.TP
+.B \-M
+Use \fIsecret\fP as a shared secret for validating the digests found in
+TCP segments with the TCP-MD5 option (RFC 2385), if present.
+.TP
+.B \-n
+Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.
+.TP
+.B \-N
+Don't print domain name qualification of host names.
+E.g.,
+if you give this flag then \fItcpdump\fP will print ``nic''
+instead of ``nic.ddn.mil''.
+.TP
+.B \-O
+Do not run the packet-matching code optimizer.
+This is useful only
+if you suspect a bug in the optimizer.
+.TP
+.B \-p
+\fIDon't\fP put the interface
+into promiscuous mode.
+Note that the interface might be in promiscuous
+mode for some other reason; hence, `-p' cannot be used as an abbreviation for
+`ether host {local-hw-addr} or ether broadcast'.
+.TP
+.B \-q
+Quick (quiet?) output.
+Print less protocol information so output
+lines are shorter.
+.TP
+.B \-R
+Assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829).
+If specified, \fItcpdump\fP will not print replay prevention field.
+Since there is no protocol version field in ESP/AH specification,
+\fItcpdump\fP cannot deduce the version of ESP/AH protocol.
+.TP
+.B \-r
+Read packets from \fIfile\fR (which was created with the
+.B \-w
+option).
+Standard input is used if \fIfile\fR is ``-''.
+.TP
+.B \-S
+Print absolute, rather than relative, TCP sequence numbers.
+.TP
+.B \-s
+Snarf \fIsnaplen\fP bytes of data from each packet rather than the
+default of 65535 bytes.
+Packets truncated because of a limited snapshot
+are indicated in the output with ``[|\fIproto\fP]'', where \fIproto\fP
+is the name of the protocol level at which the truncation has occurred.
+Note that taking larger snapshots both increases
+the amount of time it takes to process packets and, effectively,
+decreases the amount of packet buffering.
+This may cause packets to be
+lost.
+You should limit \fIsnaplen\fP to the smallest number that will
+capture the protocol information you're interested in.
+Setting
+\fIsnaplen\fP to 0 sets it to the default of 65535,
+for backwards compatibility with recent older versions of
+.IR tcpdump .
+.TP
+.B \-T
+Force packets selected by "\fIexpression\fP" to be interpreted the
+specified \fItype\fR.
+Currently known types are
+\fBaodv\fR (Ad-hoc On-demand Distance Vector protocol),
+\fBcnfp\fR (Cisco NetFlow protocol),
+\fBrpc\fR (Remote Procedure Call),
+\fBrtp\fR (Real-Time Applications protocol),
+\fBrtcp\fR (Real-Time Applications control protocol),
+\fBsnmp\fR (Simple Network Management Protocol),
+\fBtftp\fR (Trivial File Transfer Protocol),
+\fBvat\fR (Visual Audio Tool),
+and
+\fBwb\fR (distributed White Board).
+.TP
+.B \-t
+\fIDon't\fP print a timestamp on each dump line.
+.TP
+.B \-tt
+Print an unformatted timestamp on each dump line.
+.TP
+.B \-ttt
+Print a delta (micro-second resolution) between current and previous line
+on each dump line.
+.TP
+.B \-tttt
+Print a timestamp in default format proceeded by date on each dump line.
+.TP
+.B \-ttttt
+Print a delta (micro-second resolution) between current and first line
+on each dump line.
+.TP
+.B \-u
+Print undecoded NFS handles.
+.TP
+.B \-U
+Make output saved via the
+.B \-w
+option ``packet-buffered''; i.e., as each packet is saved, it will be
+written to the output file, rather than being written only when the
+output buffer fills.
+.IP
+The
+.B \-U
+flag will not be supported if
+.I tcpdump
+was built with an older version of
+.I libpcap
+that lacks the
+.B pcap_dump_flush()
+function.
+.TP
+.B \-v
+When parsing and printing, produce (slightly more) verbose output.
+For example, the time to live,
+identification, total length and options in an IP packet are printed.
+Also enables additional packet integrity checks such as verifying the
+IP and ICMP header checksum.
+.IP
+When writing to a file with the
+.B \-w
+option, report, every 10 seconds, the number of packets captured.
+.TP
+.B \-vv
+Even more verbose output.
+For example, additional fields are
+printed from NFS reply packets, and SMB packets are fully decoded.
+.TP
+.B \-vvv
+Even more verbose output.
+For example,
+telnet \fBSB\fP ... \fBSE\fP options
+are printed in full.
+With
+.B \-X
+Telnet options are printed in hex as well.
+.TP
+.B \-w
+Write the raw packets to \fIfile\fR rather than parsing and printing
+them out.
+They can later be printed with the \-r option.
+Standard output is used if \fIfile\fR is ``-''.
+See
+.BR pcap-savefile (5)
+for a description of the file format.
+.TP
+.B \-W
+Used in conjunction with the
+.B \-C
+option, this will limit the number
+of files created to the specified number, and begin overwriting files
+from the beginning, thus creating a 'rotating' buffer.
+In addition, it will name
+the files with enough leading 0s to support the maximum number of
+files, allowing them to sort correctly.
+.IP
+Used in conjunction with the
+.B \-G
+option, this will limit the number of rotated dump files that get
+created, exiting with status 0 when reaching the limit. If used with
+.B \-C
+as well, the behavior will result in cyclical files per timeslice.
+.TP
+.B \-x
+When parsing and printing,
+in addition to printing the headers of each packet, print the data of
+each packet (minus its link level header) in hex.
+The smaller of the entire packet or
+.I snaplen
+bytes will be printed. Note that this is the entire link-layer
+packet, so for link layers that pad (e.g. Ethernet), the padding bytes
+will also be printed when the higher layer packet is shorter than the
+required padding.
+.TP
+.B \-xx
+When parsing and printing,
+in addition to printing the headers of each packet, print the data of
+each packet,
+.I including
+its link level header, in hex.
+.TP
+.B \-X
+When parsing and printing,
+in addition to printing the headers of each packet, print the data of
+each packet (minus its link level header) in hex and ASCII.
+This is very handy for analysing new protocols.
+.TP
+.B \-XX
+When parsing and printing,
+in addition to printing the headers of each packet, print the data of
+each packet,
+.I including
+its link level header, in hex and ASCII.
+.TP
+.B \-y
+Set the data link type to use while capturing packets to \fIdatalinktype\fP.
+.TP
+.B \-z
+Used in conjunction with the
+.B -C
+or
+.B -G
+options, this will make
+.I tcpdump
+run "
+.I command file
+" where
+.I file
+is the savefile being closed after each rotation. For example, specifying
+.B \-z gzip
+or
+.B \-z bzip2
+will compress each savefile using gzip or bzip2.
+.IP
+Note that tcpdump will run the command in parallel to the capture, using
+the lowest priority so that this doesn't disturb the capture process.
+.IP
+And in case you would like to use a command that itself takes flags or
+different arguments, you can always write a shell script that will take the
+savefile name as the only argument, make the flags & arguments arrangements
+and execute the command that you want.
+.TP
+.B \-Z
+Drops privileges (if root) and changes user ID to
+.I user
+and the group ID to the primary group of
+.IR user .
+.IP
+This behavior can also be enabled by default at compile time.
+.IP "\fI expression\fP"
+.RS
+selects which packets will be dumped.
+If no \fIexpression\fP
+is given, all packets on the net will be dumped.
+Otherwise,
+only packets for which \fIexpression\fP is `true' will be dumped.
+.LP
+For the \fIexpression\fP syntax, see
+.BR pcap-filter (7).
+.LP
+Expression arguments can be passed to \fItcpdump\fP as either a single
+argument or as multiple arguments, whichever is more convenient.
+Generally, if the expression contains Shell metacharacters, it is
+easier to pass it as a single, quoted argument.
+Multiple arguments are concatenated with spaces before being parsed.
+.SH EXAMPLES
+.LP
+To print all packets arriving at or departing from \fIsundown\fP:
+.RS
+.nf
+\fBtcpdump host sundown\fP
+.fi
+.RE
+.LP
+To print traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR:
+.RS
+.nf
+\fBtcpdump host helios and \\( hot or ace \\)\fP
+.fi
+.RE
+.LP
+To print all IP packets between \fIace\fR and any host except \fIhelios\fR:
+.RS
+.nf
+\fBtcpdump ip host ace and not helios\fP
+.fi
+.RE
+.LP
+To print all traffic between local hosts and hosts at Berkeley:
+.RS
+.nf
+.B
+tcpdump net ucb-ether
+.fi
+.RE
+.LP
+To print all ftp traffic through internet gateway \fIsnup\fP:
+(note that the expression is quoted to prevent the shell from
+(mis-)interpreting the parentheses):
+.RS
+.nf
+.B
+tcpdump 'gateway snup and (port ftp or ftp-data)'
+.fi
+.RE
+.LP
+To print traffic neither sourced from nor destined for local hosts
+(if you gateway to one other net, this stuff should never make it
+onto your local net).
+.RS
+.nf
+.B
+tcpdump ip and not net \fIlocalnet\fP
+.fi
+.RE
+.LP
+To print the start and end packets (the SYN and FIN packets) of each
+TCP conversation that involves a non-local host.
+.RS
+.nf
+.B
+tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP'
+.fi
+.RE
+.LP
+To print all IPv4 HTTP packets to and from port 80, i.e. print only
+packets that contain data, not, for example, SYN and FIN packets and
+ACK-only packets. (IPv6 is left as an exercise for the reader.)
+.RS
+.nf
+.B
+tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
+.fi
+.RE
+.LP
+To print IP packets longer than 576 bytes sent through gateway \fIsnup\fP:
+.RS
+.nf
+.B
+tcpdump 'gateway snup and ip[2:2] > 576'
+.fi
+.RE
+.LP
+To print IP broadcast or multicast packets that were
+.I not
+sent via Ethernet broadcast or multicast:
+.RS
+.nf
+.B
+tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
+.fi
+.RE
+.LP
+To print all ICMP packets that are not echo requests/replies (i.e., not
+ping packets):
+.RS
+.nf
+.B
+tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'
+.fi
+.RE
+.SH OUTPUT FORMAT
+.LP
+The output of \fItcpdump\fP is protocol dependent.
+The following
+gives a brief description and examples of most of the formats.
+.de HD
+.sp 1.5
+.B
+..
+.HD
+Link Level Headers
+.LP
+If the '-e' option is given, the link level header is printed out.
+On Ethernets, the source and destination addresses, protocol,
+and packet length are printed.
+.LP
+On FDDI networks, the '-e' option causes \fItcpdump\fP to print
+the `frame control' field, the source and destination addresses,
+and the packet length.
+(The `frame control' field governs the
+interpretation of the rest of the packet.
+Normal packets (such
+as those containing IP datagrams) are `async' packets, with a priority
+value between 0 and 7; for example, `\fBasync4\fR'.
+Such packets
+are assumed to contain an 802.2 Logical Link Control (LLC) packet;
+the LLC header is printed if it is \fInot\fR an ISO datagram or a
+so-called SNAP packet.
+.LP
+On Token Ring networks, the '-e' option causes \fItcpdump\fP to print
+the `access control' and `frame control' fields, the source and
+destination addresses, and the packet length.
+As on FDDI networks,
+packets are assumed to contain an LLC packet.
+Regardless of whether
+the '-e' option is specified or not, the source routing information is
+printed for source-routed packets.
+.LP
+On 802.11 networks, the '-e' option causes \fItcpdump\fP to print
+the `frame control' fields, all of the addresses in the 802.11 header,
+and the packet length.
+As on FDDI networks,
+packets are assumed to contain an LLC packet.
+.LP
+\fI(N.B.: The following description assumes familiarity with
+the SLIP compression algorithm described in RFC-1144.)\fP
+.LP
+On SLIP links, a direction indicator (``I'' for inbound, ``O'' for outbound),
+packet type, and compression information are printed out.
+The packet type is printed first.
+The three types are \fIip\fP, \fIutcp\fP, and \fIctcp\fP.
+No further link information is printed for \fIip\fR packets.
+For TCP packets, the connection identifier is printed following the type.
+If the packet is compressed, its encoded header is printed out.
+The special cases are printed out as
+\fB*S+\fIn\fR and \fB*SA+\fIn\fR, where \fIn\fR is the amount by which
+the sequence number (or sequence number and ack) has changed.
+If it is not a special case,
+zero or more changes are printed.
+A change is indicated by U (urgent pointer), W (window), A (ack),
+S (sequence number), and I (packet ID), followed by a delta (+n or -n),
+or a new value (=n).
+Finally, the amount of data in the packet and compressed header length
+are printed.
+.LP
+For example, the following line shows an outbound compressed TCP packet,
+with an implicit connection identifier; the ack has changed by 6,
+the sequence number by 49, and the packet ID by 6; there are 3 bytes of
+data and 6 bytes of compressed header:
+.RS
+.nf
+\fBO ctcp * A+6 S+49 I+6 3 (6)\fP
+.fi
+.RE
+.HD
+ARP/RARP Packets
+.LP
+Arp/rarp output shows the type of request and its arguments.
+The
+format is intended to be self explanatory.
+Here is a short sample taken from the start of an `rlogin' from
+host \fIrtsg\fP to host \fIcsam\fP:
+.RS
+.nf
+.sp .5
+\f(CWarp who-has csam tell rtsg
+arp reply csam is-at CSAM\fR
+.sp .5
+.fi
+.RE
+The first line says that rtsg sent an arp packet asking
+for the Ethernet address of internet host csam.
+Csam
+replies with its Ethernet address (in this example, Ethernet addresses
+are in caps and internet addresses in lower case).
+.LP
+This would look less redundant if we had done \fItcpdump \-n\fP:
+.RS
+.nf
+.sp .5
+\f(CWarp who-has 128.3.254.6 tell 128.3.254.68
+arp reply 128.3.254.6 is-at 02:07:01:00:01:c4\fP
+.fi
+.RE
+.LP
+If we had done \fItcpdump \-e\fP, the fact that the first packet is
+broadcast and the second is point-to-point would be visible:
+.RS
+.nf
+.sp .5
+\f(CWRTSG Broadcast 0806 64: arp who-has csam tell rtsg
+CSAM RTSG 0806 64: arp reply csam is-at CSAM\fR
+.sp .5
+.fi
+.RE
+For the first packet this says the Ethernet source address is RTSG, the
+destination is the Ethernet broadcast address, the type field
+contained hex 0806 (type ETHER_ARP) and the total length was 64 bytes.
+.HD
+TCP Packets
+.LP
+\fI(N.B.:The following description assumes familiarity with
+the TCP protocol described in RFC-793.
+If you are not familiar
+with the protocol, neither this description nor \fItcpdump\fP will
+be of much use to you.)\fP
+.LP
+The general format of a tcp protocol line is:
+.RS
+.nf
+.sp .5
+\fIsrc > dst: flags data-seqno ack window urgent options\fP
+.sp .5
+.fi
+.RE
+\fISrc\fP and \fIdst\fP are the source and destination IP
+addresses and ports.
+\fIFlags\fP are some combination of S (SYN),
+F (FIN), P (PUSH), R (RST), W (ECN CWR) or E (ECN-Echo), or a single
+`.' (no flags).
+\fIData-seqno\fP describes the portion of sequence space covered
+by the data in this packet (see example below).
+\fIAck\fP is sequence number of the next data expected the other
+direction on this connection.
+\fIWindow\fP is the number of bytes of receive buffer space available
+the other direction on this connection.
+\fIUrg\fP indicates there is `urgent' data in the packet.
+\fIOptions\fP are tcp options enclosed in angle brackets (e.g., <mss 1024>).
+.LP
+\fISrc, dst\fP and \fIflags\fP are always present.
+The other fields
+depend on the contents of the packet's tcp protocol header and
+are output only if appropriate.
+.LP
+Here is the opening portion of an rlogin from host \fIrtsg\fP to
+host \fIcsam\fP.
+.RS
+.nf
+.sp .5
+\s-2\f(CWrtsg.1023 > csam.login: S 768512:768512(0) win 4096 <mss 1024>
+csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024>
+rtsg.1023 > csam.login: . ack 1 win 4096
+rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096
+csam.login > rtsg.1023: . ack 2 win 4096
+rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
+csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077
+csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1
+csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fR\s+2
+.sp .5
+.fi
+.RE
+The first line says that tcp port 1023 on rtsg sent a packet
+to port \fIlogin\fP
+on csam.
+The \fBS\fP indicates that the \fISYN\fP flag was set.
+The packet sequence number was 768512 and it contained no data.
+(The notation is `first:last(nbytes)' which means `sequence
+numbers \fIfirst\fP
+up to but not including \fIlast\fP which is \fInbytes\fP bytes of user data'.)
+There was no piggy-backed ack, the available receive window was 4096
+bytes and there was a max-segment-size option requesting an mss of
+1024 bytes.
+.LP
+Csam replies with a similar packet except it includes a piggy-backed
+ack for rtsg's SYN.
+Rtsg then acks csam's SYN.
+The `.' means no
+flags were set.
+The packet contained no data so there is no data sequence number.
+Note that the ack sequence
+number is a small integer (1).
+The first time \fItcpdump\fP sees a
+tcp `conversation', it prints the sequence number from the packet.
+On subsequent packets of the conversation, the difference between
+the current packet's sequence number and this initial sequence number
+is printed.
+This means that sequence numbers after the
+first can be interpreted
+as relative byte positions in the conversation's data stream (with the
+first data byte each direction being `1').
+`-S' will override this
+feature, causing the original sequence numbers to be output.
+.LP
+On the 6th line, rtsg sends csam 19 bytes of data (bytes 2 through 20
+in the rtsg \(-> csam side of the conversation).
+The PUSH flag is set in the packet.
+On the 7th line, csam says it's received data sent by rtsg up to
+but not including byte 21.
+Most of this data is apparently sitting in the
+socket buffer since csam's receive window has gotten 19 bytes smaller.
+Csam also sends one byte of data to rtsg in this packet.
+On the 8th and 9th lines,
+csam sends two bytes of urgent, pushed data to rtsg.
+.LP
+If the snapshot was small enough that \fItcpdump\fP didn't capture
+the full TCP header, it interprets as much of the header as it can
+and then reports ``[|\fItcp\fP]'' to indicate the remainder could not
+be interpreted.
+If the header contains a bogus option (one with a length
+that's either too small or beyond the end of the header), \fItcpdump\fP
+reports it as ``[\fIbad opt\fP]'' and does not interpret any further
+options (since it's impossible to tell where they start).
+If the header
+length indicates options are present but the IP datagram length is not
+long enough for the options to actually be there, \fItcpdump\fP reports
+it as ``[\fIbad hdr length\fP]''.
+.HD
+.B Capturing TCP packets with particular flag combinations (SYN-ACK, URG-ACK, etc.)
+.PP
+There are 8 bits in the control bits section of the TCP header:
+.IP
+.I CWR | ECE | URG | ACK | PSH | RST | SYN | FIN
+.PP
+Let's assume that we want to watch packets used in establishing
+a TCP connection.
+Recall that TCP uses a 3-way handshake protocol
+when it initializes a new connection; the connection sequence with
+regard to the TCP control bits is
+.PP
+.RS
+1) Caller sends SYN
+.RE
+.RS
+2) Recipient responds with SYN, ACK
+.RE
+.RS
+3) Caller sends ACK
+.RE
+.PP
+Now we're interested in capturing packets that have only the
+SYN bit set (Step 1).
+Note that we don't want packets from step 2
+(SYN-ACK), just a plain initial SYN.
+What we need is a correct filter
+expression for \fItcpdump\fP.
+.PP
+Recall the structure of a TCP header without options:
+.PP
+.nf
+ 0 15 31
+-----------------------------------------------------------------
+| source port | destination port |
+-----------------------------------------------------------------
+| sequence number |
+-----------------------------------------------------------------
+| acknowledgment number |
+-----------------------------------------------------------------
+| HL | rsvd |C|E|U|A|P|R|S|F| window size |
+-----------------------------------------------------------------
+| TCP checksum | urgent pointer |
+-----------------------------------------------------------------
+.fi
+.PP
+A TCP header usually holds 20 octets of data, unless options are
+present.
+The first line of the graph contains octets 0 - 3, the
+second line shows octets 4 - 7 etc.
+.PP
+Starting to count with 0, the relevant TCP control bits are contained
+in octet 13:
+.PP
+.nf
+ 0 7| 15| 23| 31
+----------------|---------------|---------------|----------------
+| HL | rsvd |C|E|U|A|P|R|S|F| window size |
+----------------|---------------|---------------|----------------
+| | 13th octet | | |
+.fi
+.PP
+Let's have a closer look at octet no. 13:
+.PP
+.nf
+ | |
+ |---------------|
+ |C|E|U|A|P|R|S|F|
+ |---------------|
+ |7 5 3 0|
+.fi
+.PP
+These are the TCP control bits we are interested
+in.
+We have numbered the bits in this octet from 0 to 7, right to
+left, so the PSH bit is bit number 3, while the URG bit is number 5.
+.PP
+Recall that we want to capture packets with only SYN set.
+Let's see what happens to octet 13 if a TCP datagram arrives
+with the SYN bit set in its header:
+.PP
+.nf
+ |C|E|U|A|P|R|S|F|
+ |---------------|
+ |0 0 0 0 0 0 1 0|
+ |---------------|
+ |7 6 5 4 3 2 1 0|
+.fi
+.PP
+Looking at the
+control bits section we see that only bit number 1 (SYN) is set.
+.PP
+Assuming that octet number 13 is an 8-bit unsigned integer in
+network byte order, the binary value of this octet is
+.IP
+00000010
+.PP
+and its decimal representation is
+.PP
+.nf
+ 7 6 5 4 3 2 1 0
+0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 1*2 + 0*2 = 2
+.fi
+.PP
+We're almost done, because now we know that if only SYN is set,
+the value of the 13th octet in the TCP header, when interpreted
+as a 8-bit unsigned integer in network byte order, must be exactly 2.
+.PP
+This relationship can be expressed as
+.RS
+.B
+tcp[13] == 2
+.RE
+.PP
+We can use this expression as the filter for \fItcpdump\fP in order
+to watch packets which have only SYN set:
+.RS
+.B
+tcpdump -i xl0 tcp[13] == 2
+.RE
+.PP
+The expression says "let the 13th octet of a TCP datagram have
+the decimal value 2", which is exactly what we want.
+.PP
+Now, let's assume that we need to capture SYN packets, but we
+don't care if ACK or any other TCP control bit is set at the
+same time.
+Let's see what happens to octet 13 when a TCP datagram
+with SYN-ACK set arrives:
+.PP
+.nf
+ |C|E|U|A|P|R|S|F|
+ |---------------|
+ |0 0 0 1 0 0 1 0|
+ |---------------|
+ |7 6 5 4 3 2 1 0|
+.fi
+.PP
+Now bits 1 and 4 are set in the 13th octet.
+The binary value of
+octet 13 is
+.IP
+ 00010010
+.PP
+which translates to decimal
+.PP
+.nf
+ 7 6 5 4 3 2 1 0
+0*2 + 0*2 + 0*2 + 1*2 + 0*2 + 0*2 + 1*2 + 0*2 = 18
+.fi
+.PP
+Now we can't just use 'tcp[13] == 18' in the \fItcpdump\fP filter
+expression, because that would select only those packets that have
+SYN-ACK set, but not those with only SYN set.
+Remember that we don't care
+if ACK or any other control bit is set as long as SYN is set.
+.PP
+In order to achieve our goal, we need to logically AND the
+binary value of octet 13 with some other value to preserve
+the SYN bit.
+We know that we want SYN to be set in any case,
+so we'll logically AND the value in the 13th octet with
+the binary value of a SYN:
+.PP
+.nf
+
+ 00010010 SYN-ACK 00000010 SYN
+ AND 00000010 (we want SYN) AND 00000010 (we want SYN)
+ -------- --------
+ = 00000010 = 00000010
+.fi
+.PP
+We see that this AND operation delivers the same result
+regardless whether ACK or another TCP control bit is set.
+The decimal representation of the AND value as well as
+the result of this operation is 2 (binary 00000010),
+so we know that for packets with SYN set the following
+relation must hold true:
+.IP
+( ( value of octet 13 ) AND ( 2 ) ) == ( 2 )
+.PP
+This points us to the \fItcpdump\fP filter expression
+.RS
+.B
+ tcpdump -i xl0 'tcp[13] & 2 == 2'
+.RE
+.PP
+Some offsets and field values may be expressed as names
+rather than as numeric values. For example tcp[13] may
+be replaced with tcp[tcpflags]. The following TCP flag
+field values are also available: tcp-fin, tcp-syn, tcp-rst,
+tcp-push, tcp-act, tcp-urg.
+.PP
+This can be demonstrated as:
+.RS
+.B
+ tcpdump -i xl0 'tcp[tcpflags] & tcp-push != 0'
+.RE
+.PP
+Note that you should use single quotes or a backslash
+in the expression to hide the AND ('&') special character
+from the shell.
+.HD
+.B
+UDP Packets
+.LP
+UDP format is illustrated by this rwho packet:
+.RS
+.nf
+.sp .5
+\f(CWactinide.who > broadcast.who: udp 84\fP
+.sp .5
+.fi
+.RE
+This says that port \fIwho\fP on host \fIactinide\fP sent a udp
+datagram to port \fIwho\fP on host \fIbroadcast\fP, the Internet
+broadcast address.
+The packet contained 84 bytes of user data.
+.LP
+Some UDP services are recognized (from the source or destination
+port number) and the higher level protocol information printed.
+In particular, Domain Name service requests (RFC-1034/1035) and Sun
+RPC calls (RFC-1050) to NFS.
+.HD
+UDP Name Server Requests
+.LP
+\fI(N.B.:The following description assumes familiarity with
+the Domain Service protocol described in RFC-1035.
+If you are not familiar
+with the protocol, the following description will appear to be written
+in greek.)\fP
+.LP
+Name server requests are formatted as
+.RS
+.nf
+.sp .5
+\fIsrc > dst: id op? flags qtype qclass name (len)\fP
+.sp .5
+\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fR
+.sp .5
+.fi
+.RE
+Host \fIh2opolo\fP asked the domain server on \fIhelios\fP for an
+address record (qtype=A) associated with the name \fIucbvax.berkeley.edu.\fP
+The query id was `3'.
+The `+' indicates the \fIrecursion desired\fP flag
+was set.
+The query length was 37 bytes, not including the UDP and
+IP protocol headers.
+The query operation was the normal one, \fIQuery\fP,
+so the op field was omitted.
+If the op had been anything else, it would
+have been printed between the `3' and the `+'.
+Similarly, the qclass was the normal one,
+\fIC_IN\fP, and omitted.
+Any other qclass would have been printed
+immediately after the `A'.
+.LP
+A few anomalies are checked and may result in extra fields enclosed in
+square brackets: If a query contains an answer, authority records or
+additional records section,
+.IR ancount ,
+.IR nscount ,
+or
+.I arcount
+are printed as `[\fIn\fPa]', `[\fIn\fPn]' or `[\fIn\fPau]' where \fIn\fP
+is the appropriate count.
+If any of the response bits are set (AA, RA or rcode) or any of the
+`must be zero' bits are set in bytes two and three, `[b2&3=\fIx\fP]'
+is printed, where \fIx\fP is the hex value of header bytes two and three.
+.HD
+UDP Name Server Responses
+.LP
+Name server responses are formatted as
+.RS
+.nf
+.sp .5
+\fIsrc > dst: id op rcode flags a/n/au type class data (len)\fP
+.sp .5
+\f(CWhelios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273)
+helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fR
+.sp .5
+.fi
+.RE
+In the first example, \fIhelios\fP responds to query id 3 from \fIh2opolo\fP
+with 3 answer records, 3 name server records and 7 additional records.
+The first answer record is type A (address) and its data is internet
+address 128.32.137.3.
+The total size of the response was 273 bytes,
+excluding UDP and IP headers.
+The op (Query) and response code
+(NoError) were omitted, as was the class (C_IN) of the A record.
+.LP
+In the second example, \fIhelios\fP responds to query 2 with a
+response code of non-existent domain (NXDomain) with no answers,
+one name server and no authority records.
+The `*' indicates that
+the \fIauthoritative answer\fP bit was set.
+Since there were no
+answers, no type, class or data were printed.
+.LP
+Other flag characters that might appear are `\-' (recursion available,
+RA, \fInot\fP set) and `|' (truncated message, TC, set).
+If the
+`question' section doesn't contain exactly one entry, `[\fIn\fPq]'
+is printed.
+
+.HD
+SMB/CIFS decoding
+.LP
+\fItcpdump\fP now includes fairly extensive SMB/CIFS/NBT decoding for data
+on UDP/137, UDP/138 and TCP/139.
+Some primitive decoding of IPX and
+NetBEUI SMB data is also done.
+
+By default a fairly minimal decode is done, with a much more detailed
+decode done if -v is used.
+Be warned that with -v a single SMB packet
+may take up a page or more, so only use -v if you really want all the
+gory details.
+
+For information on SMB packet formats and what all te fields mean see
+www.cifs.org or the pub/samba/specs/ directory on your favorite
+samba.org mirror site.
+The SMB patches were written by Andrew Tridgell
+(tridge@samba.org).
+
+.HD
+NFS Requests and Replies
+.LP
+Sun NFS (Network File System) requests and replies are printed as:
+.RS
+.nf
+.sp .5
+\fIsrc.xid > dst.nfs: len op args\fP
+\fIsrc.nfs > dst.xid: reply stat len op results\fP
+.sp .5
+\f(CW
+sushi.6709 > wrl.nfs: 112 readlink fh 21,24/10.73165
+wrl.nfs > sushi.6709: reply ok 40 readlink "../var"
+sushi.201b > wrl.nfs:
+ 144 lookup fh 9,74/4096.6878 "xcolors"
+wrl.nfs > sushi.201b:
+ reply ok 128 lookup fh 9,74/4134.3150
+\fR
+.sp .5
+.fi
+.RE
+In the first line, host \fIsushi\fP sends a transaction with id \fI6709\fP
+to \fIwrl\fP (note that the number following the src host is a
+transaction id, \fInot\fP the source port).
+The request was 112 bytes,
+excluding the UDP and IP headers.
+The operation was a \fIreadlink\fP
+(read symbolic link) on file handle (\fIfh\fP) 21,24/10.731657119.
+(If one is lucky, as in this case, the file handle can be interpreted
+as a major,minor device number pair, followed by the inode number and
+generation number.)
+\fIWrl\fP replies `ok' with the contents of the link.
+.LP
+In the third line, \fIsushi\fP asks \fIwrl\fP to lookup the name
+`\fIxcolors\fP' in directory file 9,74/4096.6878.
+Note that the data printed
+depends on the operation type.
+The format is intended to be self
+explanatory if read in conjunction with
+an NFS protocol spec.
+.LP
+If the \-v (verbose) flag is given, additional information is printed.
+For example:
+.RS
+.nf
+.sp .5
+\f(CW
+sushi.1372a > wrl.nfs:
+ 148 read fh 21,11/12.195 8192 bytes @ 24576
+wrl.nfs > sushi.1372a:
+ reply ok 1472 read REG 100664 ids 417/0 sz 29388
+\fP
+.sp .5
+.fi
+.RE
+(\-v also prints the IP header TTL, ID, length, and fragmentation fields,
+which have been omitted from this example.) In the first line,
+\fIsushi\fP asks \fIwrl\fP to read 8192 bytes from file 21,11/12.195,
+at byte offset 24576.
+\fIWrl\fP replies `ok'; the packet shown on the
+second line is the first fragment of the reply, and hence is only 1472
+bytes long (the other bytes will follow in subsequent fragments, but
+these fragments do not have NFS or even UDP headers and so might not be
+printed, depending on the filter expression used).
+Because the \-v flag
+is given, some of the file attributes (which are returned in addition
+to the file data) are printed: the file type (``REG'', for regular file),
+the file mode (in octal), the uid and gid, and the file size.
+.LP
+If the \-v flag is given more than once, even more details are printed.
+.LP
+Note that NFS requests are very large and much of the detail won't be printed
+unless \fIsnaplen\fP is increased.
+Try using `\fB\-s 192\fP' to watch
+NFS traffic.
+.LP
+NFS reply packets do not explicitly identify the RPC operation.
+Instead,
+\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the
+replies using the transaction ID.
+If a reply does not closely follow the
+corresponding request, it might not be parsable.
+.HD
+AFS Requests and Replies
+.LP
+Transarc AFS (Andrew File System) requests and replies are printed
+as:
+.HD
+.RS
+.nf
+.sp .5
+\fIsrc.sport > dst.dport: rx packet-type\fP
+\fIsrc.sport > dst.dport: rx packet-type service call call-name args\fP
+\fIsrc.sport > dst.dport: rx packet-type service reply call-name args\fP
+.sp .5
+\f(CW
+elvis.7001 > pike.afsfs:
+ rx data fs call rename old fid 536876964/1/1 ".newsrc.new"
+ new fid 536876964/1/1 ".newsrc"
+pike.afsfs > elvis.7001: rx data fs reply rename
+\fR
+.sp .5
+.fi
+.RE
+In the first line, host elvis sends a RX packet to pike.
+This was
+a RX data packet to the fs (fileserver) service, and is the start of
+an RPC call.
+The RPC call was a rename, with the old directory file id
+of 536876964/1/1 and an old filename of `.newsrc.new', and a new directory
+file id of 536876964/1/1 and a new filename of `.newsrc'.
+The host pike
+responds with a RPC reply to the rename call (which was successful, because
+it was a data packet and not an abort packet).
+.LP
+In general, all AFS RPCs are decoded at least by RPC call name.
+Most
+AFS RPCs have at least some of the arguments decoded (generally only
+the `interesting' arguments, for some definition of interesting).
+.LP
+The format is intended to be self-describing, but it will probably
+not be useful to people who are not familiar with the workings of
+AFS and RX.
+.LP
+If the -v (verbose) flag is given twice, acknowledgement packets and
+additional header information is printed, such as the the RX call ID,
+call number, sequence number, serial number, and the RX packet flags.
+.LP
+If the -v flag is given twice, additional information is printed,
+such as the the RX call ID, serial number, and the RX packet flags.
+The MTU negotiation information is also printed from RX ack packets.
+.LP
+If the -v flag is given three times, the security index and service id
+are printed.
+.LP
+Error codes are printed for abort packets, with the exception of Ubik
+beacon packets (because abort packets are used to signify a yes vote
+for the Ubik protocol).
+.LP
+Note that AFS requests are very large and many of the arguments won't
+be printed unless \fIsnaplen\fP is increased.
+Try using `\fB-s 256\fP'
+to watch AFS traffic.
+.LP
+AFS reply packets do not explicitly identify the RPC operation.
+Instead,
+\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the
+replies using the call number and service ID.
+If a reply does not closely
+follow the
+corresponding request, it might not be parsable.
+
+.HD
+KIP AppleTalk (DDP in UDP)
+.LP
+AppleTalk DDP packets encapsulated in UDP datagrams are de-encapsulated
+and dumped as DDP packets (i.e., all the UDP header information is
+discarded).
+The file
+.I /etc/atalk.names
+is used to translate AppleTalk net and node numbers to names.
+Lines in this file have the form
+.RS
+.nf
+.sp .5
+\fInumber name\fP
+
+\f(CW1.254 ether
+16.1 icsd-net
+1.254.110 ace\fR
+.sp .5
+.fi
+.RE
+The first two lines give the names of AppleTalk networks.
+The third
+line gives the name of a particular host (a host is distinguished
+from a net by the 3rd octet in the number \-
+a net number \fImust\fP have two octets and a host number \fImust\fP
+have three octets.) The number and name should be separated by
+whitespace (blanks or tabs).
+The
+.I /etc/atalk.names
+file may contain blank lines or comment lines (lines starting with
+a `#').
+.LP
+AppleTalk addresses are printed in the form
+.RS
+.nf
+.sp .5
+\fInet.host.port\fP
+
+\f(CW144.1.209.2 > icsd-net.112.220
+office.2 > icsd-net.112.220
+jssmag.149.235 > icsd-net.2\fR
+.sp .5
+.fi
+.RE
+(If the
+.I /etc/atalk.names
+doesn't exist or doesn't contain an entry for some AppleTalk
+host/net number, addresses are printed in numeric form.)
+In the first example, NBP (DDP port 2) on net 144.1 node 209
+is sending to whatever is listening on port 220 of net icsd node 112.
+The second line is the same except the full name of the source node
+is known (`office').
+The third line is a send from port 235 on
+net jssmag node 149 to broadcast on the icsd-net NBP port (note that
+the broadcast address (255) is indicated by a net name with no host
+number \- for this reason it's a good idea to keep node names and
+net names distinct in /etc/atalk.names).
+.LP
+NBP (name binding protocol) and ATP (AppleTalk transaction protocol)
+packets have their contents interpreted.
+Other protocols just dump
+the protocol name (or number if no name is registered for the
+protocol) and packet size.
+
+\fBNBP packets\fP are formatted like the following examples:
+.RS
+.nf
+.sp .5
+\s-2\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*"
+jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250
+techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fR\s+2
+.sp .5
+.fi
+.RE
+The first line is a name lookup request for laserwriters sent by net icsd host
+112 and broadcast on net jssmag.
+The nbp id for the lookup is 190.
+The second line shows a reply for this request (note that it has the
+same id) from host jssmag.209 saying that it has a laserwriter
+resource named "RM1140" registered on port 250.
+The third line is
+another reply to the same request saying host techpit has laserwriter
+"techpit" registered on port 186.
+
+\fBATP packet\fP formatting is demonstrated by the following example:
+.RS
+.nf
+.sp .5
+\s-2\f(CWjssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001
+helios.132 > jssmag.209.165: atp-resp 12266:0 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:1 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:2 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:4 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:6 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp*12266:7 (512) 0xae040000
+jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001
+helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
+jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001
+jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fR\s+2
+.sp .5
+.fi
+.RE
+Jssmag.209 initiates transaction id 12266 with host helios by requesting
+up to 8 packets (the `<0-7>').
+The hex number at the end of the line
+is the value of the `userdata' field in the request.
+.LP
+Helios responds with 8 512-byte packets.
+The `:digit' following the
+transaction id gives the packet sequence number in the transaction
+and the number in parens is the amount of data in the packet,
+excluding the atp header.
+The `*' on packet 7 indicates that the
+EOM bit was set.
+.LP
+Jssmag.209 then requests that packets 3 & 5 be retransmitted.
+Helios
+resends them then jssmag.209 releases the transaction.
+Finally,
+jssmag.209 initiates the next request.
+The `*' on the request
+indicates that XO (`exactly once') was \fInot\fP set.
+
+.HD
+IP Fragmentation
+.LP
+Fragmented Internet datagrams are printed as
+.RS
+.nf
+.sp .5
+\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB+)\fR
+\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB)\fR
+.sp .5
+.fi
+.RE
+(The first form indicates there are more fragments.
+The second
+indicates this is the last fragment.)
+.LP
+\fIId\fP is the fragment id.
+\fISize\fP is the fragment
+size (in bytes) excluding the IP header.
+\fIOffset\fP is this
+fragment's offset (in bytes) in the original datagram.
+.LP
+The fragment information is output for each fragment.
+The first
+fragment contains the higher level protocol header and the frag
+info is printed after the protocol info.
+Fragments
+after the first contain no higher level protocol header and the
+frag info is printed after the source and destination addresses.
+For example, here is part of an ftp from arizona.edu to lbl-rtsg.arpa
+over a CSNET connection that doesn't appear to handle 576 byte datagrams:
+.RS
+.nf
+.sp .5
+\s-2\f(CWarizona.ftp-data > rtsg.1170: . 1024:1332(308) ack 1 win 4096 (frag 595a:328@0+)
+arizona > rtsg: (frag 595a:204@328)
+rtsg.1170 > arizona.ftp-data: . ack 1536 win 2560\fP\s+2
+.sp .5
+.fi
+.RE
+There are a couple of things to note here: First, addresses in the
+2nd line don't include port numbers.
+This is because the TCP
+protocol information is all in the first fragment and we have no idea
+what the port or sequence numbers are when we print the later fragments.
+Second, the tcp sequence information in the first line is printed as if there
+were 308 bytes of user data when, in fact, there are 512 bytes (308 in
+the first frag and 204 in the second).
+If you are looking for holes
+in the sequence space or trying to match up acks
+with packets, this can fool you.
+.LP
+A packet with the IP \fIdon't fragment\fP flag is marked with a
+trailing \fB(DF)\fP.
+.HD
+Timestamps
+.LP
+By default, all output lines are preceded by a timestamp.
+The timestamp
+is the current clock time in the form
+.RS
+.nf
+\fIhh:mm:ss.frac\fP
+.fi
+.RE
+and is as accurate as the kernel's clock.
+The timestamp reflects the time the kernel first saw the packet.
+No attempt
+is made to account for the time lag between when the
+Ethernet interface removed the packet from the wire and when the kernel
+serviced the `new packet' interrupt.
+.SH "SEE ALSO"
+stty(1), pcap(3PCAP), bpf(4), nit(4P), pcap-savefile(5),
+pcap-filter(7)
+.SH AUTHORS
+The original authors are:
+.LP
+Van Jacobson,
+Craig Leres and
+Steven McCanne, all of the
+Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
+.LP
+It is currently being maintained by tcpdump.org.
+.LP
+The current version is available via http:
+.LP
+.RS
+.I http://www.tcpdump.org/
+.RE
+.LP
+The original distribution is available via anonymous ftp:
+.LP
+.RS
+.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
+.RE
+.LP
+IPv6/IPsec support is added by WIDE/KAME project.
+This program uses Eric Young's SSLeay library, under specific configurations.
+.SH BUGS
+Please send problems, bugs, questions, desirable enhancements, patches
+etc. to:
+.LP
+.RS
+tcpdump-workers@lists.tcpdump.org
+.RE
+.LP
+NIT doesn't let you watch your own outbound traffic, BPF will.
+We recommend that you use the latter.
+.LP
+On Linux systems with 2.0[.x] kernels:
+.IP
+packets on the loopback device will be seen twice;
+.IP
+packet filtering cannot be done in the kernel, so that all packets must
+be copied from the kernel in order to be filtered in user mode;
+.IP
+all of a packet, not just the part that's within the snapshot length,
+will be copied from the kernel (the 2.0[.x] packet capture mechanism, if
+asked to copy only part of a packet to userland, will not report the
+true length of the packet; this would cause most IP packets to get an
+error from
+.BR tcpdump );
+.IP
+capturing on some PPP devices won't work correctly.
+.LP
+We recommend that you upgrade to a 2.2 or later kernel.
+.LP
+Some attempt should be made to reassemble IP fragments or, at least
+to compute the right length for the higher level protocol.
+.LP
+Name server inverse queries are not dumped correctly: the (empty)
+question section is printed rather than real query in the answer
+section.
+Some believe that inverse queries are themselves a bug and
+prefer to fix the program generating them rather than \fItcpdump\fP.
+.LP
+A packet trace that crosses a daylight savings time change will give
+skewed time stamps (the time change is ignored).
+.LP
+Filter expressions on fields other than those in Token Ring headers will
+not correctly handle source-routed Token Ring packets.
+.LP
+Filter expressions on fields other than those in 802.11 headers will not
+correctly handle 802.11 data packets with both To DS and From DS set.
+.LP
+.BR "ip6 proto"
+should chase header chain, but at this moment it does not.
+.BR "ip6 protochain"
+is supplied for this behavior.
+.LP
+Arithmetic expression against transport layer headers, like \fBtcp[0]\fP,
+does not work against IPv6 packets.
+It only looks at IPv4 packets.
OpenPOWER on IntegriCloud