diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/stdtime/strptime.c | 9 | ||||
-rw-r--r-- | lib/libc/string/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/string/Symbol.map | 4 | ||||
-rw-r--r-- | lib/libc/string/bzero.3 | 20 | ||||
-rw-r--r-- | lib/libc/string/explicit_bzero.c | 22 | ||||
-rw-r--r-- | lib/libpcap/Makefile | 1 | ||||
-rw-r--r-- | lib/libpcap/config.h | 3 | ||||
-rw-r--r-- | lib/libpcap/pcap-netmap.c | 283 |
8 files changed, 337 insertions, 9 deletions
diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c index 55c9960..2be6358 100644 --- a/lib/libc/stdtime/strptime.c +++ b/lib/libc/stdtime/strptime.c @@ -103,9 +103,6 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, ptr = fmt; while (*ptr != 0) { - if (*buf == 0) - break; - c = *ptr++; if (c != '%') { @@ -123,7 +120,6 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, label: c = *ptr++; switch (c) { - case 0: case '%': if (*buf++ != '%') return (NULL); @@ -600,6 +596,9 @@ label: while (isspace_l((unsigned char)*buf, locale)) buf++; break; + + default: + return (NULL); } } @@ -676,8 +675,6 @@ strptime_l(const char * __restrict buf, const char * __restrict fmt, if (ret && gmt) { time_t t = timegm(tm); - if (t == -1) - return (NULL); localtime_r(&t, tm); } diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index 731f4fc..385837c 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -6,7 +6,8 @@ CFLAGS+= -I${LIBC_SRCTOP}/locale # machine-independent string sources -MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c ffsll.c fls.c flsl.c flsll.c \ +MISRCS+=bcmp.c bcopy.c bzero.c explicit_bzero.c \ + ffs.c ffsl.c ffsll.c fls.c flsl.c flsll.c \ memccpy.c memchr.c memrchr.c memcmp.c \ memcpy.c memmem.c memmove.c memset.c \ stpcpy.c stpncpy.c strcasecmp.c \ @@ -35,6 +36,7 @@ MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wcscoll.3 wcstok.3 \ wcswidth.3 wcsxfrm.3 wmemchr.3 +MLINKS+=bzero.3 explicit_bzero.3 MLINKS+=ffs.3 ffsl.3 \ ffs.3 ffsll.3 \ ffs.3 fls.3 \ diff --git a/lib/libc/string/Symbol.map b/lib/libc/string/Symbol.map index 8e80165..5961092 100644 --- a/lib/libc/string/Symbol.map +++ b/lib/libc/string/Symbol.map @@ -100,6 +100,10 @@ FBSD_1.3 { wcwidth_l; }; +FBSD_1.4 { + explicit_bzero; +}; + FBSDprivate_1.0 { __strtok_r; }; diff --git a/lib/libc/string/bzero.3 b/lib/libc/string/bzero.3 index 029644a..5af1bcf 100644 --- a/lib/libc/string/bzero.3 +++ b/lib/libc/string/bzero.3 @@ -31,11 +31,12 @@ .\" @(#)bzero.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd October 6, 2014 .Dt BZERO 3 .Os .Sh NAME -.Nm bzero +.Nm bzero , +.Nm explicit_bzero .Nd write zeroes to a byte string .Sh LIBRARY .Lb libc @@ -43,6 +44,8 @@ .In strings.h .Ft void .Fn bzero "void *b" "size_t len" +.Ft void +.Fn explicit_bzero "void *b" "size_t len" .Sh DESCRIPTION The .Fn bzero @@ -56,6 +59,12 @@ If is zero, .Fn bzero does nothing. +.Pp +The +.Fn explicit_bzero +variant behaves the same, but will not be removed by a compiler's dead store +optimization pass, making it useful for clearing sensitive memory such as a +password. .Sh SEE ALSO .Xr memset 3 , .Xr swab 3 @@ -72,3 +81,10 @@ before it was moved to for .St -p1003.1-2001 compliance. +.Pp +The +.Fn explicit_bzero +function first appeared in +.Ox 5.5 +and +.Fx 11.0 . diff --git a/lib/libc/string/explicit_bzero.c b/lib/libc/string/explicit_bzero.c new file mode 100644 index 0000000..a7811b0 --- /dev/null +++ b/lib/libc/string/explicit_bzero.c @@ -0,0 +1,22 @@ +/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */ +/* + * Public domain. + * Written by Matthew Dempsky. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <string.h> + +__attribute__((weak)) void +__explicit_bzero_hook(void *buf, size_t len) +{ +} + +void +explicit_bzero(void *buf, size_t len) +{ + memset(buf, 0, len); + __explicit_bzero_hook(buf, len); +} diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile index 8cae1f1..11d7f73 100644 --- a/lib/libpcap/Makefile +++ b/lib/libpcap/Makefile @@ -7,6 +7,7 @@ SHLIBDIR?= /lib LIB= pcap SRCS= grammar.y tokdefs.h version.h pcap-bpf.c \ + pcap-netmap.c \ pcap.c pcap-common.c inet.c fad-getad.c gencode.c optimize.c nametoaddr.c \ etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c \ scanner.l sf-pcap.c sf-pcap-ng.c version.c diff --git a/lib/libpcap/config.h b/lib/libpcap/config.h index 79cb3d2..60cb448 100644 --- a/lib/libpcap/config.h +++ b/lib/libpcap/config.h @@ -271,6 +271,9 @@ /* target host supports USB sniffing */ /* #undef PCAP_SUPPORT_USB */ +/* target host supports netmap */ +#define PCAP_SUPPORT_NETMAP 1 + /* include ACN support */ /* #undef SITA */ diff --git a/lib/libpcap/pcap-netmap.c b/lib/libpcap/pcap-netmap.c new file mode 100644 index 0000000..309cf63 --- /dev/null +++ b/lib/libpcap/pcap-netmap.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2014 Luigi Rizzo. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <poll.h> +#include <ctype.h> +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define NETMAP_WITH_LIBS +#include <net/netmap_user.h> + +#include "pcap-int.h" + +/* + * $FreeBSD$ + * + * This code is meant to build also on other versions of libpcap. + * + * older libpcap miss p->priv, use p->md.device instead (and allocate). + * Also opt.timeout was in md.timeout before. + * Use #define PCAP_IF_UP to discriminate + */ +#ifdef PCAP_IF_UP +#define NM_PRIV(p) ((struct pcap_netmap *)(p->priv)) +#define the_timeout opt.timeout +#else +#define HAVE_NO_PRIV +#define NM_PRIV(p) ((struct pcap_netmap *)(p->md.device)) +#define SET_PRIV(p, x) p->md.device = (void *)x +#define the_timeout md.timeout +#endif + +#if defined (linux) +/* On FreeBSD we use IFF_PPROMISC which is in ifr_flagshigh. + * remap to IFF_PROMISC on linux + */ +#define IFF_PPROMISC IFF_PROMISC +#endif /* linux */ + +struct pcap_netmap { + struct nm_desc *d; /* pointer returned by nm_open() */ + pcap_handler cb; /* callback and argument */ + u_char *cb_arg; + int must_clear_promisc; /* flag */ + uint64_t rx_pkts; /* # of pkts received before the filter */ +}; + + +static int +pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps) +{ + struct pcap_netmap *pn = NM_PRIV(p); + + ps->ps_recv = pn->rx_pkts; + ps->ps_drop = 0; + ps->ps_ifdrop = 0; + return 0; +} + + +static void +pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf) +{ + pcap_t *p = (pcap_t *)arg; + struct pcap_netmap *pn = NM_PRIV(p); + const struct bpf_insn *pc = p->fcode.bf_insns; + + ++pn->rx_pkts; + if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen)) + pn->cb(pn->cb_arg, h, buf); +} + + +static int +pcap_netmap_dispatch(pcap_t *p, int cnt, pcap_handler cb, u_char *user) +{ + int ret; + struct pcap_netmap *pn = NM_PRIV(p); + struct nm_desc *d = pn->d; + struct pollfd pfd = { .fd = p->fd, .events = POLLIN, .revents = 0 }; + + pn->cb = cb; + pn->cb_arg = user; + + for (;;) { + if (p->break_loop) { + p->break_loop = 0; + return PCAP_ERROR_BREAK; + } + /* nm_dispatch won't run forever */ + + ret = nm_dispatch((void *)d, cnt, (void *)pcap_netmap_filter, (void *)p); + if (ret != 0) + break; + errno = 0; + ret = poll(&pfd, 1, p->the_timeout); + } + return ret; +} + + +/* XXX need to check the NIOCTXSYNC/poll */ +static int +pcap_netmap_inject(pcap_t *p, const void *buf, size_t size) +{ + struct nm_desc *d = NM_PRIV(p)->d; + + return nm_inject(d, buf, size); +} + + +static int +pcap_netmap_ioctl(pcap_t *p, u_long what, uint32_t *if_flags) +{ + struct pcap_netmap *pn = NM_PRIV(p); + struct nm_desc *d = pn->d; + struct ifreq ifr; + int error, fd = d->fd; + +#ifdef linux + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + fprintf(stderr, "Error: cannot get device control socket.\n"); + return -1; + } +#endif /* linux */ + bzero(&ifr, sizeof(ifr)); + strncpy(ifr.ifr_name, d->req.nr_name, sizeof(ifr.ifr_name)); + switch (what) { + case SIOCSIFFLAGS: + ifr.ifr_flags = *if_flags; +#ifdef __FreeBSD__ + ifr.ifr_flagshigh = *if_flags >> 16; +#endif /* __FreeBSD__ */ + break; + } + error = ioctl(fd, what, &ifr); + if (!error) { + switch (what) { + case SIOCGIFFLAGS: + *if_flags = ifr.ifr_flags; +#ifdef __FreeBSD__ + *if_flags |= (ifr.ifr_flagshigh << 16); +#endif /* __FreeBSD__ */ + } + } +#ifdef linux + close(fd); +#endif /* linux */ + return error ? -1 : 0; +} + + +static void +pcap_netmap_close(pcap_t *p) +{ + struct pcap_netmap *pn = NM_PRIV(p); + struct nm_desc *d = pn->d; + uint32_t if_flags = 0; + + if (pn->must_clear_promisc) { + pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */ + if (if_flags & IFF_PPROMISC) { + if_flags &= ~IFF_PPROMISC; + pcap_netmap_ioctl(p, SIOCSIFFLAGS, &if_flags); + } + } + nm_close(d); +#ifdef HAVE_NO_PRIV + free(pn); + SET_PRIV(p, NULL); // unnecessary +#endif + pcap_cleanup_live_common(p); +} + + +static int +pcap_netmap_activate(pcap_t *p) +{ + struct pcap_netmap *pn = NM_PRIV(p); + struct nm_desc *d = nm_open(p->opt.source, NULL, 0, NULL); + uint32_t if_flags = 0; + + if (d == NULL) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "netmap open: cannot access %s: %s\n", + p->opt.source, pcap_strerror(errno)); +#ifdef HAVE_NO_PRIV + free(pn); + SET_PRIV(p, NULL); // unnecessary +#endif + pcap_cleanup_live_common(p); + return (PCAP_ERROR); + } + if (0) + fprintf(stderr, "%s device %s priv %p fd %d ports %d..%d\n", + __FUNCTION__, p->opt.source, d, d->fd, + d->first_rx_ring, d->last_rx_ring); + pn->d = d; + p->fd = d->fd; + if (p->opt.promisc && !(d->req.nr_ringid & NETMAP_SW_RING)) { + pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */ + if (!(if_flags & IFF_PPROMISC)) { + pn->must_clear_promisc = 1; + if_flags |= IFF_PPROMISC; + pcap_netmap_ioctl(p, SIOCSIFFLAGS, &if_flags); + } + } + p->linktype = DLT_EN10MB; + p->selectable_fd = p->fd; + p->read_op = pcap_netmap_dispatch; + p->inject_op = pcap_netmap_inject, + p->setfilter_op = install_bpf_program; + p->setdirection_op = NULL; + p->set_datalink_op = NULL; + p->getnonblock_op = pcap_getnonblock_fd; + p->setnonblock_op = pcap_setnonblock_fd; + p->stats_op = pcap_netmap_stats; + p->cleanup_op = pcap_netmap_close; + + return (0); +} + + +pcap_t * +pcap_netmap_create(const char *device, char *ebuf, int *is_ours) +{ + pcap_t *p; + + *is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4)); + if (! *is_ours) + return NULL; +#ifdef HAVE_NO_PRIV + { + void *pn = calloc(1, sizeof(struct pcap_netmap)); + if (pn == NULL) + return NULL; + p = pcap_create_common(device, ebuf); + if (p == NULL) { + free(pn); + return NULL; + } + SET_PRIV(p, pn); + } +#else + p = pcap_create_common(device, ebuf, sizeof (struct pcap_netmap)); + if (p == NULL) + return (NULL); +#endif + p->activate_op = pcap_netmap_activate; + return (p); +} |