/* * Copyright (c) 2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Copyright (c) 2005-2008 Jelmer Vernooij * Copyright (C) 2006-2014 Stefan Metzmacher * Copyright (C) 2013-2014 Andreas Schneider * * 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. * * 3. Neither the name of the author 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 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. * */ /* Socket wrapper library. Passes all socket communication over unix domain sockets if the environment variable SOCKET_WRAPPER_DIR is set. */ #include #include #include #include #include #include #include enum swrap_dbglvl_e { SWRAP_LOG_ERROR = 0, SWRAP_LOG_WARN, SWRAP_LOG_DEBUG, SWRAP_LOG_TRACE }; /* Macros for accessing mutexes */ #define SWRAP_LOCK(m) do { \ pthread_mutex_lock(&(m ## _mutex)); \ } while(0) #define SWRAP_UNLOCK(m) do { \ pthread_mutex_unlock(&(m ## _mutex)); \ } while(0) /* Add new global locks here please */ #define SWRAP_LOCK_ALL \ SWRAP_LOCK(libc_symbol_binding); \ #define SWRAP_UNLOCK_ALL \ SWRAP_UNLOCK(libc_symbol_binding); \ /* The mutex for accessing the global libc.symbols */ static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER; /* Function prototypes */ #ifdef NDEBUG #define SWRAP_LOG(...) #else static unsigned int swrap_log_lvl = SWRAP_LOG_WARN; static void swrap_log (enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE (3, 4); #define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__) static void swrap_log (enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) { char buffer[1024]; va_list va; va_start (va, format); vsnprintf (buffer, sizeof (buffer), format, va); va_end (va); if (dbglvl <= swrap_log_lvl) { switch (dbglvl) { case SWRAP_LOG_ERROR: fprintf (stderr, "SWRAP_ERROR(%d) - %s: %s\n", (int) getpid (), func, buffer); break; case SWRAP_LOG_WARN: fprintf (stderr, "SWRAP_WARN(%d) - %s: %s\n", (int) getpid (), func, buffer); break; case SWRAP_LOG_DEBUG: fprintf (stderr, "SWRAP_DEBUG(%d) - %s: %s\n", (int) getpid (), func, buffer); break; case SWRAP_LOG_TRACE: fprintf (stderr, "SWRAP_TRACE(%d) - %s: %s\n", (int) getpid (), func, buffer); break; } } } #endif /********************************************************* * SWRAP LOADING LIBC FUNCTIONS *********************************************************/ typedef int (*__libc_accept4) (int sockfd, struct sockaddr * addr, socklen_t * addrlen, int flags); typedef int (*__libc_accept) (int sockfd, struct sockaddr * addr, socklen_t * addrlen); typedef int (*__libc_bind) (int sockfd, const struct sockaddr * addr, socklen_t addrlen); typedef int (*__libc_close) (int fd); typedef int (*__libc_connect) (int sockfd, const struct sockaddr * addr, socklen_t addrlen); #if 0 /* TBD: dup and dup2 to be implemented later */ typedef int (*__libc_dup) (int fd); typedef int (*__libc_dup2) (int oldfd, int newfd); #endif typedef int (*__libc_fcntl) (int fd, int cmd, ...); typedef FILE *(*__libc_fopen) (const char *name, const char *mode); #ifdef HAVE_FOPEN64 typedef FILE *(*__libc_fopen64) (const char *name, const char *mode); #endif #ifdef HAVE_EVENTFD typedef int (*__libc_eventfd) (int count, int flags); #endif typedef int (*__libc_getpeername) (int sockfd, struct sockaddr * addr, socklen_t * addrlen); typedef int (*__libc_getsockname) (int sockfd, struct sockaddr * addr, socklen_t * addrlen); typedef int (*__libc_getsockopt) (int sockfd, int level, int optname, void *optval, socklen_t * optlen); typedef int (*__libc_ioctl) (int d, unsigned long int request, ...); typedef int (*__libc_listen) (int sockfd, int backlog); typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode); #ifdef HAVE_OPEN64 typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode); #endif /* HAVE_OPEN64 */ typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...); typedef int (*__libc_pipe) (int pipefd[2]); typedef int (*__libc_read) (int fd, void *buf, size_t count); typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov, int iovcnt); typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags); typedef int (*__libc_recvfrom) (int sockfd, void *buf, size_t len, int flags, struct sockaddr * src_addr, socklen_t * addrlen); typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg, int flags); typedef int (*__libc_send) (int sockfd, const void *buf, size_t len, int flags); typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset, size_t len); typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg, int flags); typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len, int flags, const struct sockaddr * dst_addr, socklen_t addrlen); typedef int (*__libc_setsockopt) (int sockfd, int level, int optname, const void *optval, socklen_t optlen); #ifdef HAVE_SIGNALFD typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags); #endif typedef int (*__libc_socket) (int domain, int type, int protocol); typedef int (*__libc_socketpair) (int domain, int type, int protocol, int sv[2]); #ifdef HAVE_TIMERFD_CREATE typedef int (*__libc_timerfd_create) (int clockid, int flags); #endif typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count); typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov, int iovcnt); typedef int (*__libc_shutdown) (int fd, int how); typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds, fd_set * __restrict __writefds, fd_set * __restrict __exceptfds, struct timeval * __restrict __timeout); #ifdef __USE_XOPEN2K typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds, fd_set * __restrict __writefds, fd_set * __restrict __exceptfds, const struct timespec * __restrict __timeout, const __sigset_t * __restrict __sigmask); #endif typedef int (*__libc_epoll_create) (int __size); typedef int (*__libc_epoll_create1) (int __flags); typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd, struct epoll_event * __event); typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events, int __maxevents, int __timeout); typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events, int __maxevents, int __timeout, const __sigset_t * __ss); typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds, int __timeout); #ifdef __USE_GNU typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds, const struct timespec * __timeout, const __sigset_t * __ss); #endif #define SWRAP_SYMBOL_ENTRY(i) \ union { \ __libc_##i f; \ void *obj; \ } _libc_##i struct swrap_libc_symbols { SWRAP_SYMBOL_ENTRY (accept4); SWRAP_SYMBOL_ENTRY (accept); SWRAP_SYMBOL_ENTRY (bind); SWRAP_SYMBOL_ENTRY (close); SWRAP_SYMBOL_ENTRY (connect); #if 0 /* TBD: dup and dup2 to be implemented later */ SWRAP_SYMBOL_ENTRY (dup); SWRAP_SYMBOL_ENTRY (dup2); #endif SWRAP_SYMBOL_ENTRY (fcntl); SWRAP_SYMBOL_ENTRY (fopen); #ifdef HAVE_FOPEN64 SWRAP_SYMBOL_ENTRY (fopen64); #endif #ifdef HAVE_EVENTFD SWRAP_SYMBOL_ENTRY (eventfd); #endif SWRAP_SYMBOL_ENTRY (getpeername); SWRAP_SYMBOL_ENTRY (getsockname); SWRAP_SYMBOL_ENTRY (getsockopt); SWRAP_SYMBOL_ENTRY (ioctl); SWRAP_SYMBOL_ENTRY (listen); SWRAP_SYMBOL_ENTRY (open); #ifdef HAVE_OPEN64 SWRAP_SYMBOL_ENTRY (open64); #endif SWRAP_SYMBOL_ENTRY (openat); SWRAP_SYMBOL_ENTRY (pipe); SWRAP_SYMBOL_ENTRY (read); SWRAP_SYMBOL_ENTRY (readv); SWRAP_SYMBOL_ENTRY (recv); SWRAP_SYMBOL_ENTRY (recvfrom); SWRAP_SYMBOL_ENTRY (recvmsg); SWRAP_SYMBOL_ENTRY (send); SWRAP_SYMBOL_ENTRY (sendfile); SWRAP_SYMBOL_ENTRY (sendmsg); SWRAP_SYMBOL_ENTRY (sendto); SWRAP_SYMBOL_ENTRY (setsockopt); #ifdef HAVE_SIGNALFD SWRAP_SYMBOL_ENTRY (signalfd); #endif SWRAP_SYMBOL_ENTRY (socket); SWRAP_SYMBOL_ENTRY (socketpair); #ifdef HAVE_TIMERFD_CREATE SWRAP_SYMBOL_ENTRY (timerfd_create); #endif SWRAP_SYMBOL_ENTRY (write); SWRAP_SYMBOL_ENTRY (writev); SWRAP_SYMBOL_ENTRY (shutdown); SWRAP_SYMBOL_ENTRY (select); #ifdef __USE_XOPEN2K SWRAP_SYMBOL_ENTRY (pselect); #endif SWRAP_SYMBOL_ENTRY (epoll_create); SWRAP_SYMBOL_ENTRY (epoll_create1); SWRAP_SYMBOL_ENTRY (epoll_ctl); SWRAP_SYMBOL_ENTRY (epoll_wait); SWRAP_SYMBOL_ENTRY (epoll_pwait); SWRAP_SYMBOL_ENTRY (poll); #ifdef __USE_GNU SWRAP_SYMBOL_ENTRY (ppoll); #endif }; struct swrap { struct { void *handle; void *socket_handle; struct swrap_libc_symbols symbols; } libc; }; static struct swrap swrap; #define LIBC_NAME "libc.so" enum swrap_lib { SWRAP_LIBC, }; #ifndef NDEBUG static const char * swrap_str_lib (enum swrap_lib lib) { switch (lib) { case SWRAP_LIBC: return "libc"; } /* Compiler would warn us about unhandled enum value if we get here */ return "unknown"; } #endif static void * swrap_load_lib_handle (enum swrap_lib lib) { int flags = RTLD_LAZY; void *handle = NULL; int i; #ifdef RTLD_DEEPBIND flags |= RTLD_DEEPBIND; #endif switch (lib) { case SWRAP_LIBC: handle = swrap.libc.handle; #ifdef LIBC_SO if (handle == NULL) { handle = dlopen (LIBC_SO, flags); swrap.libc.handle = handle; } #endif if (handle == NULL) { for (i = 10; i >= 0; i--) { char soname[256] = { 0 }; snprintf (soname, sizeof (soname), "libc.so.%d", i); handle = dlopen (soname, flags); if (handle != NULL) { break; } } swrap.libc.handle = handle; } break; } if (handle == NULL)
#!/usr/bin/env python3

# Copyright (c) 2021 Cisco and/or its affiliates.
#
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
#
# Licensed under the Apache License 2.0 or
# GNU General Public License v2.0 or later;  you may not use this file
# except in compliance with one of these Licenses. You
# may obtain a copy of the Licenses at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#     https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
#
# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
# must be under GPLv2+.  If at any point in the future it is no longer linked
# with Scapy (or other GPLv2+ licensed software), you are free to choose
# Apache 2.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either exp