diff options
author | dim <dim@FreeBSD.org> | 2010-11-01 22:11:18 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-11-01 22:11:18 +0000 |
commit | 04d5797c20a5e7f5811ee5653a8bd4fa9300325d (patch) | |
tree | 45cdf1680ec076c4c54b758b1c55a767bb75694b /usr.sbin | |
parent | 2b41f57ec24828271cbc72256afbf6947f14fac0 (diff) | |
parent | 71407681fdd1b75689f0d0a1e99666c0b45dfc6a (diff) | |
download | FreeBSD-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.c | 332 | ||||
-rw-r--r-- | usr.sbin/config/main.c | 27 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_config.c | 91 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_drive.c | 56 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_evt.c | 32 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_flash.c | 23 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_patrol.c | 52 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_show.c | 60 | ||||
-rw-r--r-- | usr.sbin/mfiutil/mfi_volume.c | 40 | ||||
-rwxr-xr-x | usr.sbin/pc-sysinstall/backend-query/disk-info.sh | 2 | ||||
-rw-r--r-- | usr.sbin/rtadvd/rtadvd.conf.5 | 4 | ||||
-rw-r--r-- | usr.sbin/tcpdump/tcpdump/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/tcpdump/tcpdump/config.h | 93 | ||||
-rw-r--r-- | usr.sbin/tcpdump/tcpdump/tcpdump.1 | 1722 |
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. |