diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2022-03-16 22:20:47 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2022-03-16 22:20:47 +0100 |
commit | 54fb5592b4724934535a606f1981ea439533a4a8 (patch) | |
tree | 4e5a664466817aa10195216b6e46c7ed855156b5 | |
parent | 521ee3bb8356c0916b7fb228612f06e07a841b36 (diff) |
initial whatever
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rw-r--r-- | src/challenge.c | 135 | ||||
-rw-r--r-- | src/challenge.h | 95 | ||||
-rw-r--r-- | src/md5.c | 381 | ||||
-rw-r--r-- | src/md5.h | 92 | ||||
-rw-r--r-- | src/options.c | 613 | ||||
-rw-r--r-- | src/options.h | 129 | ||||
-rw-r--r-- | src/pconfig.h | 147 | ||||
-rw-r--r-- | src/pdesc.c | 316 | ||||
-rw-r--r-- | src/pdesc.h | 188 | ||||
-rw-r--r-- | src/pkt.c | 525 | ||||
-rw-r--r-- | src/pkt.h | 144 | ||||
-rw-r--r-- | src/ppkt.h | 20 | ||||
-rw-r--r-- | src/psock.c | 92 | ||||
-rw-r--r-- | src/psock.h | 27 | ||||
-rw-r--r-- | src/ptunnel.c | 874 | ||||
-rw-r--r-- | src/ptunnel.h | 164 | ||||
-rw-r--r-- | src/utils.c | 195 | ||||
-rw-r--r-- | src/utils.h | 66 | ||||
-rw-r--r-- | src/win32/includes/bittypes.h | 137 | ||||
-rw-r--r-- | src/win32/includes/pcap-stdinc.h | 93 | ||||
-rw-r--r-- | src/win32/includes/pcap.h | 45 | ||||
-rw-r--r-- | src/win32/includes/pcap/bpf.h | 934 | ||||
-rw-r--r-- | src/win32/includes/pcap/pcap.h | 407 |
24 files changed, 159 insertions, 5669 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 5786a01..60b5bc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,13 +39,8 @@ ptunnel_ng_CFLAGS += -fsanitize=address -fsanitize=leak -fsanitize=undefined endif ptunnel_ng_SOURCES = \ - md5.c \ - challenge.c \ - options.c \ - utils.c \ - pkt.c \ - pdesc.c \ - ptunnel.c + ptunnel.c \ + psock.c if IS_WINDOWS wpcap_DEF = $(srcdir)/win32/WPCAP.DEF diff --git a/src/challenge.c b/src/challenge.c deleted file mode 100644 index d12beea..0000000 --- a/src/challenge.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * challenge.c - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> -#include <assert.h> - -#include "challenge.h" -#include "options.h" -#include "md5.h" -#include "utils.h" - -/* generate_challenge: Generates a random challenge, incorporating the current - * local timestamp to avoid replay attacks. - */ -challenge_t *generate_challenge(void) { - struct timeval tt; - challenge_t *c; - int i; - - c = (challenge_t *) calloc(1, sizeof(challenge_t)); - assert(c != NULL); - gettimeofday(&tt, 0); - c->plain.sec = tt.tv_sec; - c->plain.usec_rnd = tt.tv_usec + pt_random(); - for (i=0;i<6;i++) - c->plain.random[i] = pt_random(); - - return c; -} - -/* generate_response_md5: Generates a response to the given challenge. The response - * is generated by combining the concatenating the challenge data with the - * md5 digest of the password, and then calculating the MD5 digest of the - * entire buffer. The result is stored in the passed-in challenge, overwriting - * the challenge data. - */ -void generate_response_md5(challenge_plain_t *plain, challenge_digest_t *digest) { - md5_byte_t buf[sizeof(*plain) + kMD5_digest_size]; - md5_state_t state; - - digest->hash_type = HT_MD5; - memcpy(buf, plain, sizeof(*plain)); - memcpy(&buf[sizeof(*plain)], opts.md5_password_digest, kMD5_digest_size); - memset(plain, 0, sizeof(*plain)); - - md5_init(&state); - md5_append(&state, buf, sizeof(*plain) + kMD5_digest_size); - md5_finish(&state, (md5_byte_t *) &digest->md5[0]); -} - -/* validate_challenge_md5: Checks whether a given response matches the expected - * response, returning 1 if validation succeeded, and 0 otherwise. Note that - * overwriting the local challenge with the challenge result is not a problem, - * as the data will not be used again anyway (authentication either succeeds, - * or the connection is closed down). - */ -int validate_challenge_md5(challenge_t *local, challenge_digest_t *remote) { - generate_response_md5(&local->plain, &local->digest); - if (remote->hash_type == HT_MD5 && - memcmp(&local->digest.md5[0], &remote->md5[0], sizeof(local->digest.md5)) == 0) - { - return 1; - } - return 0; -} - -#ifdef ENABLE_SHA512 -void generate_response_sha512(challenge_plain_t *plain, challenge_digest_t *digest) -{ - unsigned char buf[sizeof(*plain) + kSHA512_digest_size]; - - digest->hash_type = HT_SHA512; - memcpy(buf, plain, sizeof(*plain)); - memcpy(&buf[sizeof(*plain)], opts.sha512_password_digest, kSHA512_digest_size); - memset(plain, 0, sizeof(*plain)); - - SHA512(buf, sizeof(*plain) + kSHA512_digest_size, &digest->sha512[0]); -} - -int validate_challenge_sha512(challenge_t *local, challenge_digest_t *remote) -{ - generate_response_sha512(&local->plain, &local->digest); - - if (remote->hash_type == HT_SHA512 && - memcmp(&local->digest.sha512[0], &remote->sha512[0], sizeof(local->digest.sha512)) == 0) - { - return 1; - } - return 0; -} -#endif /* ENABLE_SHA512 */ diff --git a/src/challenge.h b/src/challenge.h deleted file mode 100644 index 203e420..0000000 --- a/src/challenge.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * challenge.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifndef CHALLENGE_H -#define CHALLENGE_H 1 - -#include "pconfig.h" - -#include <stdint.h> -#ifdef ENABLE_SHA512 -#include <openssl/sha.h> -#endif - -#define HT_MD5 0x1 -#define HT_SHA512 0x2 - - -typedef struct challenge_plain_t { - /** tv_sec as returned by gettimeofday */ - uint32_t sec; - /** tv_usec as returned by gettimeofday + random value */ - uint32_t usec_rnd; - /** random values */ - uint32_t random[6]; -} __attribute__ ((packed)) challenge_plain_t; - -typedef struct challenge_digest_t { - uint8_t hash_type; - union { - unsigned char md5[kMD5_digest_size]; - unsigned char sha512[kSHA512_digest_size]; - }; -} __attribute__ ((packed)) challenge_digest_t; - -/** challenge_t: This structure contains the pseudo-random challenge used for - * authentication. If OpenSSL is available SHA512 will be used per default. - */ -typedef struct challenge_t { - challenge_plain_t plain; - challenge_digest_t digest; -} __attribute__ ((packed)) challenge_t; - -challenge_t *generate_challenge(void); - -void generate_response_md5(challenge_plain_t *plain, challenge_digest_t *digest); -int validate_challenge_md5(challenge_t *local, challenge_digest_t *remote); - -#ifdef ENABLE_SHA512 -void generate_response_sha512(challenge_plain_t *plain, challenge_digest_t *digest); -int validate_challenge_sha512(challenge_t *local, challenge_digest_t *remote); -#endif - -#endif diff --git a/src/md5.c b/src/md5.c deleted file mode 100644 index cd87d02..0000000 --- a/src/md5.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.c,v 1.1 2005/04/15 07:37:22 daniels Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include <string.h> - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include <stdio.h> in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include <string.h> - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/src/md5.h b/src/md5.h deleted file mode 100644 index f9fdeb4..0000000 --- a/src/md5.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.1 2005/04/15 07:37:22 daniels Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke <purschke@bnl.gov>. - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ -#define MD5_LEN 16 - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[MD5_LEN]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/src/options.c b/src/options.c deleted file mode 100644 index 84227ae..0000000 --- a/src/options.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * options.c - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdint.h> -#include <string.h> -#include <getopt.h> -#include <ctype.h> -#include <assert.h> -#ifdef WIN32 -#include <ws2tcpip.h> -#endif -#ifdef ENABLE_SHA512 -#include <openssl/sha.h> -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "options.h" -#include "utils.h" -#include "ptunnel.h" -#include "md5.h" - - -struct options opts; - -enum option_type { - OPT_BOOL, OPT_DEC32, OPT_HEX32, OPT_STR -}; - -struct option_usage { - const char *short_help; - int required; - enum option_type otype; - union { - int32_t num; - uint32_t unum; - const char *str; - }; - const char *long_help; -}; - -static const struct option_usage usage[] = { - /** --magic */ - {"magic", 0, OPT_HEX32, {.unum = 0xdeadc0de}, - "Set ptunnel magic hexadecimal number. (32-bit unsigned)\n" - "It is an identifier for all ICMP/UDP packets\n" - "and can be used to bypass Cisco IPS fingerprint scan.\n" - "This value has to be the same on the server and client!\n" - }, - /** --proxy */ - {"address", 1, OPT_STR, {.str = NULL}, - "Set address of peer running packet forwarder. This causes\n" - "ptunnel to operate in forwarding mode (Client) - the absence of this\n" - "option causes ptunnel to operate in proxy mode (Server).\n" - }, - /** --listen */ - {"port", 0, OPT_DEC32, {.unum = 2222}, - "Set TCP listening port (only used when operating in forward mode)\n" - }, - /** --remote-addr */ - {"address", 1, OPT_STR, {.str = "127.0.0.1"}, - "Set remote proxy destination address if client\n" - "Restrict to only this destination address if server\n" - }, - /** --remote-port */ - {"port", 1, OPT_DEC32, {.unum = 22}, - "Set remote proxy destination port if client\n" - "Restrict to only this destination port if server\n" - }, - /** --connections */ - {"connections", 0, OPT_DEC32, {.unum = kMax_tunnels}, - "Set maximum number of concurrent tunnels\n" - }, - /** --verbosity */ - {"level", 0, OPT_DEC32, {.num = kLog_event}, - "Verbosity level (-1 to 4, where -1 is no output, and 4 is all output)\n" - "The special level 5 (or higher) includes xfer logging (lots of output)\n" - }, - /** --libpcap */ - {"interface", 0, OPT_STR, {.str = NULL}, -#ifndef HAVE_PCAP - "(Not available on this platform.)\n" -#endif - "Enable libpcap on the given device.\n" - }, - /** --list-libpcap-devices */ - {NULL, 0, OPT_BOOL, {.num = 0}, -#ifndef HAVE_PCAP - "(Not available on this platform.)\n" -#endif - "List all available pcap devices.\n" - }, - /** --logfile */ - {"file", 0, OPT_STR, {.str = "/var/log/ptunnel.log"}, - "Specify a file to log to, rather than printing to standard out.\n" - }, - /** --statistics */ - {NULL, 0, OPT_BOOL, {.num = 0}, - "Client only. Enables continuous output of statistics (packet loss, etc.)\n" - }, - /** --passwd */ - {"password", 0, OPT_STR, {.str = NULL}, - "Set a password (must be same on client and proxy)\n" - "DEPRECATED: Will be removed/replaced soon!\n" - }, - /** --udp */ - {NULL, 0, OPT_BOOL, {.num = 0}, - "Toggle use of UDP instead of ICMP. Proxy will listen on port 53 (must be root).\n" - }, - /** --unprivileged */ - {NULL, 0, OPT_BOOL, {.num = 0}, - "Run proxy in unprivileged mode. This causes the proxy to forward\n" - "packets using standard echo requests, instead of crafting custom echo replies.\n" - "Unprivileged mode will only work on some systems, and is in general less reliable\n" - "than running in privileged mode.\n" - }, - /** --force-sha512 */ - {"force-sha512", 0, OPT_BOOL, {.num = 0}, - "Force SHA512 as challenge response checksum generator.\n" -#ifdef ENABLE_SHA512 - "This is the default for this configuration.\n" -#else - "SHA512 is not available for this configuration.\n" -#endif - }, - /** --daemon */ - {"pidfile", 0, OPT_STR, {.str = "/run/ptunnel.pid"}, -#ifdef WIN32 - "(Not available on this platform.)\n" -#endif - "Run in background, the PID will be written in the file supplied as argument\n" - }, - /** --syslog */ - {NULL, 0, OPT_BOOL, {.num = 0}, -#ifdef WIN32 - "(Not available on this platform.)\n" -#endif - "Output debug to syslog instead of standard out.\n" - }, - /** --user */ - {"user", 0, OPT_STR, {.str = "nobody"}, -#ifdef WIN32 - "(Not available on this platform.)\n" -#endif - "When started in privileged mode, drop down to user's rights as soon as possible\n" - }, - /** --group */ - {"group", 0, OPT_STR, {.str = "nogroup"}, -#ifdef WIN32 - "(Not available on this platform.)\n" -#endif - "When started in privileged mode, drop down to group's rights as soon as possible\n" - }, - /** --chroot */ - {"directory", 0, OPT_STR, {.str = "/var/lib/ptunnel"}, -#ifdef WIN32 - "(Not available on this platform.)\n" -#endif - "When started in privileged mode, restrict file access to the specified directory\n" - }, - /** --setcon */ - {"context", 0, OPT_STR, {.str = "ptunnel"}, -#ifndef HAVE_SELINUX - "(Not available on this platform.)\n" -#endif - "Set SELinux context when all there is left to do are network I/O operations\n" - "To combine with --chroot you will have to `mount --bind /proc /chrootdir/proc`\n" - }, - /** --help */ - {NULL, 0, OPT_STR, {.str = NULL}, "this\n"}, - {NULL,0,OPT_BOOL,{.unum=0},NULL} -}; - -static struct option long_options[] = { - {"magic", required_argument, 0, 'm'}, - {"proxy", required_argument, 0, 'p'}, - {"listen", required_argument, 0, 'l'}, - {"remote-addr", optional_argument, 0, 'r'}, - {"remote-port", optional_argument, 0, 'R'}, - {"connections", required_argument, 0, 'c'}, - {"verbosity", required_argument, 0, 'v'}, - {"libpcap", required_argument, 0, 'L'}, - {"list-libpcap-devices", no_argument, &opts.list_pcap_devices, 1}, - {"logfile", optional_argument, 0, 'o'}, - {"statistics", no_argument, 0, 's'}, - {"passwd", required_argument, 0, 'P'}, - {"udp", no_argument, &opts.udp, 1}, - {"unprivileged", no_argument, &opts.unprivileged, 1}, - {"force-sha512", no_argument, &opts.force_sha512, 1}, - {"daemon", optional_argument, 0, 'd'}, - {"syslog", no_argument, 0, 'S'}, - {"user", optional_argument, 0, 'u'}, - {"group", optional_argument, 0, 'g'}, - {"chroot", optional_argument, 0, 'C'}, - {"setcon", optional_argument, 0, 'e'}, - {"help", no_argument, 0, 'h'}, - {NULL,0,0,0} -}; - - -static const void *get_default_optval(enum option_type opttype, const char *optname) { - (void) opttype; - - for (unsigned i = 0; i < ARRAY_SIZE(long_options); ++i) { - if (strncmp(long_options[i].name, optname, BUFSIZ /* not optimal */) == 0 && - strlen(long_options[i].name) == strlen(optname)) - { - assert(usage[i].otype == opttype && - (usage[i].otype != OPT_STR || usage[i].str)); - return &usage[i].str; - } - } - assert(NULL); - return NULL; -} - -static void set_options_defaults(void) { -#ifndef WIN32 - char *tmp; - struct passwd *pwnam; - struct group *grnam; -#endif - - memset(&opts, 0, sizeof(opts)); - opts.magic = *(uint32_t *) get_default_optval(OPT_HEX32, "magic"); - opts.mode = kMode_proxy; - opts.tcp_listen_port = *(uint32_t *) get_default_optval(OPT_DEC32, "listen"); - opts.given_dst_hostname = strdup(*(char **) get_default_optval(OPT_STR, "remote-addr")); - opts.given_dst_port = *(uint32_t *) get_default_optval(OPT_DEC32, "remote-port"); - opts.max_tunnels = *(uint32_t *) get_default_optval(OPT_DEC32, "connections"); - opts.log_level = *(int *) get_default_optval(OPT_DEC32, "verbosity"); - opts.log_path = strdup(*(char **)get_default_optval(OPT_STR, "logfile")); - opts.log_file = stdout; - opts.print_stats = *(int *) get_default_optval(OPT_BOOL, "statistics"); -#ifndef WIN32 - opts.pid_path = strdup(*(char **)get_default_optval(OPT_STR, "daemon")); - - errno = 0; - tmp = *(char **) get_default_optval(OPT_STR, "user"); - if (NULL == (pwnam = getpwnam(tmp))) - pt_log(kLog_error, "%s: %s\n", tmp, errno ? strerror(errno) : "unknown user"); - else { - opts.uid = pwnam->pw_uid; - if (!opts.gid) - opts.gid = pwnam->pw_gid; - } - - errno = 0; - tmp = *(char **) get_default_optval(OPT_STR, "group"); - if (NULL != (grnam = getgrnam(tmp))) - opts.gid = grnam->gr_gid; - - opts.root_dir = strdup(*(char **)get_default_optval(OPT_STR, "chroot")); -#endif -#ifdef HAVE_SELINUX - opts.selinux_context = strdup(*(char **)get_default_optval(OPT_STR, "setcon")); -#endif -} - -static void print_multiline(const char *prefix, const char *multiline) { - const char sep[] = "\n"; - const char *start, *end; - - start = multiline; - end = NULL; - do { - if (start) { - end = strstr(start, sep); - if (end && *end != '\0') { - printf("%s%.*s\n", prefix, (int)(end-start), start); - start = end + strnlen(sep, BUFSIZ /* not optimal */); - } - } - } while (start && end); -} - -static void print_long_help(unsigned index, int required_state) { - const char spaces[] = " "; - - if (usage[index].required != required_state) - return; - if (!long_options[index].name) - return; - - if (isalpha(long_options[index].val)) { - printf("%.*s-%c --%s\n", 4, spaces, long_options[index].val, long_options[index].name); - } else { - printf("%.*s--%s\n", 4, spaces, long_options[index].name); - } - - if (usage[index].long_help) { - print_multiline(&spaces[4], usage[index].long_help); - } - - switch (usage[index].otype) { - case OPT_BOOL: - break; - case OPT_DEC32: - printf("%s(default: %d)\n", spaces, usage[index].num); - break; - case OPT_HEX32: - printf("%s(default: 0x%X)\n", spaces, usage[index].unum); - break; - case OPT_STR: - if (usage[index].str) - printf("%s(default: %s)\n", spaces, usage[index].str); - break; - } -} - -static void print_short_help(unsigned index, int required_state) { - const char *ob = (required_state == 0 ? "[" : ""); - const char *cb = (required_state == 0 ? "]" : ""); - const char *ov = (long_options[index].has_arg != optional_argument ? " " : ""); - - if (usage[index].required != required_state) - return; - if (!long_options[index].name) - return; - - if (!usage[index].short_help && isalpha(long_options[index].val)) { - printf(" %s-%c%s", ob, long_options[index].val, cb); - } - else if (!usage[index].short_help) { - printf(" %s--%s%s", ob, long_options[index].name, cb); - } - else if (isalpha(long_options[index].val)) { - printf(" %s-%c%s<%s>%s", ob, long_options[index].val, ov, usage[index].short_help, cb); - } - else { - printf(" %s--%s <%s>%s", ob, long_options[index].name, usage[index].short_help, cb); - } -} - -void print_usage(const char *arg0) { - unsigned i; - - printf("%s\n\nUsage: %s", PACKAGE_STRING, arg0); - /* print (short)help argument line */ - for (i = 0; i < ARRAY_SIZE(usage); ++i) { - print_short_help(i, 1); - } - for (i = 0; i < ARRAY_SIZE(usage); ++i) { - print_short_help(i, 0); - } - - printf("%s", "\n\n"); - /* print (long)help lines */ - for (i = 0; i < ARRAY_SIZE(usage); ++i) { - print_long_help(i, 1); - } - for (i = 0; i < ARRAY_SIZE(usage); ++i) { - print_long_help(i, 0); - } -} - -int parse_options(int argc, char **argv) { - int c = 0, oidx = -1, has_logfile = 0, ret; - md5_state_t state; -#ifndef WIN32 - struct passwd *pwnam; - struct group *grnam; -#endif - FILE *tmp_log; - - assert( ARRAY_SIZE(long_options) == ARRAY_SIZE(usage) ); - - /* set defaults */ - set_options_defaults(); - - /* parse command line arguments */ - while (1) { - /* FIXME: We are using '::' (optional argument values). This is not optimal - * since you have to pass long options as '--option=value'. Commonly used - * '--option value' is *NOT* allowed for some libc implementations. - */ - c = getopt_long(argc, argv, "m:p:l:r::R::c:v:L:o::sP:d::Su::g::C::e::h", &long_options[0], &oidx); - if (c == -1) break; - - switch (c) { - case 'm': - if (!optarg) - break; - opts.magic = strtoul(optarg, NULL, 16); - break; - case 'p': - if (!optarg) - break; - opts.mode = kMode_forward; - if (opts.given_proxy_hostname) - free(opts.given_proxy_hostname); - opts.given_proxy_hostname = strdup(optarg); - break; - case 'l': - if (!optarg) - break; - opts.tcp_listen_port = strtoul(optarg, NULL, 10); - break; - case 'r': - opts.restrict_dst_ip = 1; - if (!optarg) - break; - if (opts.given_dst_hostname) - free(opts.given_dst_hostname); - opts.given_dst_hostname = strdup(optarg); - break; - case 'R': - opts.restrict_dst_port = 1; - if (optarg) - opts.given_dst_port = strtoul(optarg, NULL, 10); - break; - case 'c': - if (!optarg) - break; - opts.max_tunnels = strtoul(optarg, NULL,10); - if (opts.max_tunnels > kMax_tunnels) - opts.max_tunnels = kMax_tunnels; - break; - case 'v': - if (!optarg) - break; - opts.log_level = strtol(optarg, NULL, 10); - break; - case 'L': -#ifdef HAVE_PCAP - opts.pcap = 1; - if (!optarg) - break; - if (opts.pcap_device) - free(opts.pcap_device); - opts.pcap_device = strdup(optarg); - break; -#else - pt_log(kLog_error, "pcap: %s\n", "feature not supported"); - exit(1); -#endif - case 'o': - has_logfile = 1; - if (!optarg) - break; - if (opts.log_path) - free(opts.log_path); - opts.log_path = strdup(optarg); - break; - case 's': - opts.print_stats = !opts.print_stats; - break; - case 'P': - if (!optarg) - break; - if (opts.password) - free(opts.password); - opts.password = strdup(optarg); - pt_log(kLog_debug, "%s\n", "Password set - unauthenicated connections will be refused."); - /* Compute the md5 password digest */ - md5_init(&state); - md5_append(&state, (md5_byte_t *)optarg, strnlen(opts.password, BUFSIZ /* not optimal */)); - md5_finish(&state, &opts.md5_password_digest[0]); -#ifdef ENABLE_SHA512 - pt_log(kLog_debug, "%s\n", "Password set - sha512 authentication enabled."); - SHA512((const unsigned char *)optarg, strnlen(opts.password, BUFSIZ /* not optimal */), &opts.sha512_password_digest[0]); -#endif - // Hide the password in process listing - memset(optarg, '*', strnlen(optarg, BUFSIZ /* not optimal */)); - break; -#ifndef WIN32 - case 'd': - opts.daemonize = true; - if (!optarg) - break; - if (opts.pid_path) - free(opts.pid_path); - opts.pid_path = strdup(optarg); - break; - case 'S': - opts.use_syslog = 1; - break; - case 'u': - if (!optarg) - break; - errno = 0; - if (NULL == (pwnam = getpwnam(optarg))) { - pt_log(kLog_error, "%s: %s\n", optarg, errno ? strerror(errno) : "unknown user"); - exit(1); - } - opts.uid = pwnam->pw_uid; - if (!opts.gid) - opts.gid = pwnam->pw_gid; - break; - case 'g': - if (!optarg) - break; - errno = 0; - if (NULL == (grnam = getgrnam(optarg))) { - pt_log(kLog_error, "%s: %s\n", optarg, errno ? strerror(errno) : "unknown group"); - exit(1); - } - opts.gid = grnam->gr_gid; - break; - case 'C': - opts.chroot = 1; - if (!optarg) - break; - if (opts.root_dir) - free(opts.root_dir); - opts.root_dir = strdup(optarg); - break; -#else - case 'd': - case 'S': - case 'u': - case 'g': - case 'C': - pt_log(kLog_error, "-%c: %s\n", c, "feature not supported"); - exit(1); -#endif - case 'e': -#ifdef HAVE_SELINUX - opts.selinux = 1; - if (!optarg) - break; - if (opts.selinux_context) - free(opts.selinux_context); - opts.selinux_context = strdup(optarg); - break; -#else - pt_log(kLog_error, "SeLinux: %s\n", "feature not supported"); - exit(1); -#endif - case 'h': - print_usage(argv[0]); - exit(EXIT_SUCCESS); - case 0: /* long opt only */ - default: - break; - } - } - - if (optind != argc) { - pt_log(kLog_error, "Unknown argument: '%s'\n", argv[optind]); - exit(1); - } - -#ifndef ENABLE_SHA512 - if (opts.force_sha512) { - pt_log(kLog_error, "%s\n", "You are forcing sha512 but it isn't available."); - return 1; - } -#endif - - if (opts.given_proxy_hostname) { - if ((ret = host_to_addr(opts.given_proxy_hostname, &opts.given_proxy_ip)) != 0) { - pt_log(kLog_error, "Failed to look up %s as destination address: %s\n", - opts.given_proxy_hostname, gai_strerror(ret)); - return 1; - } - } - - if ((ret = host_to_addr(opts.given_dst_hostname, &opts.given_dst_ip)) != 0) { - pt_log(kLog_error, "Failed to look up %s as destination address: %s\n", - opts.given_dst_hostname, gai_strerror(ret)); - return 1; - } - -#ifndef WIN32 - if (NULL == (opts.pid_file = fopen(opts.pid_path, "w"))) - pt_log(kLog_error, "Failed to open pidfile: \"%s\", Cause: %s\n", opts.pid_path, strerror(errno)); -#endif - - if (has_logfile && opts.log_path) { - pt_log(kLog_info, "Open Logfile: \"%s\"\n", opts.log_path); - tmp_log = fopen(opts.log_path, "a"); - if (!tmp_log) { - pt_log(kLog_error, "Failed to open log file: \"%s\", Cause: %s\n", opts.log_path, strerror(errno)); - pt_log(kLog_error, "Reverting log to standard out.\n"); - } else opts.log_file = tmp_log; - } - - return 0; -} diff --git a/src/options.h b/src/options.h deleted file mode 100644 index bea713b..0000000 --- a/src/options.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * options.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - */ - -#ifndef OPTIONS_H -#define OPTIONS_H 1 - -#include <stdio.h> -#include <stdint.h> -#include <stdbool.h> -#ifndef WIN32 -#include <pwd.h> -#include <grp.h> -#endif -#ifdef HAVE_SELINUX -#include <selinux/selinux.h> -#endif - -#include "md5.h" -#include "pconfig.h" - -struct options { - /** user defined magic value (prevent Cisco WSA/IronPort fingerprint scan) */ - uint32_t magic; - /** proxy or forwarder? */ - int mode; - /** Proxy's internet address */ - char *given_proxy_hostname; - uint32_t given_proxy_ip; - /** Port the client listens on */ - uint32_t tcp_listen_port; - /** restrict Forward/Proxy destination internet address */ - int restrict_dst_ip; - char *given_dst_hostname; - uint32_t given_dst_ip; - /** restrict Forward/Proxy destination port */ - int restrict_dst_port; - uint32_t given_dst_port; - /** Default maximum number of tunnels to support at once */ - uint32_t max_tunnels; - /** Default log level */ - int log_level; -#ifdef HAVE_PCAP - /** Non zero value if user wants packet capturing */ - int pcap; - /** Device to capture packets from */ - char *pcap_device; -#endif - /** Force SHA512 based challenge response. */ - int force_sha512; - /** List all available pcap devices and exit */ - int list_pcap_devices; - /** Usually stdout, but can be altered by the user */ - char *log_path; - FILE *log_file; - /** Print more detailed traffic statistics if non zero value */ - int print_stats; - /** Password (must be the same on proxy and client for authentica tion to succeed) */ - char *password; - /** MD5 digest of password */ - md5_byte_t md5_password_digest[kMD5_digest_size]; - /** SHA512 digest of password */ - unsigned char sha512_password_digest[kSHA512_digest_size]; - /** use UDP instead of ICMP */ - int udp; - /** unpriviledged mode */ - int unprivileged; - -#ifndef WIN32 - /** run as daemon if non zero value */ - int daemonize; - /** PIDFILE if running as daemon */ - char *pid_path; - FILE *pid_file; - /** log to syslog if non zero value */ - int use_syslog; - /** UID of the running process */ - uid_t uid; - /** GID of the running process */ - gid_t gid; - /** CHROOT dir */ - int chroot; - char *root_dir; -#endif - -#ifdef HAVE_SELINUX - /** Non zero value if uer wants SeLinux */ - int selinux; - /** SeLinux context name */ - char *selinux_context; -#endif -}; - -extern struct options opts; - -void print_usage(const char *arg0); - -int parse_options(int argc, char **argv); - -#endif diff --git a/src/pconfig.h b/src/pconfig.h deleted file mode 100644 index 140cad5..0000000 --- a/src/pconfig.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * pconfig.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifndef PCONFIG_H -#define PCONFIG_H 1 - -enum { - /** Set this constant to the number of - * concurrent connections you wish to handle by default. - */ - kMax_tunnels = 10, - /** numbers */ - kIP_packet_max_size = 576, - /** In bytes, mind you */ - kIP_header_size = 20, - kIP_actual_size = (kIP_packet_max_size - kIP_header_size) - ((kIP_packet_max_size - kIP_header_size) % 8), - /** Also in bytes */ - kICMP_header_size = 8, - /** This constant control the maximum size of - * the payload-portion of the ICMP packets - * we send. Note that this does not include - * the IP or ICMP headers! - */ - kDefault_buf_size = 1024, - /** Type code for echo request and replies */ - kICMP_echo_request = 8, - kICMP_echo_reply = 0, - /** number of packets we can have in our send/receive ring */ - kPing_window_size = 64, - /** Tunnels are automatically closed after one minute of inactivity. Since - * we continously send acknowledgements between the two peers, this mechanism - * won't disconnect "valid" connections. - */ - kAutomatic_close_timeout = 60, // Seconds! - /** size of md5 digest in bytes */ - kMD5_digest_size = 16, - /** size of sha512 digest in bytes */ - kSHA512_digest_size = 64, - kDNS_port = 53 -}; - -enum oper_mode { - /** Ping tunnel's operating mode (client) */ - kMode_forward = 0, - /** Ping tunnel's operating mode (server) */ - kMode_proxy -}; - -enum pkt_flag { - /** set when packet comes from a user */ - kUser_flag = 1 << 30, - /** set when packet comes from the proxy */ - kProxy_flag = 1 << 31, - kFlag_mask = kUser_flag | kProxy_flag -}; - -enum log_level { - /** Different verbosity levels. */ - kNo_log = -1, - kLog_error = 0, - kLog_info, - kLog_event, - kLog_verbose, - kLog_debug, - kLog_sendrecv -}; - -enum proxy_state { - /** These constants are used to indicate the protocol state. The protocol - * works as follows: - * - The identifier is used by both the proxy and the forwarder - * to identify the session (and thus the relevant sockets). - * - The seq-no of the ping packet is used in a sliding-window-esque - * way, and to identify the order of data. - * - * The protocol can be in any of the following states: - * kProxy_start Causes the proxy to open a connection to the given - * host and port, associating the ID with the socket, - * before the data on the socket are transmitted. - * kProxy_data Indicates that the packet contains data from the proxy. - * Data ordering is indicated by the seq-no, which will start - * at 0. (The proxy and forwarder maintain different seq-nos.) - * kUser_data This packet contains user data. - * kConnection_close Indicates that the connection is being closed. - * kProxy_ack and Acknowledges the packet (and all packets before it) with seq_no = ack. - * kUser_ack This is used if there are no implicit acknowledgements due to data - * being sent. - * - * Acknowledgements work by the remote peer acknowledging the last - * continuous seq no it has received. - * - * Note: A proxy receiving a kProxy_data packet, or a user receiving a - * kUser_data packet, should ignore it, as it is the host operating system - * actually returning the ping. This is mostly relevant for users, and for - * proxies running in unprivileged mode. - */ - kProxy_start = 0, - kProto_ack, - kProto_data, - kProto_close, - kProto_authenticate, - kNum_proto_types -}; - -#endif diff --git a/src/pdesc.c b/src/pdesc.c deleted file mode 100644 index bcae1c4..0000000 --- a/src/pdesc.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * pdesc.c - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#include <stdlib.h> -#include <sys/time.h> -#include <assert.h> - -#include "pdesc.h" -#include "options.h" -#include "utils.h" -#include "ptunnel.h" - - -/* create_and_insert_proxy_desc: Creates a new proxy descriptor, linking it into - * the descriptor chain. If the sock argument is 0, the function will establish - * a TCP connection to the ip and port given by dst_ip, dst_port. - */ -proxy_desc_t *create_and_insert_proxy_desc(uint16_t id_no, uint16_t icmp_id, - int sock, struct sockaddr_in *addr, - uint32_t dst_ip, uint32_t dst_port, - uint32_t init_state, enum pkt_flag type) { - proxy_desc_t *cur; - - pthread_mutex_lock(&chain_lock); - if (num_tunnels >= opts.max_tunnels) { - pt_log(kLog_info, "Discarding incoming connection - too many tunnels! Maximum count is %u (adjust with the -m switch).\n", opts.max_tunnels); - if (sock) - close(sock); - pthread_mutex_unlock(&chain_lock); - return 0; - } - num_tunnels++; - pthread_mutex_unlock(&chain_lock); - - pt_log(kLog_debug, "Adding proxy desc to run loop. Type is %s. Will create socket: %s\n", (type == kUser_flag ? "user" : "proxy"), (sock ? "No" : "Yes")); - cur = (proxy_desc_t *) calloc(1, sizeof(proxy_desc_t)); - cur->id_no = id_no; - cur->dest_addr = *addr; - cur->dst_ip = dst_ip; - cur->dst_port = dst_port; - cur->icmp_id = icmp_id; - if (!sock) { - cur->sock = socket(AF_INET, SOCK_STREAM, 0); - memset(addr, 0, sizeof(struct sockaddr_in)); - addr->sin_port = htons((uint16_t)dst_port); - addr->sin_addr.s_addr = dst_ip; - addr->sin_family = AF_INET; - /* Let's just assume success, shall we? */ - if (cur->sock >= 0 && - connect(cur->sock, (struct sockaddr*)addr, sizeof(struct sockaddr_in)) < 0) - { - pt_log(kLog_error, "Connect to %s:%d failed: %s\n", inet_ntoa(*(struct in_addr*)&addr->sin_addr.s_addr) , ntohs(addr->sin_port), strerror(errno)); - } - } else { - cur->sock = sock; - } - cur->state = init_state; - cur->type_flag = type; - if (cur->type_flag == kUser_flag) { - cur->pkt_type = kICMP_echo_request; - } else { - cur->pkt_type = (opts.unprivileged ? kICMP_echo_request : kICMP_echo_reply); - } - cur->buf = (char *) malloc(icmp_receive_buf_len); - cur->last_activity = time_as_double(); - cur->authenticated = 0; - - pthread_mutex_lock(&chain_lock); - cur->next = chain; - chain = cur; - pthread_mutex_unlock(&chain_lock); - cur->xfer.bytes_in = 0.0; - cur->xfer.bytes_out = 0.0; - cur->window_size = kPing_window_size; - cur->ack_interval = 1.0; - cur->resend_interval = 1.5; - cur->send_ring = (icmp_desc_t *) calloc(cur->window_size, sizeof(icmp_desc_t)); - cur->recv_ring = (forward_desc_t **) calloc(cur->window_size, sizeof(forward_desc_t *)); - return cur; -} - -/* remove_proxy_desc: Removes the given proxy desc, freeing its resources. - * Assumes that we hold the chain_lock. - */ -void remove_proxy_desc(proxy_desc_t *cur, proxy_desc_t *prev) { - struct timeval tt; - - pt_log(kLog_debug, "Removing proxy descriptor.\n"); - /* Get a timestamp, for making an entry in the seq_expiry_tbl */ - gettimeofday(&tt, 0); - seq_expiry_tbl[cur->id_no] = tt.tv_sec+(2*kAutomatic_close_timeout); - - /* Free resources associated with connection */ - if (cur->buf) - free(cur->buf); - cur->buf = 0; - remove_proxy_desc_rings(cur); - close(cur->sock); - cur->sock = 0; - - /* Keep list up-to-date */ - if (prev) - prev->next = cur->next; - else - chain = cur->next; - if (cur->challenge) - free(cur->challenge); - free(cur); - num_tunnels--; -} - -void remove_proxy_desc_rings(proxy_desc_t *cur) { - int i; - for (i=0;i<cur->window_size;i++) { - if (cur->send_ring[i].pkt) - free(cur->send_ring[i].pkt); - cur->send_ring[i].pkt = 0; - if (cur->recv_ring[i]) - free(cur->recv_ring[i]); - cur->recv_ring[i] = 0; - } - free(cur->send_ring); - free(cur->recv_ring); - - cur->recv_idx = 0; - cur->recv_xfer_idx = 0; - cur->send_idx = 0; - cur->send_first_ack = 0; - cur->recv_wait_send = 0; - cur->send_wait_ack = 0; - cur->next_resend_start = 0; -} - -forward_desc_t* create_fwd_desc(uint16_t seq_no, uint32_t data_len, char *data) { - forward_desc_t *fwd_desc; - fwd_desc = (forward_desc_t *) malloc(sizeof(forward_desc_t)+data_len); - fwd_desc->seq_no = seq_no; - fwd_desc->length = data_len; - fwd_desc->remaining = data_len; - if (data_len > 0) - memcpy(fwd_desc->data, data, data_len); - return fwd_desc; -} - -/* queue_packet: - * Creates an ICMP packet descriptor, and sends it. The packet descriptor is added - * to the given send ring, for potential resends later on. - */ -int queue_packet(int sock_fd, proxy_desc_t *cur, char *buf, size_t bufsiz, - uint32_t dest_ip, uint32_t dest_port, uint32_t state) -{ - int pkt_len = sizeof(icmp_echo_packet_t) + - sizeof(ping_tunnel_pkt_t) + bufsiz; - int err = 0; - icmp_echo_packet_t *pkt = 0; - ping_tunnel_pkt_t *pt_pkt = 0; - uint16_t ack_val; - uint8_t * icmp_chksm_ptr; - - assert(sock_fd >= 0); - assert(cur); - if (sock_fd < 0 || !cur) - return -1; - - ack_val = cur->next_remote_seq - 1; - - if (pkt_len % 2) - pkt_len++; - - pkt = (icmp_echo_packet_t *) calloc(1, pkt_len); - /* ICMP Echo request or reply */ - pkt->type = cur->pkt_type; - /* Must be zero (non-zero requires root) */ - pkt->code = 0; - pkt->identifier = htons(cur->icmp_id); - pkt->seq = htons(cur->ping_seq); - pkt->checksum = 0; - cur->ping_seq++; - /* Add our information */ - pt_pkt = (ping_tunnel_pkt_t*)pkt->data; - pt_pkt->magic = htonl(opts.magic); - pt_pkt->dst_ip = dest_ip; - pt_pkt->dst_port = htonl(dest_port); - pt_pkt->ack = htonl(ack_val); - pt_pkt->data_len = htonl(bufsiz); - pt_pkt->state = htonl(state); - pt_pkt->seq_no = htons(cur->my_seq); - pt_pkt->id_no = htons(cur->id_no); - /* Copy user data */ - if (buf && bufsiz > 0) - memcpy(pt_pkt->data, buf, bufsiz); - icmp_chksm_ptr = (uint8_t*)pkt; - pkt->checksum = htons(calc_icmp_checksum((uint16_t*)icmp_chksm_ptr, pkt_len)); - - /* Send it! */ - pt_log(kLog_sendrecv, "Send: %4d [%4d] bytes " - "[id = 0x%04X] [seq = %d] " - "[seq_no = %d] [type = %s] " - "[ack = %d] [icmp = %d] " - "[user = %s]\n", - pkt_len, bufsiz, - cur->icmp_id, cur->ping_seq, - cur->my_seq, state_name[state & (~kFlag_mask)], - ack_val, cur->pkt_type, - ((state & kUser_flag) == kUser_flag ? "yes" : "no")); - log_sendrecv_hexstr("SEND ICMP", pkt, sizeof(*pkt)); - log_sendrecv_hexstr("SEND PTNG", pt_pkt, sizeof(*pt_pkt)); - if (pkt_len - (pt_pkt->data - (char *)pkt) > 0) { - log_sendrecv_hexstr("SEND PAYL", pt_pkt->data, pkt_len - (pt_pkt->data - (char *)pkt)); - } - - err = sendto(sock_fd, (const void*)pkt, pkt_len, 0, - (struct sockaddr*)&cur->dest_addr, sizeof(struct sockaddr)); - if (err < 0) { - pt_log(kLog_error, "Failed to send ICMP packet: %s\n", strerror(errno)); - free(pkt); - return -1; - } - else if (err != pkt_len) - pt_log(kLog_error, "WARNING WARNING, didn't send entire packet\n"); - - /* Update sequence no's and so on */ - cur->send_ring[cur->send_idx].pkt = pkt; - cur->send_ring[cur->send_idx].pkt_len = pkt_len; - cur->send_ring[cur->send_idx].last_resend = time_as_double(); - cur->send_ring[cur->send_idx].seq_no = cur->my_seq; - cur->send_ring[cur->send_idx].icmp_id = cur->icmp_id; - cur->my_seq++; - if (!cur->send_ring[cur->send_first_ack].pkt) - cur->send_first_ack = cur->send_idx; - cur->send_wait_ack++; - cur->send_idx++; - if (cur->send_idx >= cur->window_size) - cur->send_idx = 0; - return 0; -} - -/* send_packets: - * Examines the passed-in ring, and forwards data in it over TCP. - */ -uint32_t send_packets(forward_desc_t *ring[], int *xfer_idx, int *await_send, int *sock, uint16_t window_size) { - forward_desc_t *fwd_desc; - int bytes, total = 0; - - while (*await_send > 0) { - fwd_desc = ring[*xfer_idx]; - if (!fwd_desc)/* We haven't got this packet yet.. */ - break; - if (fwd_desc->length > 0) { - bytes = send(*sock, &fwd_desc->data[fwd_desc->length - fwd_desc->remaining], - fwd_desc->remaining, 0); - if (bytes < 0) { - printf("Weirdness.\n"); - /* TODO: send close stuff */ - close(*sock); - *sock = 0; - break; - } - fwd_desc->remaining -= bytes; - total += bytes; - } - if (!fwd_desc->remaining) { - ring[*xfer_idx] = 0; - free(fwd_desc); - (*xfer_idx)++; - (*await_send)--; - if (*xfer_idx >= window_size) - *xfer_idx = 0; - } - else - break; - } - return total; -} diff --git a/src/pdesc.h b/src/pdesc.h index 62740df..fbd9c7c 100644 --- a/src/pdesc.h +++ b/src/pdesc.h @@ -1,188 +1,12 @@ -/* - * pdesc.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - #ifndef PDESC_H -#define PDESC_H 1 +#define PDESC_H #include <stdint.h> -#ifndef WIN32 -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif - -#include "pkt.h" -#include "challenge.h" -#include "pconfig.h" - -/** forward_desc_t: Describes a piece of that needs to be forwarded. This - * structure is used for receiving data from the network, and for subsequent - * forwarding over TCP: - * - * 1. Client sends data to proxy over ICMP - * 2. Proxy receives the data, and puts it into a forward_desc_t - * 3. The proxy starts send()-ing the data over the TCP socket to the destination, - * decreasing forward_desc_t->remaining with the number of bytes transferred. - * 4. Once remaining reaches 0, the forward_desc_t is removed from the receive - * ring. - * - * The same procedure is followed in proxy-to-client communication. Just replace - * proxy with client and vice versa in the list above. - */ -typedef struct forward_desc_t { - /** ping_tunnel_pkt_t seq_no */ - uint16_t seq_no; - /** length of data */ - uint16_t length; - /** amount of data not yet transferred */ - size_t remaining; - char data[0]; -} forward_desc_t; - -/** icmp_desc_t: This structure is used to track the ICMP packets sent by either - * the client or proxy. The last_resend variable is used to prevent resending - * the packet too often. Once the packet is acknowledged by the remote end, - * it will be removed from the send-ring, freeing up space for more outgoing - * ICMP packets. - */ -typedef struct icmp_desc_t { - /** total length of ICMP packet, including ICMP header and ptunnel data. */ - uint16_t pkt_len; - double last_resend; - uint16_t seq_no; - uint16_t icmp_id; - icmp_echo_packet_t * pkt; -} icmp_desc_t; - -/** xfer_stats_t: Various transfer statistics, such as bytes sent and received, - * number of ping packets sent/received, etc. - */ -typedef struct xfer_stats_t { - double bytes_in; - double bytes_out; - uint32_t icmp_in; - uint32_t icmp_out; - uint32_t icmp_resent; - uint32_t icmp_ack_out; -} xfer_stats_t; - -/** proxy_desc_t: This massive structure describes a tunnel instance. - */ -typedef struct proxy_desc_t { - /** ICMP or UDP socket */ - int sock; - /** number of bytes in receive buffer */ - int bytes; - /** set to true once this instance should be removed */ - int should_remove; - /** data buffer, used to receive ping and pong packets */ - char * buf; - uint16_t id_no; - uint16_t my_seq; - uint16_t ping_seq; - uint16_t next_remote_seq; - uint16_t pkt_type; - uint16_t remote_ack_val; - uint16_t icmp_id; - /** first available slot in recv ring */ - int recv_idx; - /** current slot in recv ring being transferred */ - int recv_xfer_idx; - /** first available slot in send ring */ - int send_idx; - /** first packet in send ring not yet acked */ - int send_first_ack; - /** number of items in recv ring awaiting send */ - int recv_wait_send; - /** number of items in send ring awaiting ack */ - int send_wait_ack; - int next_resend_start; - int authenticated; - /** Contains the challenge, if used. */ - challenge_t * challenge; - /** Protocol state */ - uint32_t state; - /** Either kProxy_flag or kUser_flag */ - enum pkt_flag type_flag; - /** IP and port to which data should be forwarded. */ - uint32_t dst_ip; - uint32_t dst_port; - /** Same as above */ - struct sockaddr_in dest_addr; - /** Time when last ack packet was sent. */ - double last_ack; - /** Time when a packet was last received. */ - double last_activity; - double last_data_activity; - uint16_t window_size; - double ack_interval; - double resend_interval; - icmp_desc_t * send_ring; - forward_desc_t ** recv_ring; - xfer_stats_t xfer; - struct proxy_desc_t * next; -} proxy_desc_t; - -proxy_desc_t * create_and_insert_proxy_desc(uint16_t id_no, - uint16_t icmp_id, - int sock, - struct sockaddr_in * addr, - uint32_t dst_ip, - uint32_t dst_port, - uint32_t init_state, - enum pkt_flag type); - -void remove_proxy_desc(proxy_desc_t * cur, proxy_desc_t * prev); - -void remove_proxy_desc_rings(proxy_desc_t * cur); - -forward_desc_t * create_fwd_desc(uint16_t seq_no, uint32_t data_len, char * data); - -int queue_packet( - int sock_fd, proxy_desc_t * cur, char * buf, size_t bufsiz, uint32_t dest_ip, uint32_t dest_port, uint32_t state); -uint32_t send_packets(forward_desc_t * ring[], int * xfer_idx, int * await_send, int * sock, uint16_t window_size); +struct pdesc +{ + uint16_t identifier; + uint16_t sequence; +}; #endif diff --git a/src/pkt.c b/src/pkt.c deleted file mode 100644 index 64feabf..0000000 --- a/src/pkt.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * pkt.c - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifndef WIN32 -#include <netinet/in.h> -#include <arpa/inet.h> -#include <pthread.h> -#endif -#include <sys/time.h> - -#include "ptunnel.h" -#include "pkt.h" -#include "pdesc.h" -#include "options.h" -#include "utils.h" - -static proxy_desc_t * handle_incoming_tunnel_request(unsigned bytes, - struct sockaddr_in * addr, - int icmp_sock, - icmp_echo_packet_t * const pkt, - ping_tunnel_pkt_t * const pt_pkt) -{ - struct timeval tt; - struct in_addr in_addr; - uint32_t init_state; - proxy_desc_t * cur; - - pt_log(kLog_info, "Incoming tunnel request from %s.\n", inet_ntoa(*(struct in_addr *)&addr->sin_addr)); - - gettimeofday(&tt, 0); - if (tt.tv_sec < seq_expiry_tbl[pt_pkt->id_no]) { - pt_log(kLog_verbose, "Dropping request: ID was recently in use.\n"); - return NULL; - } - - in_addr.s_addr = pt_pkt->dst_ip; - pt_log(kLog_info, - "Starting new session to %s:%d with ID %d\n", - inet_ntoa(in_addr), - ntohl(pt_pkt->dst_port), - pt_pkt->id_no); - - if ((opts.restrict_dst_ip && opts.given_dst_ip && opts.given_dst_ip != pt_pkt->dst_ip) || - (opts.restrict_dst_port && (uint32_t)-1 != opts.given_dst_port && - opts.given_dst_port != ntohl(pt_pkt->dst_port))) { - pt_log(kLog_info, "Destination administratively prohibited!\n"); - return NULL; - } - - if (opts.password) { - init_state = kProto_authenticate; - } else { - init_state = kProto_data; - } - - cur = (proxy_desc_t *)create_and_insert_proxy_desc( - pt_pkt->id_no, pkt->identifier, 0, addr, pt_pkt->dst_ip, ntohl(pt_pkt->dst_port), init_state, kProxy_flag); - if (!cur) { - /* if failed, abort. Logging is done in create_insert_proxy_desc */ - pt_log(kLog_error, "Failed to create proxy descriptor!\n"); - return NULL; - } - if (pt_pkt->data_len > 0) { - handle_data(pkt, bytes, cur); - } - if (init_state == kProto_authenticate) { - pt_log(kLog_debug, "Sending authentication challenge..\n"); - /* Send challenge */ - cur->challenge = generate_challenge(); - memcpy(cur->buf, cur->challenge, sizeof(challenge_t)); - queue_packet(icmp_sock, cur, cur->buf, sizeof(challenge_t), 0, 0, kProto_authenticate | cur->type_flag); - } - - return cur; -} - -static void handle_auth_request(unsigned bytes, - int icmp_sock, - icmp_echo_packet_t * const pkt, - proxy_desc_t * const cur, - challenge_t * const challenge) -{ - if (!opts.password) { - pt_log(kLog_error, - "This proxy requires a password! " - "Please supply one usin g the -x switch.\n"); - send_termination_msg(cur, icmp_sock); - cur->should_remove = 1; - return; - } -#ifdef ENABLE_SHA512 - if (opts.force_sha512) { - pt_log(kLog_debug, "Got authentication challenge - sending SHA512 response\n"); - generate_response_sha512(&challenge->plain, &challenge->digest); - } else -#endif - { - pt_log(kLog_debug, "Got authentication challenge - sending MD5 response\n"); - generate_response_md5(&challenge->plain, &challenge->digest); - } - - memcpy(cur->buf, challenge, sizeof(challenge_t)); - queue_packet(icmp_sock, cur, cur->buf, sizeof(challenge_t), 0, 0, kProto_authenticate | cur->type_flag); - /* We have authenticated locally. - * It's up to the proxy now if it accepts our response or not.. - */ - cur->authenticated = 1; - handle_data(pkt, bytes, cur); -} - -static void handle_auth_response(unsigned bytes, - int icmp_sock, - icmp_echo_packet_t * const pkt, - proxy_desc_t * const cur, - challenge_t * const challenge) -{ - pt_log(kLog_debug, - "Received remote %s challenge response.\n", - (challenge->digest.hash_type == HT_SHA512 ? "SHA512" : "MD5")); - if ((!opts.force_sha512 && challenge->digest.hash_type == HT_MD5 && - validate_challenge_md5(cur->challenge, &challenge->digest)) || -#ifdef ENABLE_SHA512 - (challenge->digest.hash_type == HT_SHA512 && validate_challenge_sha512(cur->challenge, &challenge->digest)) || -#endif - cur->authenticated) { - pt_log(kLog_verbose, "Remote end authenticated successfully.\n"); - /* Authentication has succeeded, so now we can proceed - * to handle incoming TCP data. - */ - cur->authenticated = 1; - cur->state = kProto_data; - /* Insert the packet into the receive ring, to avoid - * confusing the reliab ility mechanism. - */ - handle_data(pkt, bytes, cur); - } else { - pt_log(kLog_info, "Remote end failed authentication.\n"); - send_termination_msg(cur, icmp_sock); - cur->should_remove = 1; - } -} - -static void header_byteorder_ntoh(icmp_echo_packet_t * const icmp_pkt, ping_tunnel_pkt_t * const pt_pkt) -{ - pt_pkt->state = ntohl(pt_pkt->state); - icmp_pkt->identifier = ntohs(icmp_pkt->identifier); - icmp_pkt->seq = ntohs(icmp_pkt->seq); - pt_pkt->id_no = ntohs(pt_pkt->id_no); - pt_pkt->seq_no = ntohs(pt_pkt->seq_no); -} - -static proxy_desc_t * get_proxy_descriptor(uint16_t id_no) -{ - proxy_desc_t * cur; - - /* Find the relevant connection, if it exists */ - pthread_mutex_lock(&chain_lock); - for (cur = chain; cur; cur = cur->next) { - if (cur->id_no == id_no) { - break; - } - } - pthread_mutex_unlock(&chain_lock); - - return cur; -} - -/* handle_proxy_packet: - * Processes incoming ICMP packets for the proxy. The packet can come either from the - * packet capture lib, or from the actual socket or both. - * Input: A buffer pointing at the start of an IP header, the buffer length and the proxy - * descriptor chain. - */ -void handle_packet(char * buf, unsigned bytes, int is_pcap, struct sockaddr_in * addr, int icmp_sock) -{ - ip_packet_t * ip_pkt = NULL; - icmp_echo_packet_t * pkt; - ping_tunnel_pkt_t * pt_pkt; - proxy_desc_t * cur; - int pkt_flag; - enum pkt_flag type_flag, proxy_flag; - challenge_t * challenge; - - proxy_flag = kProxy_flag; - - if (bytes < sizeof(icmp_echo_packet_t) + sizeof(ping_tunnel_pkt_t)) { - pt_log(kLog_verbose, - "Skipping this packet - too short. " - "Expect: %lu+%lu = %lu ; Got: %u\n", - sizeof(icmp_echo_packet_t), - sizeof(ping_tunnel_pkt_t), - sizeof(icmp_echo_packet_t) + sizeof(ping_tunnel_pkt_t), - bytes); - return; - } - - if (opts.udp || opts.unprivileged) { - pkt = (icmp_echo_packet_t *)buf; - pt_pkt = (ping_tunnel_pkt_t *)pkt->data; - } else { - ip_pkt = (ip_packet_t *)buf; - pkt = (icmp_echo_packet_t *)ip_pkt->data; - pt_pkt = (ping_tunnel_pkt_t *)pkt->data; - } - - if (ntohl(pt_pkt->magic) != opts.magic) { - pt_log(kLog_verbose, "Ignored incoming packet. Magic value 0x%X mismatch.\n", ntohl(pt_pkt->magic)); - return; - } - - header_byteorder_ntoh(pkt, pt_pkt); - cur = get_proxy_descriptor(pt_pkt->id_no); - - /* Handle the packet if it comes from "the other end." This is a bit tricky - * to get right, since we receive both our own and the other end's packets. - * Basically, a proxy will accept any packet from a user, regardless if it - * has a valid connection or not. A user will only accept the packet if there - * exists a connection to handle it. - */ - if (cur) { - type_flag = cur->type_flag; - if (type_flag == kProxy_flag) { - cur->icmp_id = pkt->identifier; - cur->ping_seq = pkt->seq; - } - if (!is_pcap) - cur->xfer.icmp_in++; - } else { - type_flag = kProxy_flag; - } - - pkt_flag = (int)pt_pkt->state & kFlag_mask; - pt_pkt->state &= ~kFlag_mask; - if (pt_pkt->state > (kNum_proto_types - 1)) { - pt_log(kLog_error, "Dropping packet with invalid state.\n"); - return; - } - - pt_log(kLog_sendrecv, - "Recv: %4d [%4d] bytes " - "[id = 0x%04X] [seq = %d] " - "[seq_no = %d] [type = %s] " - "[ack = %d] [icmp = %d] " - "[user = %s] [pcap = %d]\n", - bytes, - ntohl(pt_pkt->data_len), - pkt->identifier, - ntohs(pkt->seq), - pt_pkt->seq_no, - state_name[pt_pkt->state & (~kFlag_mask)], - ntohl(pt_pkt->ack), - pkt->type, - (pkt_flag == kUser_flag ? "yes" : "no"), - is_pcap); - log_sendrecv_hexstr("RECV ICMP", pkt, sizeof(*pkt)); - log_sendrecv_hexstr("RECV PTNG", pt_pkt, sizeof(*pt_pkt)); - if (bytes - (pt_pkt->data - buf) > 0) { - log_sendrecv_hexstr("RECV PAYL", pt_pkt->data, bytes - (pt_pkt->data - buf)); - } - - /* This test essentially verifies that the packet comes from someone who isn't us. */ - if ((pkt_flag == kUser_flag && type_flag == proxy_flag) || (pkt_flag == proxy_flag && type_flag == kUser_flag)) { - pt_pkt->data_len = ntohl(pt_pkt->data_len); - pt_pkt->ack = ntohl(pt_pkt->ack); - if (pt_pkt->state == kProxy_start) { - if (!cur && type_flag == proxy_flag) { - cur = handle_incoming_tunnel_request(bytes, addr, icmp_sock, pkt, pt_pkt); - if (!cur) { - return; - } - } else if (type_flag == kUser_flag) { - pt_log(kLog_error, "Dropping proxy session request - we are not a proxy!\n"); - return; - } else { - pt_log(kLog_error, - "Dropping duplicate proxy session request " - "with ID %d and seq %d.\n", - pt_pkt->id_no, - pt_pkt->seq_no); - } - } else if (cur && pt_pkt->state == kProto_authenticate) { - /* Sanity check packet length, and make sure it matches what we expect */ - if (pt_pkt->data_len != sizeof(challenge_t)) { - pt_log(kLog_error, - "Received challenge packet, but data length " - "is not as expected.\n"); - pt_log(kLog_debug, "Data length: %u Expected: %lu\n", pt_pkt->data_len, sizeof(challenge_t)); - cur->should_remove = 1; - return; - } - /* Prevent packet data from being forwarded over TCP! */ - pt_pkt->data_len = 0; - challenge = (challenge_t *)pt_pkt->data; - /* If client: Compute response to challenge */ - if (type_flag == kUser_flag) { - /* Required for integration tests w/ passwd set. */ - pt_log(kLog_debug, "AUTH-REQUEST: Received ack-series starting at seq %d\n", pt_pkt->seq_no); - handle_auth_request(bytes, icmp_sock, pkt, cur, challenge); - return; - } - /* If proxy: Handle client's response to challenge */ - else if (type_flag == proxy_flag) { - cur->next_remote_seq++; - handle_auth_response(bytes, icmp_sock, pkt, cur, challenge); - return; - } - } - /* Handle close-messages for connections we know about */ - if (cur && pt_pkt->state == kProto_close) { - pt_log(kLog_info, "Received session close from remote peer.\n"); - cur->should_remove = 1; - return; - } - /* The proxy will ignore any other packets from the client - * until it has been authenticated. The packet resend mechanism - * insures that this isn't problematic. - */ - if (type_flag == proxy_flag && opts.password && cur && !cur->authenticated) { - pt_log(kLog_debug, - "Ignoring packet with seq-no %d " - "- not authenticated yet.\n", - pt_pkt->seq_no); - return; - } - - if (cur && cur->sock) { - double now = time_as_double(); - if (pt_pkt->state != kProto_ack) { - cur->last_data_activity = now; - } - if (pt_pkt->state == kProto_data || pt_pkt->state == kProxy_start || pt_pkt->state == kProto_ack) { - if (pt_pkt->state == kProxy_start) { - pt_pkt->data_len = 0; - } - handle_data(pkt, bytes, cur); - } - handle_ack(pt_pkt->ack, cur); - cur->last_activity = now; - } - } -} - -static void queue_payload_data(ping_tunnel_pkt_t * const pt_pkt, proxy_desc_t * const cur) -{ - /* Check if we should add payload data to the queue. */ - if (!cur->recv_ring[cur->recv_idx] && pt_pkt->state == kProto_data) { - pt_log(kLog_debug, "Queing data packet: %d\n", pt_pkt->seq_no); - cur->recv_ring[cur->recv_idx] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); - cur->recv_wait_send++; - cur->recv_idx++; - } else { - pt_log(kLog_debug, "Dup packet for %d ?\n", pt_pkt->seq_no); - } - - cur->next_remote_seq++; - if (cur->recv_idx >= cur->window_size) { - cur->recv_idx = 0; - } - - /* Check if we have already received some of the next packets. */ - while (cur->recv_ring[cur->recv_idx]) { - if (cur->recv_ring[cur->recv_idx]->seq_no == cur->next_remote_seq) { - cur->next_remote_seq++; - cur->recv_idx++; - if (cur->recv_idx >= cur->window_size) { - cur->recv_idx = 0; - } - } else { - break; - } - } -} - -static void queue_payload_data_out_of_order(ping_tunnel_pkt_t * const pt_pkt, proxy_desc_t * const cur) -{ - int r, s, d, pos; - pos = -1; /* If pos ends up staying -1, packet is discarded. */ - r = cur->next_remote_seq; - s = pt_pkt->seq_no; - d = s - r; - if (d < 0) { /* This packet _may_ be old, or seq_no may have wrapped around */ - d = (s + 0xFFFF) - r; - if (cur->window_size && d < cur->window_size) { - /* Counter has wrapped, so we should add this packet to the recv ring */ - pos = (cur->recv_idx + d) % cur->window_size; - } - } else if (cur->window_size && d < cur->window_size) { - pos = (cur->recv_idx + d) % cur->window_size; - } - - if (pos != -1) { - if (!cur->recv_ring[pos]) { - pt_log(kLog_verbose, - "Out of order. Expected: %d Got: %d Inserted: %d " - "(cur = %d)\n", - cur->next_remote_seq, - pt_pkt->seq_no, - pos, - cur->recv_idx); - cur->recv_ring[pos] = create_fwd_desc(pt_pkt->seq_no, pt_pkt->data_len, pt_pkt->data); - cur->recv_wait_send++; - } - } else { - pt_log(kLog_info, "Packet discarded - outside receive window.\n"); - } -} - -/* handle_data: - * Utility function for handling kProto_data packets, and place the data it contains - * onto the passed-in receive ring. - */ -void handle_data(icmp_echo_packet_t * pkt, int total_len, proxy_desc_t * cur) -{ - ping_tunnel_pkt_t * pt_pkt = (ping_tunnel_pkt_t *)pkt->data; - int expected_len = sizeof(ip_packet_t) + sizeof(icmp_echo_packet_t) + sizeof(ping_tunnel_pkt_t); /* 20+8+28 */ - /* Place packet in the receive ring, in its proper place. - * This works as follows: - * -1. Packet == ack packet? Perform ack, and continue. - * 0. seq_no < next_remote_seq, and absolute difference is bigger than w size => discard - * 1. If seq_no == next_remote_seq, we have no problems; just put it in the ring. - * 2. If seq_no > next_remote_seq + remaining window size, discard packet. - * Send resend request for missing packets. - * 3. Else, put packet in the proper place in the ring - * (don't overwrite if one is already there), but don't increment next_remote_seq_no - * 4. If packed was not discarded, process ack info in packet. - */ - expected_len += pt_pkt->data_len; - expected_len += expected_len % 2; - if (opts.udp || opts.unprivileged) { - expected_len -= sizeof(ip_packet_t); - } - if (total_len < expected_len) { - pt_log(kLog_error, "Packet not completely received: %d Should be: %d.\n", total_len, expected_len); - pt_log(kLog_debug, "Data length: %d Total length: %d\n", pt_pkt->data_len, total_len); - /* just ignore that packet */ - return; - } - - if (pt_pkt->seq_no == cur->next_remote_seq) { - queue_payload_data(pt_pkt, cur); - } else { - queue_payload_data_out_of_order(pt_pkt, cur); - } -} - -void handle_ack(uint32_t seq_no, proxy_desc_t * cur) -{ - if (cur->send_wait_ack > 0) { - int i, can_ack = 0, count = 0; - i = cur->send_idx - 1; - if (i < 0) { - i = cur->window_size - 1; - } - - pt_log(kLog_debug, "Received ack-series starting at seq %d\n", seq_no); - while (count < cur->window_size) { - if (!cur->send_ring[i].pkt) { - break; - } - if (cur->send_ring[i].seq_no == seq_no) { - can_ack = 1; - } else if (!can_ack) { - cur->send_first_ack = i; - } - if (can_ack) { - free(cur->send_ring[i].pkt); - cur->send_ring[i].pkt = 0; - cur->send_ring[i].pkt_len = 0; - cur->send_wait_ack--; - } - i--; - if (i < 0) { - i = cur->window_size - 1; - } - count++; - } - } else { - pt_log(kLog_verbose, - "Dropping superfluous acknowledgement for seq %d " - "(no outstanding packets needing ack.)\n", - seq_no); - } -} diff --git a/src/pkt.h b/src/pkt.h deleted file mode 100644 index 163e7b8..0000000 --- a/src/pkt.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * pkt.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifndef PKT_H -#define PKT_H 1 - -#include <stdint.h> - -#ifndef __MINGW32__ -#define __PTATTR__ __attribute__((packed)) -#else -#define __PTATTR__ __attribute__((packed, gcc_struct)) -#endif - -#ifdef WIN32 -#include <winsock2.h> -typedef int socklen_t; -typedef uint32_t in_addr_t; -#define ETH_ALEN 6 /* Octets in one ethernet addr */ -struct ether_header { - uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ - uint8_t ether_shost[ETH_ALEN]; /* source ether addr */ - uint16_t ether_type; /* packet type ID field */ -} __PTATTR__; -#endif /* WIN32 */ - -/** Resend packets after this interval (in seconds) */ -#define kResend_interval 1.5 - -/** ping_tunnel_pkt_t: This data structure represents the header of a ptunnel - * packet, consisting of a magic number, the tunnel's destination IP and port, - * as well as some other fields. Note that the dest IP and port is only valid - * in packets from the client to the proxy. - */ -typedef struct { - /** magic number, used to identify ptunnel packets. */ - uint32_t magic; - /** destination IP and port (used by proxy to figure */ - uint32_t dst_ip; - /** out where to tunnel to) */ - uint32_t dst_port; - /** current connection state; see constants above. */ - uint32_t state; - /** sequence number of last packet received from other end */ - uint32_t ack; - /** length of data buffer */ - uint32_t data_len; - /** sequence number of this packet */ - uint16_t seq_no; - /** id number, used to separate different tunnels from each other */ - uint16_t id_no; - /** optional data buffer */ - char data[0]; -} __PTATTR__ ping_tunnel_pkt_t; - -/** ip_packet_t: This is basically my own definition of the IP packet, which - * of course complies with the official definition ;) See any good book on IP - * (or even the RFC) for info on the contents of this packet. - */ -typedef struct { - uint8_t vers_ihl; - uint8_t tos; - uint16_t pkt_len; - uint16_t id; - uint16_t flags_frag_offset; - uint8_t ttl; - uint8_t proto; // 1 for ICMP - uint16_t checksum; - uint32_t src_ip; - uint32_t dst_ip; - char data[0]; -} __PTATTR__ ip_packet_t; - -/** icmp_echo_packet_t: This is the definition of a standard ICMP header. The - * ptunnel packets are constructed as follows: - * [ ip header (20 bytes) ] - * [ icmp header (8 bytes) ] - * [ ptunnel header (28 bytes) ] - * - * We actually only create the ICMP and ptunnel headers, the IP header is - * taken care of by the OS. - */ -typedef struct { - uint8_t type; - uint8_t code; - uint16_t checksum; - uint16_t identifier; - uint16_t seq; - char data[0]; -} __PTATTR__ icmp_echo_packet_t; - -typedef struct forward_desc_t forward_desc_t; -typedef struct icmp_desc_t icmp_desc_t; -typedef struct proxy_desc_t proxy_desc_t; - -void handle_packet(char * buf, unsigned bytes, int is_pcap, struct sockaddr_in * addr, int icmp_sock); - -void handle_data(icmp_echo_packet_t * pkt, int total_len, proxy_desc_t * cur); - -void handle_ack(uint32_t seq_no, proxy_desc_t * cur); - -#endif diff --git a/src/ppkt.h b/src/ppkt.h new file mode 100644 index 0000000..83cc78a --- /dev/null +++ b/src/ppkt.h @@ -0,0 +1,20 @@ +#ifndef PPKT_H +#define PPKT_H 1 + +#include <stdint.h> + +#define PPKT_TYPE_DATA 0x0001u + +struct ppkt +{ + uint16_t type; + uint16_t data_size; + uint32_t sequence; + uint8_t data[0]; +}; + +void ppkt_header_prepare(struct ppkt *); + +void ppkt_header_process(struct ppkt *); + +#endif diff --git a/src/psock.c b/src/psock.c new file mode 100644 index 0000000..ca6f95d --- /dev/null +++ b/src/psock.c @@ -0,0 +1,92 @@ +#include "pdesc.h" +#include "psock.h" + +#include <errno.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/epoll.h> +#include <sys/socket.h> +#include <unistd.h> + + +int psock_init(struct psock * psock, size_t max_descriptors) +{ + struct epoll_event ev; + + memset(psock, 0, sizeof(*psock)); + + psock->icmp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (psock->icmp_fd < 0) + { + goto error; + } + + psock->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (psock->epoll_fd < 0) + { + goto error; + } + + ev.events = EPOLLIN; + ev.data.fd = psock->icmp_fd; + if (epoll_ctl(psock->epoll_fd, EPOLL_CTL_ADD, psock->icmp_fd, &ev) != 0) + { + goto error; + } + + psock->remotes.max = max_descriptors; + psock->remotes.used = 0; + psock->remotes.descriptors = (struct pdesc **)calloc(max_descriptors, sizeof(**psock->remotes.descriptors)); + + return 0; +error: + if (errno != 0) + { + perror("[FATAL] psock_init failed"); + } + psock_free(psock); + return -1; +} + +void psock_free(struct psock * psock) +{ + free(psock->remotes.descriptors); + psock->remotes.descriptors = NULL; + psock->remotes.used = 0; + psock->remotes.max = 0; + + close(psock->icmp_fd); + psock->icmp_fd = -1; + + close(psock->epoll_fd); + psock->epoll_fd = -1; +} + +static void psock_handle_events(struct psock * psock) +{ + printf("!!!!!!\n"); +} + +void psock_loop(struct psock * psock) +{ + const int max_events = 32; + struct epoll_event events[max_events]; + + while (1) + { + int nready = epoll_wait(psock->epoll_fd, events, max_events, -1); + + switch (nready) + { + case -1: + break; + case 0: + continue; + default: + psock_handle_events(psock); + break; + } + } +} diff --git a/src/psock.h b/src/psock.h new file mode 100644 index 0000000..6f564de --- /dev/null +++ b/src/psock.h @@ -0,0 +1,27 @@ +#ifndef PSOCK_H +#define PSOCK_H 1 + +#include <stdlib.h> + + +struct pdesc; + +struct psock +{ + int epoll_fd; + int icmp_fd; + struct { + size_t used; + size_t max; + struct pdesc ** descriptors; + } remotes; +}; + + +int psock_init(struct psock *, size_t); + +void psock_free(struct psock *); + +void psock_loop(struct psock *); + +#endif diff --git a/src/ptunnel.c b/src/ptunnel.c index ac6ff4f..d0f5823 100644 --- a/src/ptunnel.c +++ b/src/ptunnel.c @@ -1,871 +1,21 @@ -/* - * ptunnel.c - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stoedle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "ptunnel.h" -#include "options.h" -#include "utils.h" -#include "md5.h" -#ifdef HAVE_SELINUX -#include <selinux/selinux.h> -#endif +#include "psock.h" -#ifndef PACKAGE_STRING -#define PACKAGE_STRING "ptunnel-ng" -#endif +#include <stdio.h> +#include <stdlib.h> -#ifdef WIN32 -#include <tchar.h> -#include <winsock2.h> -/* Map errno (which Winsock doesn't use) to GetLastError; include the code in the strerror */ -#ifdef errno -#undef errno -#endif /* errno */ -#define errno GetLastError() -/** Local error string storage */ -static char errorstr[255]; -static char * print_last_windows_error() { - char last_errorstr[255]; - DWORD last_error = GetLastError(); - memset(last_errorstr, 0, sizeof(last_errorstr)); - FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, last_error, 0, last_errorstr, sizeof(last_errorstr), NULL); - snprintf(errorstr, sizeof(errorstr), "%s (%lu)", last_errorstr, last_error); - return errorstr; -} -#define strerror(x) print_last_windows_error() -#endif /* WIN32 */ - -#ifdef HAVE_NPCAP -static BOOL LoadNpcapDlls() -{ - TCHAR npcap_dir[512]; - UINT len; - len = GetSystemDirectory(npcap_dir, 480); - if (!len) { - pt_log(kLog_error, "Error in GetSystemDirectory: %x", GetLastError()); - return FALSE; - } - _tcscat_s(npcap_dir, 512, _T("\\Npcap")); - if (SetDllDirectory(npcap_dir) == 0) { - pt_log(kLog_error, "Error in SetDllDirectory: %x", GetLastError()); - return FALSE; - } - return TRUE; -} -#endif - -/* globals */ -/** Lock protecting the chain of connections */ -pthread_mutex_t chain_lock; -/** Lock protecting the num_threads variable */ -pthread_mutex_t num_threads_lock; -/** Current thread count */ -int num_threads = 0; -/** Current tunnel count */ -uint32_t num_tunnels = 0; -/** Table indicating when a connection ID is allowable (used by proxy) */ -time_t *seq_expiry_tbl = NULL; - -/* Some buffer constants */ -const int tcp_receive_buf_len = kDefault_buf_size; -const int icmp_receive_buf_len = kDefault_buf_size + kIP_header_size + - kICMP_header_size + sizeof(ping_tunnel_pkt_t); -const int pcap_buf_size = (kDefault_buf_size + kIP_header_size + - kICMP_header_size + sizeof(ping_tunnel_pkt_t)+64)*64; -/** (icmp[icmptype] = icmp-echo || icmp[icmptype] = icmp-echoreply) */ -char pcap_filter_program[] = "icmp"; - -/** The chain of client/proxy connections */ -proxy_desc_t *chain = 0; -const char *state_name[kNum_proto_types] = { "start", "ack ", "data ", - "close", "authenticate" }; - -#ifdef HAVE_PCAP -static void print_pcap_devices(void) { - pcap_if_t *devs, *cur_dev; - pcap_addr_t *cur_addr; - char errbuf[PCAP_ERRBUF_SIZE+1]; - - if (pcap_findalldevs(&devs, errbuf)) { - pt_log(kLog_error, "List all available pcap devices failed: %s.\n", errbuf); - } - printf("Available pcap devices:\n"); - for (cur_dev = devs; cur_dev; cur_dev = cur_dev->next) { - if (cur_dev->description) - printf("\n\t%s%c '%s'\n", cur_dev->name, (cur_dev->addresses ? ':' : ' '), - cur_dev->description); - else - printf("\n\t%s%c\n", cur_dev->name, (cur_dev->addresses ? ':' : ' ')); - for (cur_addr = cur_dev->addresses; cur_addr; cur_addr = cur_addr->next) { - if (cur_addr->addr->sa_family == AF_INET) - printf("\t\t%s\n", inet_ntoa(((struct sockaddr_in*)cur_addr->addr)->sin_addr)); - } - } - pcap_freealldevs(devs); -} -#endif - -/* Let the fun begin! */ -int main(int argc, char *argv[]) { -#ifndef WIN32 - pid_t pid; -#endif -#ifdef WIN32 - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup( wVersionRequested, &wsaData ); - if ( err != 0 ) { - return -1; - } - - if (LOBYTE( wsaData.wVersion ) != 2 || - HIBYTE( wsaData.wVersion ) != 2) - { - WSACleanup(); - return -1; - } -#endif /* WIN32 */ - -#ifdef HAVE_NPCAP - if (!LoadNpcapDlls()) - return -1; -#endif - - memset(opts.md5_password_digest, 0, kMD5_digest_size); - memset(opts.sha512_password_digest, 0, kSHA512_digest_size); - - /* The seq_expiry_tbl is used to prevent the remote ends from prematurely - * re-using a sequence number. - */ - seq_expiry_tbl = (time_t *) calloc(65536, sizeof(time_t)); - - /* Parse options */ - if (parse_options(argc, argv)) - return -1; - - /* Init ptunnel RNG */ - pt_random(); - - if (opts.list_pcap_devices) { -#ifdef HAVE_PCAP - print_pcap_devices(); - return 0; -#else - pt_log(kLog_error, "Pcap not available!\n"); - return 1; -#endif - } - -#ifdef HAVE_PCAP - if (opts.pcap && opts.udp) { - pt_log(kLog_error, "Packet capture is not supported (or needed) when using UDP for transport.\n"); - opts.pcap = 0; - } -#ifdef WIN32 - if (!opts.pcap && !opts.udp) { - pt_log(kLog_info, "Running ptunnel-ng on Windows in ICMP mode without WinPcap/Npcap enabled is not supported and may not work!\n"); - pt_log(kLog_info, "If you encounter problems, install WinPCAP/Npcap from:\n"); - pt_log(kLog_info, "https://www.winpcap.org/install/default.htm or Npcap for WIN10: https://nmap.org/npcap/windows-10.html\n"); - pt_log(kLog_info, "After WinPCAP is installed, you can list pcap devices with: --list-pcap-devices\n"); - } -#endif -#endif - pt_log(kLog_info, "Starting %s.\n", PACKAGE_STRING); - pt_log(kLog_info, "(c) 2004-2011 Daniel Stoedle, <daniels@cs.uit.no>\n"); - pt_log(kLog_info, "(c) 2017-2019 Toni Uhlig, <matzeton@googlemail.com>\n"); -#ifdef WIN32 - pt_log(kLog_info, "Windows version by Mike Miller, <mike@mikeage.net>\n"); -#else - pt_log(kLog_info, "Security features by Sebastien Raveau, <sebastien.raveau@epita.fr>\n"); -#endif - pt_log(kLog_info, "%s.\n", (opts.mode == kMode_forward ? "Relaying packets from incoming TCP streams" : - "Forwarding incoming ping packets over TCP")); - if (opts.udp) - pt_log(kLog_info, "UDP transport enabled.\n"); - - pt_log(kLog_debug, "Destination at %s:%u\n", opts.given_dst_hostname, opts.given_dst_port); - - /* TODO: Maybe give the user the opportunity to bind to certain addresses e.g. 127.0.0.1 ? */ - if (opts.mode == kMode_forward) - pt_log(kLog_debug, "Listen for incoming connections at 0.0.0.0:%u\n", opts.tcp_listen_port); - -#ifndef WIN32 - signal(SIGPIPE, SIG_IGN); - if (opts.use_syslog) { - if (opts.log_file != stdout) { - pt_log(kLog_error, "Logging using syslog overrides the use of a specified logfile (using -f).\n"); - fclose(opts.log_file); - opts.log_file = stdout; - } - openlog("ptunnel", LOG_PID, LOG_USER); - } - if (opts.chroot) { - pt_log(kLog_info, "Restricting file access to %s\n", opts.root_dir); - if (-1 == chdir(opts.root_dir) || -1 == chroot(".") || -1 == chdir("/")) { - pt_log(kLog_error, "chdir/chroot `%s': %s\n", opts.root_dir, strerror(errno)); - exit(1); - } - } - if (opts.daemonize) { - pt_log(kLog_info, "Going to the background.\n"); - if (0 < (pid = fork())) - exit(0); - if (0 > pid) - pt_log(kLog_error, "fork: %s\n", strerror(errno)); - else - if (-1 == setsid()) - pt_log(kLog_error, "setsid: %s\n", strerror(errno)); - else { - if (0 < (pid = fork())) - exit(0); - if (0 > pid) - pt_log(kLog_error, "fork: %s\n", strerror(errno)); - else { - if (NULL != opts.pid_file) { - fprintf(opts.pid_file, "%d\n", getpid()); - fclose(opts.pid_file); - } - if (! freopen("/dev/null", "r", stdin) || - ! freopen("/dev/null", "w", stdout) || - ! freopen("/dev/null", "w", stderr)) - pt_log(kLog_error, "freopen `%s': %s\n", "/dev/null", strerror(errno)); - } - } - } -#endif /* !WIN32 */ - - pthread_mutex_init(&chain_lock, 0); - pthread_mutex_init(&num_threads_lock, 0); - - // Check mode, validate arguments and start either client or proxy. - if (opts.mode == kMode_forward) { - if (!opts.given_proxy_ip || !opts.given_dst_ip || !opts.given_dst_port || !opts.tcp_listen_port) { - printf("One of the options are missing or invalid.\n"); - print_usage(argv[0]); - return -1; - } - pt_forwarder(); - } - else - pt_proxy(0); - -#ifdef WIN32 - WSACleanup(); -#else - if (opts.root_dir) - free(opts.root_dir); -#ifdef HAVE_SELINUX - if (NULL != opts.selinux_context) - free(opts.selinux_context); -#endif -#endif /* WIN32 */ - - pt_log(kLog_info, "ptunnel is exiting.\n"); - return 0; -} - -/** pt_forwarder: - * Sets up a listening TCP socket, and forwards incoming connections - * over ping packets. - */ -void pt_forwarder(void) { - int server_sock, new_sock, sock, yes = 1; - fd_set set; - struct timeval time; - struct sockaddr_in addr, dest_addr; - socklen_t addr_len; - pthread_t pid; - uint16_t rand_id; - struct in_addr in_addr; - - pt_log(kLog_debug, "Starting forwarder..\n"); - /** Open our listening socket */ - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - pt_log(kLog_error, "Failed to create socket: %s\n", strerror(errno)); - return; - } - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &yes, sizeof(int)) == -1) { - pt_log(kLog_error, "Failed to set SO_REUSEADDR option on listening socket: %s\n", strerror(errno)); - close(sock); - return; - } - addr.sin_family = AF_INET; - addr.sin_port = htons(opts.tcp_listen_port); - addr.sin_addr.s_addr = INADDR_ANY; - memset(&(addr.sin_zero), 0, 8); - if (bind(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)) == -1) { - pt_log(kLog_error, "Failed to bind listening socket to port %u: %s\n", opts.tcp_listen_port, strerror(errno)); - close(sock); - return; - } - server_sock = sock; - /* Fill out address structure */ - memset(&dest_addr, 0, sizeof(struct sockaddr_in)); - dest_addr.sin_family = AF_INET; - if (opts.udp) - dest_addr.sin_port = htons(kDNS_port /* dns port.. */); - else - dest_addr.sin_port = 0; - in_addr.s_addr = opts.given_proxy_ip; - dest_addr.sin_addr.s_addr = opts.given_proxy_ip; - pt_log(kLog_verbose, "Proxy IP address: %s\n", inet_ntoa(in_addr)); - - listen(server_sock, 10); - while (1) { - FD_ZERO(&set); - FD_SET(server_sock, &set); - time.tv_sec = 1; - time.tv_usec = 0; - if (select(server_sock+1, &set, 0, 0, &time) > 0) { - pt_log(kLog_info, "Incoming connection.\n"); - addr_len = sizeof(struct sockaddr_in); - new_sock = accept(server_sock, (struct sockaddr*)&addr, &addr_len); - if (new_sock < 0) { - pt_log(kLog_error, "Accepting incoming connection failed.\n"); - continue; - } - pthread_mutex_lock(&num_threads_lock); - if (num_threads <= 0) { - pt_log(kLog_event, "No running proxy thread - starting it.\n"); -#ifndef WIN32 - if (pthread_create(&pid, 0, pt_proxy, 0) != 0) -#else - if (0 == (pid = _beginthreadex(0, 0, pt_proxy, 0, 0, 0))) -#endif - { - pt_log(kLog_error, "Couldn't create thread! Dropping incoming connection.\n"); - close(new_sock); - pthread_mutex_unlock(&num_threads_lock); - continue; - } - } - addr = dest_addr; - rand_id = pt_random(); - create_and_insert_proxy_desc(rand_id, rand_id, new_sock, &addr, opts.given_dst_ip, opts.given_dst_port, kProxy_start, kUser_flag); - pthread_mutex_unlock(&num_threads_lock); - } - } -} - - -int pt_create_udp_socket(int port) { - struct sockaddr_in addr; - int sock, yes = 1; - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - pt_log(kLog_error, "Failed to set create UDP socket..\n"); - return 0; - } - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void*)&yes, sizeof(int)) < 0) { - pt_log(kLog_error, "Failed to set UDP REUSEADDR socket option. (Not fatal, hopefully.)\n"); - close(sock); - return 0; - } -#ifdef SO_REUSEPORT - yes = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const void*)&yes, sizeof(int)) < 0) - pt_log(kLog_error, "Failed to set UDP REUSEPORT socket option. (Not fatal, hopefully.)\n"); -#endif /* SO_REUSEPORT */ - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(port); - if (bind(sock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in)) < 0) { - pt_log(kLog_error, "Failed to bind UDP socket to port %d (try running as root).\n", port); - close(sock); - return 0; - } - return sock; -} - -/* pt_proxy: This function does all the client and proxy stuff. - */ -#ifndef WIN32 -void * pt_proxy(void *args) -#else -unsigned int __stdcall pt_proxy(void *args) -#endif +int main(void) { - (void) args; - - fd_set set; - struct timeval timeout; - int bytes; - struct sockaddr_in addr; - socklen_t addr_len; - int fwd_sock = 0, - max_sock = 0, - idx; - char *buf; - double now, last_status_update = 0.0; - proxy_desc_t *cur, *prev, *tmp; -#ifdef HAVE_PCAP - pcap_info_t pc; - pcap_if_t *alldevs = 0, *pdev; -#endif - xfer_stats_t xfer; -#ifdef HAVE_PCAP - ip_packet_t *pkt; - uint32_t ip; - in_addr_t *adr; -#endif - struct in_addr in_addr; -#ifdef HAVE_ICMPFILTER - struct icmp_filter filt; -#endif - - /* Start the thread, initialize protocol and ring states. */ - pt_log(kLog_debug, "Starting ping proxy..\n"); - if (opts.udp) { - pt_log(kLog_debug, "Creating UDP socket..\n"); - if (opts.mode == kMode_proxy) - fwd_sock = pt_create_udp_socket(kDNS_port); - else - fwd_sock = pt_create_udp_socket(0); - if (!fwd_sock) { - pt_log(kLog_error, "Failed to create UDP socket.\n"); - return 0; - } - } - else { - if (opts.unprivileged) - { - pt_log(kLog_debug, "Attempting to create unprivileged ICMP datagram socket..\n"); - fwd_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); - } else { - pt_log(kLog_debug, "Attempting to create privileged ICMP raw socket..\n"); - fwd_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); -#ifdef HAVE_ICMPFILTER - if (opts.mode == kMode_forward) - filt.data = ~(1<<ICMP_ECHOREPLY); - else - filt.data = ~(1<<ICMP_ECHO); - if (fwd_sock >= 0 && - setsockopt(fwd_sock, SOL_RAW, ICMP_FILTER, &filt, sizeof filt) == -1) - { - pt_log(kLog_error, "setockopt for ICMP_FILTER: %s\n", strerror(errno)); - } -#endif - } - if (fwd_sock < 0) { - pt_log(kLog_error, "Couldn't create %s socket: %s\n", - (opts.unprivileged ? "unprivileged datagram" : - "privileged raw"), strerror(errno)); - return 0; - } - } - max_sock = fwd_sock+1; -#ifdef HAVE_PCAP - if (opts.pcap) { - if (opts.udp) { - pt_log(kLog_error, "Packet capture is not useful with UDP [should not get here!]!\n"); - close(fwd_sock); - return 0; - } - if (!opts.unprivileged) { - memset(&pc, 0, sizeof(pc)); - pt_log(kLog_info, "Initializing pcap.\n"); - pc.pcap_err_buf = (char *) malloc(PCAP_ERRBUF_SIZE); - pc.pcap_data_buf = (char *) malloc(pcap_buf_size); - pc.pcap_desc = pcap_open_live(opts.pcap_device, - pcap_buf_size, 0 /* promiscous */, - 50 /* ms */, pc.pcap_err_buf); - if (pc.pcap_desc) { - if (pcap_lookupnet(opts.pcap_device, &pc.netp, - &pc.netmask, pc.pcap_err_buf) == -1) - { - pt_log(kLog_error, "pcap error: %s\n", pc.pcap_err_buf); - opts.pcap = 0; - } - in_addr.s_addr = pc.netp; - pt_log(kLog_verbose, "Network: %s\n", inet_ntoa(in_addr)); - in_addr.s_addr = pc.netmask; - pt_log(kLog_verbose, "Netmask: %s\n", inet_ntoa(in_addr)); - if (pcap_compile(pc.pcap_desc, &pc.fp, pcap_filter_program, 0, pc.netp) == -1) { - pt_log(kLog_error, "Failed to compile pcap filter program.\n"); - pcap_close(pc.pcap_desc); - opts.pcap = 0; - } - else if (pcap_setfilter(pc.pcap_desc, &pc.fp) == -1) { - pt_log(kLog_error, "Failed to set pcap filter program.\n"); - pcap_close(pc.pcap_desc); - opts.pcap = 0; - } - } - else { - pt_log(kLog_error, "pcap error: %s\n", pc.pcap_err_buf); - opts.pcap = 0; - - if (pcap_findalldevs(&alldevs, pc.pcap_err_buf) == 0) { - idx = 0; - pt_log(kLog_error, "Available pcap devices:\n"); - for (pdev = alldevs; pdev != NULL; pdev = pdev->next) { - pt_log(kLog_error, "[%d] \"%s\": \"%s\"\n", ++idx, - pdev->name, (pdev->description ? pdev->description : "UNKNOWN")); - } - pcap_freealldevs(alldevs); - } - } - pc.pkt_q.head = 0; - pc.pkt_q.tail = 0; - pc.pkt_q.elems = 0; - /* Check if we have succeeded, and free stuff if not */ - if (!opts.pcap) { - pt_log(kLog_error, "There were errors enabling pcap - pcap has been disabled.\n"); - free(pc.pcap_err_buf); - free(pc.pcap_data_buf); - return 0; - } - } - else - pt_log(kLog_info, "pcap disabled since we're running in unprivileged mode.\n"); - } -#endif - - pthread_mutex_lock(&num_threads_lock); - num_threads++; - pthread_mutex_unlock(&num_threads_lock); - - /* Allocate icmp receive buffer */ - buf = (char *) malloc(icmp_receive_buf_len); - - /* Start forwarding :) */ - pt_log(kLog_info, "Ping proxy is listening in %s mode.\n", - (opts.unprivileged ? "unprivileged" : "privileged")); - -#ifndef WIN32 -#ifdef HAVE_SELINUX - if (opts.uid || opts.gid || opts.selinux_context) -#else - if (opts.uid || opts.gid) -#endif - pt_log(kLog_info, "Dropping privileges now.\n"); - if (opts.gid && -1 == setgid(opts.gid)) - pt_log(kLog_error, "setgid(%d): %s\n", opts.gid, strerror(errno)); - if (opts.uid && -1 == setuid(opts.uid)) - pt_log(kLog_error, "setuid(%d): %s\n", opts.uid, strerror(errno)); -#ifdef HAVE_SELINUX - if (opts.selinux) { - if (NULL != opts.selinux_context && -1 == setcon(opts.selinux_context)) - pt_log(kLog_error, "setcon(%s) failed: %s\n", opts.selinux_context, strerror(errno)); - } -#endif -#endif - - while (1) { - FD_ZERO(&set); - FD_SET(fwd_sock, &set); - max_sock = fwd_sock+1; - pthread_mutex_lock(&chain_lock); - for (cur = chain; cur; cur = cur->next) { - /* Only handle traffic if there is traffic on the socket, we have - * room in our send window AND we either don't use a password, or - * have been authenticated. - */ - if (cur->sock && cur->send_wait_ack < cur->window_size && - (!opts.password || cur->authenticated)) - { - FD_SET(cur->sock, &set); - if (cur->sock >= max_sock) - max_sock = cur->sock+1; - } - } - pthread_mutex_unlock(&chain_lock); - timeout.tv_sec = 0; - timeout.tv_usec = 10000; - /* Don't care about return val, since we need to check for new states anyway.. */ - select(max_sock, &set, 0, 0, &timeout); + struct psock psock = {}; - pthread_mutex_lock(&chain_lock); - for (prev = 0, cur = chain; cur && cur->sock; cur = tmp) { - /* Client: If we're starting up, send a message to the remote end saying so, - * causing him to connect to our desired endpoint. - */ - if (cur->state == kProxy_start) { - pt_log(kLog_verbose, "Sending proxy request.\n"); - cur->last_ack = time_as_double(); - queue_packet(fwd_sock, cur, NULL, 0, cur->dst_ip, cur->dst_port, cur->state | cur->type_flag); - cur->xfer.icmp_out++; - cur->state = kProto_data; - } - if (cur->should_remove) { - pt_log(kLog_info, "\nSession statistics:\n"); - print_statistics(&cur->xfer, 0); - pt_log(kLog_info, "\n"); - tmp = cur->next; - remove_proxy_desc(cur, prev); - continue; - } - /* Handle TCP traffic */ - if (FD_ISSET(cur->sock, &set)) { - bytes = recv(cur->sock, cur->buf, tcp_receive_buf_len, 0); - if (bytes <= 0) { - pt_log(kLog_info, "Connection closed or lost.\n"); - tmp = cur->next; - send_termination_msg(cur, fwd_sock); - pt_log(kLog_info, "Session statistics:\n"); - print_statistics(&cur->xfer, 0); - remove_proxy_desc(cur, prev); - /* No need to update prev */ - continue; - } - cur->xfer.bytes_out += bytes; - cur->xfer.icmp_out++; - queue_packet(fwd_sock, cur, cur->buf, bytes, 0, 0, cur->state | cur->type_flag); - } - prev = cur; - tmp = cur->next; - } - pthread_mutex_unlock(&chain_lock); + if (psock_init(&psock, 16) != 0) + { + return 1; + } - if (FD_ISSET(fwd_sock, &set)) { - /* Handle ping traffic */ - addr_len = sizeof(struct sockaddr); - bytes = recvfrom(fwd_sock, buf, icmp_receive_buf_len, 0, (struct sockaddr*)&addr, &addr_len); - if (bytes < 0) { - pt_log(kLog_error, "Error receiving packet on ICMP socket: %s\n", strerror(errno)); - break; - } - handle_packet(buf, bytes, 0, &addr, fwd_sock); - } - - /* Check for packets needing resend, and figure out if any connections - * should be closed down due to inactivity. - */ - pthread_mutex_lock(&chain_lock); - now = time_as_double(); - for (cur = chain; cur; cur = cur->next) { - in_addr.s_addr = cur->dst_ip; - if (cur->last_activity + kAutomatic_close_timeout < now) { - pt_log(kLog_info, "Dropping tunnel %u to %s:%u due to inactivity.\n", cur->id_no, inet_ntoa(in_addr), cur->dst_port); - cur->should_remove = 1; - continue; - } - if (cur->recv_wait_send && cur->sock) - cur->xfer.bytes_in += send_packets(cur->recv_ring, &cur->recv_xfer_idx, &cur->recv_wait_send, &cur->sock, cur->window_size); - - /* Check for any icmp packets requiring resend, and resend _only_ the first packet. */ - idx = cur->send_first_ack; - if (cur->send_ring[idx].pkt && cur->send_ring[idx].last_resend+cur->resend_interval < now) { - pt_log(kLog_debug, "Resending packet with seq-no %d.\n", cur->send_ring[idx].seq_no); - cur->send_ring[idx].last_resend = now; - cur->send_ring[idx].pkt->identifier = htons(cur->icmp_id); - cur->send_ring[idx].pkt->seq = htons(cur->ping_seq); - cur->ping_seq++; - cur->send_ring[idx].pkt->checksum = 0; - cur->send_ring[idx].pkt->checksum = htons(calc_icmp_checksum((uint16_t*)cur->send_ring[idx].pkt, cur->send_ring[idx].pkt_len)); - /* printf("ID: %d\n", htons(cur->send_ring[idx].pkt->identifier)); */ - sendto(fwd_sock, (const void*)cur->send_ring[idx].pkt, cur->send_ring[idx].pkt_len, - 0, (struct sockaddr*)&cur->dest_addr, sizeof(struct sockaddr)); - cur->xfer.icmp_resent++; - } - /* Figure out if it's time to send an explicit acknowledgement */ - if (cur->last_ack+cur->ack_interval < now && cur->send_wait_ack < cur->window_size && - cur->remote_ack_val+1 != cur->next_remote_seq) - { - queue_packet(fwd_sock, cur, NULL, 0, cur->dst_ip, cur->dst_port, kProto_ack | cur->type_flag); - cur->last_ack = now; - cur->xfer.icmp_ack_out++; - } - } - pthread_mutex_unlock(&chain_lock); -#ifdef HAVE_PCAP - if (opts.pcap) { - if (pcap_dispatch(pc.pcap_desc, 32, pcap_packet_handler, (u_char*)&pc.pkt_q) > 0) { - pqueue_elem_t *cur; - pt_log(kLog_verbose, "pcap captured %d packets - handling them..\n", pc.pkt_q.elems); - while (pc.pkt_q.head) { - cur = pc.pkt_q.head; - memset(&addr, 0, sizeof(struct sockaddr)); - addr.sin_family = AF_INET; - pkt = (ip_packet_t*)&cur->data[0]; - ip = pkt->src_ip; - adr = (in_addr_t*)&ip; - addr.sin_addr.s_addr = *adr; - handle_packet(cur->data, cur->bytes, 1, &addr, fwd_sock); - pc.pkt_q.head = cur->next; - free(cur); - pc.pkt_q.elems--; - } - pc.pkt_q.tail = 0; - pc.pkt_q.head = 0; - } - } -#endif - /* Update running statistics, if requested (only once every second) */ - if (opts.print_stats && opts.mode == kMode_forward && now > last_status_update+1) { - pthread_mutex_lock(&chain_lock); - memset(&xfer, 0, sizeof(xfer_stats_t)); - for (cur = chain; cur; cur = cur->next) { - xfer.bytes_in += cur->xfer.bytes_in; - xfer.bytes_out += cur->xfer.bytes_out; - xfer.icmp_in += cur->xfer.icmp_in; - xfer.icmp_out += cur->xfer.icmp_out; - xfer.icmp_resent += cur->xfer.icmp_resent; - } - pthread_mutex_unlock(&chain_lock); - print_statistics(&xfer, (opts.log_level >= kLog_verbose ? 0 : 1)); - last_status_update = now; - } - } - pt_log(kLog_debug, "Proxy exiting..\n"); - if (fwd_sock) - close(fwd_sock); - /* TODO: Clean up the other descs. Not really a priority since there's no - * real way to quit ptunnel in the first place.. - */ - free(buf); - pt_log(kLog_debug, "Ping proxy done\n"); - return 0; -} - -/* print_statistics: Prints transfer statistics for the given xfer block. The - * is_continuous variable controls the output mode, either printing a new line - * or overwriting the old line. - */ -void print_statistics(xfer_stats_t *xfer, int is_continuous) { - const double mb = 1024.0*1024.0; - double loss = 0.0; - - if (xfer->icmp_out > 0) - loss = (double)xfer->icmp_resent/(double)xfer->icmp_out; - - if (is_continuous) - printf("\r"); - - printf("[inf]: I/O: %6.2f/%6.2f mb ICMP I/O/R: %8u/%8u/%8u Loss: %4.1f%%", - xfer->bytes_in/mb, xfer->bytes_out/mb, xfer->icmp_in, xfer->icmp_out, xfer->icmp_resent, loss); - - if (!is_continuous) - printf("\n"); - else - fflush(stdout); -} - -#ifdef HAVE_PCAP -/* pcap_packet_handler: - * This is our callback function handling captured packets. We already know that the packets - * are ICMP echo or echo-reply messages, so all we need to do is strip off the ethernet header - * and append it to the queue descriptor (the refcon argument). - * - * Ok, the above isn't entirely correct (we can get other ICMP types as well). This function - * also has problems when it captures packets on the loopback interface. The moral of the - * story: Don't do ping forwarding over the loopback interface. - * - * Also, we currently don't support anything else than ethernet when in pcap mode. The reason - * is that I haven't read up on yet on how to remove the frame header from the packet.. - */ -void pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, const u_char* pkt) { - pqueue_t *q; - pqueue_elem_t *elem; - ip_packet_t *ip; - - /* pt_log(kLog_verbose, "Packet handler: %d =? %d\n", hdr->caplen, hdr->len); */ - q = (pqueue_t*)refcon; - elem = (pqueue_elem_t *) malloc(sizeof(pqueue_elem_t)+hdr->caplen-sizeof(struct ether_header)); - memcpy(elem->data, pkt+sizeof(struct ether_header), hdr->caplen-sizeof(struct ether_header)); - ip = (ip_packet_t*)elem->data; - /* TODO: Add fragment support */ - elem->bytes = ntohs(ip->pkt_len); - if (elem->bytes > hdr->caplen-sizeof(struct ether_header)) { - pt_log(kLog_error, "Received fragmented packet - unable to reconstruct!\n"); - pt_log(kLog_error, "This error usually occurs because pcap is used on " - "devices that are not wlan or ethernet.\n"); - free(elem); - return; - } - /* elem->bytes = hdr->caplen-sizeof(struct ether_header); */ - elem->next = 0; - if (q->tail) { - q->tail->next = elem; - q->tail = elem; - } - else { - q->head = elem; - q->tail = elem; - } - q->elems++; -} -#endif - -uint16_t calc_icmp_checksum(uint16_t *data, int bytes) { - uint32_t sum; - int i; - - sum = 0; - for (i = 0; i < bytes / 2; i++) { - /* WARNING; this might be a bug, but might explain why I occasionally - * see buggy checksums.. (added htons, that might be the correct behaviour) - */ - sum += data[i]; - } - sum = (sum & 0xFFFF) + (sum >> 16); - sum = htons(0xFFFF - sum); - return sum; -} + psock_loop(&psock); -/* send_termination_msg: Sends two packets to the remote end, informing it that - * the tunnel is being closed down. - */ -void send_termination_msg(proxy_desc_t *cur, int icmp_sock) { - size_t i; - const size_t max_termination_msgs = 3; + psock_free(&psock); - /* Send packet twice, hoping at least one of them makes it through.. */ - for (i = 0; i < max_termination_msgs; ++i) { - queue_packet(icmp_sock, cur, NULL, 0, cur->dst_ip, cur->dst_port, kProto_close | cur->type_flag); - } - cur->xfer.icmp_out += max_termination_msgs; + return 0; } diff --git a/src/ptunnel.h b/src/ptunnel.h deleted file mode 100644 index 9917f81..0000000 --- a/src/ptunnel.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ptunnel.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stoedle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifndef PING_TUNNEL_H -#define PING_TUNNEL_H 1 - -#ifndef WIN32 -#ifdef HAVE_ICMPFILTER -#include <linux/icmp.h> -#endif -#ifdef HAVE_SYS_UNISTD_H -#include <sys/unistd.h> -#endif -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <pthread.h> -#include <errno.h> -#include <net/ethernet.h> -#include <syslog.h> -#include <pwd.h> -#include <grp.h> -#endif /* !WIN32 */ -#include <stdarg.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <signal.h> -#include <stdint.h> -#include <stdbool.h> -#ifdef HAVE_PCAP -#include <pcap.h> -#endif - -#include "pkt.h" -#include "pdesc.h" -#include "challenge.h" - -#ifdef WIN32 -/* pthread porting to windows */ -typedef CRITICAL_SECTION pthread_mutex_t; -typedef unsigned long pthread_t; -#define pthread_mutex_init InitializeCriticalSectionAndSpinCount -#define pthread_mutex_lock EnterCriticalSection -#define pthread_mutex_unlock LeaveCriticalSection -#endif -extern pthread_mutex_t chain_lock; -extern uint32_t num_tunnels; -extern const int icmp_receive_buf_len; -extern proxy_desc_t *chain; -extern time_t *seq_expiry_tbl; -extern const char *state_name[kNum_proto_types]; - -/* pt_thread_info_t: A simple (very simple, in fact) structure that allows us - * to pass an arbitrary number of params to the threads we create. Currently, - * that's just one single parameter: The socket which the thread should listen - * to. - */ -typedef struct { - int sock; -} pt_thread_info_t; - -#ifdef HAVE_PCAP -/* pqueue_elem_t: An queue element in the pqueue structure (below). - */ -typedef struct pqueue_elem_t { - /** size of data buffer */ - unsigned long bytes; - /** next queue element (if any) */ - struct pqueue_elem_t *next; - /** optional data */ - char data[0]; -} pqueue_elem_t; - -/* pqueue_t: A simple queue strucutre. - */ -typedef struct { - pqueue_elem_t *head; - pqueue_elem_t *tail; - int elems; -} pqueue_t; - -/* pcap_info_t: Structure to hold information related to packet capturing. - */ -typedef struct { - pcap_t *pcap_desc; - /** compiled filter program */ - struct bpf_program fp; - uint32_t netp; - uint32_t netmask; - /** buffers for error info */ - char *pcap_err_buf; - /** buffers for packet info */ - char *pcap_data_buf; - /** queue of packets to process */ - pqueue_t pkt_q; -} pcap_info_t; -#endif - -/* function Prototypes */ -#ifndef WIN32 -void * pt_proxy(void *args); -#else -unsigned int __stdcall pt_proxy(void *args); -#endif - -#ifdef HAVE_PCAP -void pcap_packet_handler(u_char *refcon, const struct pcap_pkthdr *hdr, - const u_char* pkt); -#endif - -void pt_forwarder(void); - -void print_statistics(xfer_stats_t *xfer, int is_continuous); - -uint16_t calc_icmp_checksum(uint16_t *data, int bytes); - -void send_termination_msg(proxy_desc_t *cur, int icmp_sock); - -#endif diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index 7426ce1..0000000 --- a/src/utils.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * utils.c - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <string.h> -#include <time.h> -#ifdef HAVE_BSD_STDLIB_H -#include <bsd/stdlib.h> -#endif - -#ifndef WIN32 -#include <errno.h> -#include <syslog.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#else -#include <ws2tcpip.h> -#endif -#include <sys/time.h> - -#include "utils.h" -#include "options.h" - -void pt_log(enum log_level level, const char * fmt, ...) -{ - va_list args; - const char * header[] = {"[err]: ", "[inf]: ", "[evt]: ", "[vbs]: ", "[dbg]: ", "[xfr]: "}; -#ifndef WIN32 - int syslog_levels[] = {LOG_ERR, LOG_NOTICE, LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_DEBUG}; -#endif /* !WIN32 */ - - if (level <= opts.log_level) { - va_start(args, fmt); -#ifndef WIN32 - if (opts.use_syslog) { - char log[255]; - int header_len; - header_len = snprintf(log, sizeof(log), "%s", header[level]); - vsnprintf(log + header_len, sizeof(log) - header_len, fmt, args); - syslog(syslog_levels[level], "%s", log); - } else -#endif /* !WIN32 */ - fprintf(opts.log_file, "%s", header[level]), vfprintf(opts.log_file, fmt, args); - va_end(args); -#ifndef WIN32 - if (opts.log_file != stdout && !opts.use_syslog) -#else - if (opts.log_file != stdout) -#endif - fflush(opts.log_file); - } -} - -double time_as_double(void) -{ - double result; - struct timeval tt; - - gettimeofday(&tt, 0); - result = (double)tt.tv_sec + ((double)tt.tv_usec / (double)10e5); - return result; -} - -int host_to_addr(const char * hostname, uint32_t * result) -{ - int ret; - struct addrinfo * addrs = NULL; - struct addrinfo hints; - struct sockaddr_in * addr; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - - if ((ret = getaddrinfo(hostname, NULL, &hints, &addrs)) != 0) - return ret; - addr = (struct sockaddr_in *)addrs->ai_addr; - *result = *(uint32_t *)&addr->sin_addr; - freeaddrinfo(addrs); - - return 0; -} - -static const char hextab[] = "0123456789ABCDEF"; - -void log_sendrecv_hexstr(const char *prefix, void *buf, size_t siz) { - if (opts.log_level != kLog_sendrecv) { - return; - } - - const size_t outsiz = siz * 3; - - if (outsiz + 1 > BUFSIZ) { - pt_log(kLog_error, "Can not print hex string with size %zu: too big\n", siz); - return; - } - - char out[outsiz + 1]; - unsigned char high, low; - - size_t i, j; - for (i = 0, j = 0; j < siz && i < outsiz; i += 3, ++j) { - high = (((unsigned char *)buf)[j] & 0xF0) >> 4; - low = ((unsigned char *)buf)[j] & 0x0F; - out[i ] = hextab[high]; - out[i+1] = hextab[low]; - out[i+2] = ' '; - } - out[i] = '\0'; - - pt_log(kLog_sendrecv, "%s[HEX]: %s\n", prefix, out); -} - -int pt_random(void) -{ -#if defined(HAVE_ARC4RANDOM) || defined(__COVERITY__) - return arc4random(); -#else -#if defined(RNGDEV) && !defined(_WIN32) - static int rng_fd = -1; - ssize_t bytes_read; - int rnd_val; - if (rng_fd < 0) { - rng_fd = open(RNGDEV, O_RDONLY); - if (rng_fd < 0) { - pt_log(kLog_error, "FATAL: Could not open random device '%s': %s\n", RNGDEV, strerror(errno)); - exit(EXIT_FAILURE); - } - } - bytes_read = read(rng_fd, &rnd_val, sizeof rnd_val); - if (bytes_read != sizeof rnd_val) { - if (bytes_read < 0) - pt_log(kLog_error, "FATAL: Read from random device failed: %s\n", strerror(errno)); - else - pt_log(kLog_error, "FATAL: Read only %zd bytes (wanted %zd bytes)\n", bytes_read, sizeof rnd_val); - exit(EXIT_FAILURE); - } - return rnd_val; -#else - srand(time(0)); - return rand(); -#endif -#endif -} diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index b019454..0000000 --- a/src/utils.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * utils.h - * ptunnel is licensed under the BSD license: - * - * Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>, - * Yellow Lemon Software. All rights reserved. - * - * Copyright (c) 2017-2019, Toni Uhlig <matzeton@googlemail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the Yellow Lemon Software 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - * - * Contacting the author: - * You can get in touch with me, Daniel Stødle (that's the Norwegian letter oe, - * in case your text editor didn't realize), here: <daniels@cs.uit.no> - * - * The official ptunnel website is here: - * <http://www.cs.uit.no/~daniels/PingTunnel/> - * - * Note that the source code is best viewed with tabs set to 4 spaces. - */ - -#ifndef UTILS_H -#define UTILS_H 1 - -#include <stdlib.h> -#include <stdint.h> - -#include "pconfig.h" - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - -void pt_log(enum log_level level, const char * fmt, ...); - -double time_as_double(void); - -int host_to_addr(const char * hostname, uint32_t * result); - -void log_sendrecv_hexstr(const char * prefix, void *buf, size_t siz); - -int pt_random(void); - -#endif diff --git a/src/win32/includes/bittypes.h b/src/win32/includes/bittypes.h deleted file mode 100644 index 558a0b5..0000000 --- a/src/win32/includes/bittypes.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 1999 WIDE Project. - * 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 project 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 PROJECT 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 PROJECT 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. - */ -#ifndef _BITTYPES_H -#define _BITTYPES_H - -#ifndef HAVE_U_INT8_T - -#if SIZEOF_CHAR == 1 -typedef unsigned char u_int8_t; -typedef signed char int8_t; -#elif SIZEOF_INT == 1 -typedef unsigned int u_int8_t; -typedef signed int int8_t; -#else /* XXX */ -#error "there's no appropriate type for u_int8_t" -#endif -#define HAVE_U_INT8_T 1 -#define HAVE_INT8_T 1 - -#endif /* HAVE_U_INT8_T */ - -#ifndef HAVE_U_INT16_T - -#if SIZEOF_SHORT == 2 -typedef unsigned short u_int16_t; -typedef signed short int16_t; -#elif SIZEOF_INT == 2 -typedef unsigned int u_int16_t; -typedef signed int int16_t; -#elif SIZEOF_CHAR == 2 -typedef unsigned char u_int16_t; -typedef signed char int16_t; -#else /* XXX */ -#error "there's no appropriate type for u_int16_t" -#endif -#define HAVE_U_INT16_T 1 -#define HAVE_INT16_T 1 - -#endif /* HAVE_U_INT16_T */ - -#ifndef HAVE_U_INT32_T - -#if SIZEOF_INT == 4 -typedef unsigned int u_int32_t; -typedef signed int int32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long u_int32_t; -typedef signed long int32_t; -#elif SIZEOF_SHORT == 4 -typedef unsigned short u_int32_t; -typedef signed short int32_t; -#else /* XXX */ -#error "there's no appropriate type for u_int32_t" -#endif -#define HAVE_U_INT32_T 1 -#define HAVE_INT32_T 1 - -#endif /* HAVE_U_INT32_T */ - -#ifndef HAVE_U_INT64_T -#if SIZEOF_LONG_LONG == 8 -typedef unsigned long long u_int64_t; -typedef long long int64_t; -#elif defined(_MSC_EXTENSIONS) -typedef unsigned _int64 u_int64_t; -typedef _int64 int64_t; -#elif SIZEOF_INT == 8 -typedef unsigned int u_int64_t; -#elif SIZEOF_LONG == 8 -typedef unsigned long u_int64_t; -#elif SIZEOF_SHORT == 8 -typedef unsigned short u_int64_t; -#else /* XXX */ -#error "there's no appropriate type for u_int64_t" -#endif - -#endif /* HAVE_U_INT64_T */ - -#ifndef PRId64 -#ifdef _MSC_EXTENSIONS -#define PRId64 "I64d" -#else /* _MSC_EXTENSIONS */ -#define PRId64 "lld" -#endif /* _MSC_EXTENSIONS */ -#endif /* PRId64 */ - -#ifndef PRIo64 -#ifdef _MSC_EXTENSIONS -#define PRIo64 "I64o" -#else /* _MSC_EXTENSIONS */ -#define PRIo64 "llo" -#endif /* _MSC_EXTENSIONS */ -#endif /* PRIo64 */ - -#ifndef PRIx64 -#ifdef _MSC_EXTENSIONS -#define PRIx64 "I64x" -#else /* _MSC_EXTENSIONS */ -#define PRIx64 "llx" -#endif /* _MSC_EXTENSIONS */ -#endif /* PRIx64 */ - -#ifndef PRIu64 -#ifdef _MSC_EXTENSIONS -#define PRIu64 "I64u" -#else /* _MSC_EXTENSIONS */ -#define PRIu64 "llu" -#endif /* _MSC_EXTENSIONS */ -#endif /* PRIu64 */ - -#endif /* _BITTYPES_H */ diff --git a/src/win32/includes/pcap-stdinc.h b/src/win32/includes/pcap-stdinc.h deleted file mode 100644 index 4176041..0000000 --- a/src/win32/includes/pcap-stdinc.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) - * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California) - * 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 Politecnico di Torino 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 COPYRIGHT HOLDERS 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 COPYRIGHT - * OWNER 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. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL) - */ - -#define SIZEOF_CHAR 1 -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 -#ifndef _MSC_EXTENSIONS -#define SIZEOF_LONG_LONG 8 -#endif - -/* - * Avoids a compiler warning in case this was already defined - * (someone defined _WINSOCKAPI_ when including 'windows.h', in order - * to prevent it from including 'winsock.h') - */ -#ifdef _WINSOCKAPI_ -#undef _WINSOCKAPI_ -#endif -#include <winsock2.h> - -#include <fcntl.h> - -#include "bittypes.h" -#include <time.h> -#include <io.h> - -#ifndef __MINGW32__ -#include "IP6_misc.h" -#endif - -#define caddr_t char* - -#if _MSC_VER < 1500 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strdup _strdup -#endif - -#define inline __inline - -#ifdef __MINGW32__ -#include <stdint.h> -#else /*__MINGW32__*/ -/* MSVC compiler */ -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef _W64 unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif - -#ifndef _INTPTR_T_DEFINED -#ifdef _WIN64 -typedef __int64 intptr_t; -#else -typedef _W64 int intptr_t; -#endif -#define _INTPTR_T_DEFINED -#endif - -#endif /*__MINGW32__*/ diff --git a/src/win32/includes/pcap.h b/src/win32/includes/pcap.h deleted file mode 100644 index 935f949..0000000 --- a/src/win32/includes/pcap.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006/10/04 18:09:22 guy Exp $ (LBL) - */ - -/* - * For backwards compatibility. - * - * Note to OS vendors: do NOT get rid of this file! Many applications - * expect to be able to include <pcap.h>, and at least some of them - * go through contortions in their configure scripts to try to detect - * OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without - * leaving behind a <pcap.h> file. - */ -#include <pcap/pcap.h> diff --git a/src/win32/includes/pcap/bpf.h b/src/win32/includes/pcap/bpf.h deleted file mode 100644 index 9f4ca33..0000000 --- a/src/win32/includes/pcap/bpf.h +++ /dev/null @@ -1,934 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. 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 BY THE REGENTS 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 REGENTS 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. - * - * @(#)bpf.h 7.1 (Berkeley) 5/7/91 - * - * @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.19.2.8 2008-09-22 20:16:01 guy Exp $ (LBL) - */ - -/* - * This is libpcap's cut-down version of bpf.h; it includes only - * the stuff needed for the code generator and the userland BPF - * interpreter, and the libpcap APIs for setting filters, etc.. - * - * "pcap-bpf.c" will include the native OS version, as it deals with - * the OS's BPF implementation. - * - * XXX - should this all just be moved to "pcap.h"? - */ - -#ifndef BPF_MAJOR_VERSION - -#ifdef __cplusplus -extern "C" { -#endif - -/* BSD style release date */ -#define BPF_RELEASE 199606 - -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -/* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. - */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) - -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 - -/* - * Structure for "pcap_compile()", "pcap_setfilter()", etc.. - */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - -/* - * Struct return by BIOCVERSION. This represents the version number of - * the filter language described by the instruction encodings below. - * bpf understands a program iff kernel_major == filter_major && - * kernel_minor >= filter_minor, that is, if the value returned by the - * running kernel has the same major number and a minor number equal - * equal to or less than the filter being downloaded. Otherwise, the - * results are undefined, meaning an error may be returned or packets - * may be accepted haphazardly. - * It has nothing to do with the source code version. - */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; -/* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 - -/* - * Data-link level type codes. - * - * Do *NOT* add new values to this list without asking - * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run - * the risk of using a value that's already being used for some other - * purpose, and of having tools that read libpcap-format captures not - * being able to handle captures with your new DLT_ value, with no hope - * that they will ever be changed to do so (as that would destroy their - * ability to read captures using that value for that other purpose). - */ - -/* - * These are the types that are the same on all platforms, and that - * have been defined by <net/bpf.h> for ages. - */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ - -/* - * These are types that are different on some platforms, and that - * have been defined by <net/bpf.h> for ages. We use #ifdefs to - * detect the BSDs that define them differently from the traditional - * libpcap <net/bpf.h> - * - * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, - * but I don't know what the right #define is for BSD/OS. - */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ - -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif - -/* - * Given that the only OS that currently generates BSD/OS SLIP or PPP - * is, well, BSD/OS, arguably everybody should have chosen its values - * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they - * didn't. So it goes. - */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif - -/* - * 17 is used for DLT_OLD_PFLOG in OpenBSD; - * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below. - * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. - */ - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * Apparently Redback uses this for its SmartEdge 400/800. I hope - * nobody else decided to use it, too. - */ -#define DLT_REDBACK_SMARTEDGE 32 - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses - * a link-layer type of 99 for the tcpdump it supplies. The link-layer - * header has 6 bytes of unknown data, something that appears to be an - * Ethernet type, and 36 bytes that appear to be 0 in at least one capture - * I've seen. - */ -#define DLT_SYMANTEC_FIREWALL 99 - -/* - * Values between 100 and 103 are used in capture file headers as - * link-layer types corresponding to DLT_ types that differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, - * except when it isn't. (I.e., sometimes it's just raw IP, and - * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, - * so that we don't have to worry about the link-layer header.) - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so - * we don't use 12 for it in OSes other than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif - -/* - * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's - * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif - -/* - * Values between 110 and 112 are reserved for use in capture file headers - * as link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ types - * other than the corresponding DLT_ types. - */ - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 - * in SuSE 6.3, so we can't use 17 for it in capture-file headers. - * - * XXX: is there a conflict with DLT_PFSYNC 18 as well? - */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * For 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Reserved for Siemens HiPath HDLC. - */ -#define DLT_HHDLC 121 - -/* - * This is for RFC 2625 IP-over-Fibre Channel. - * - * This is not for use with raw Fibre Channel, where the link-layer - * header starts with a Fibre Channel frame header; it's for IP-over-FC, - * where the link-layer header starts with an RFC 2625 Network_Header - * field. - */ -#define DLT_IP_OVER_FC 122 - -/* - * This is for Full Frontal ATM on Solaris with SunATM, with a - * pseudo-header followed by an AALn PDU. - * - * There may be other forms of Full Frontal ATM on other OSes, - * with different pseudo-headers. - * - * If ATM software returns a pseudo-header with VPI/VCI information - * (and, ideally, packet type information, e.g. signalling, ILMI, - * LANE, LLC-multiplexed traffic, etc.), it should not use - * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump - * and the like don't have to infer the presence or absence of a - * pseudo-header and the form of the pseudo-header. - */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ - -/* - * Reserved as per request from Kent Dahlgren <kent@praesum.com> - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * Header for 802.11 plus a number of bits of link-layer information - * including radio information, used by some recent BSD drivers as - * well as the madwifi Atheros driver for Linux. - */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ - -/* - * Reserved for the TZSP encapsulation, as per request from - * Chris Waters <chris.waters@networkchemistry.com> - * TZSP is a generic encapsulation for any other link type, - * which includes a means to include meta-information - * with the packet, e.g. signal strength and channel - * for 802.11 packets. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * BSD's ARCNET headers have the source host, destination host, - * and type at the beginning of the packet; that's what's handed - * up to userland via BPF. - * - * Linux's ARCNET headers, however, have a 2-byte offset field - * between the host IDs and the type; that's what's handed up - * to userland via PF_PACKET sockets. - * - * We therefore have to have separate DLT_ values for them. - */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ - -/* - * Juniper-private data link types, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 - -/* - * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund - * <dieter@apple.com>. The header that's presented is an Ethernet-like - * header: - * - * #define FIREWIRE_EUI64_LEN 8 - * struct firewire_header { - * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - * u_char firewire_shost[FIREWIRE_EUI64_LEN]; - * u_short firewire_type; - * }; - * - * with "firewire_type" being an Ethernet type value, rather than, - * for example, raw GASP frames being handed up. - */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 - -/* - * Various SS7 encapsulations, as per a request from Jeff Morriss - * <jeff.morriss[AT]ulticom.com> and subsequent discussions. - */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ - -/* - * DOCSIS MAC frames. - */ -#define DLT_DOCSIS 143 - -/* - * Linux-IrDA packets. Protocol defined at http://www.irda.org. - * Those packets include IrLAP headers and above (IrLMP...), but - * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy - * framing can be handled by the hardware and depend on the bitrate. - * This is exactly the format you would get capturing on a Linux-IrDA - * interface (irdaX), but not on a raw serial port. - * Note the capture is done in "Linux-cooked" mode, so each packet include - * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or - * outgoing). - * When/if other platform implement IrDA capture, we may revisit the - * issue and define a real DLT_IRDA... - * Jean II - */ -#define DLT_LINUX_IRDA 144 - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that DLT_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, - * as per the comment above, and use the type you're given. - */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but it might be used by some non-AVS drivers now or in the - * future. - */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MONITOR 164 - -/* - * Reserved for BACnet MS/TP. - */ -#define DLT_BACNET_MS_TP 165 - -/* - * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>. - * - * This is used in some OSes to allow a kernel socket filter to distinguish - * between incoming and outgoing packets, on a socket intended to - * supply pppd with outgoing packets so it can do dial-on-demand and - * hangup-on-lack-of-demand; incoming packets are filtered out so they - * don't cause pppd to hold the connection up (you don't want random - * input packets such as port scans, packets from old lost connections, - * etc. to force the connection to stay up). - * - * The first byte of the PPP header (0xff03) is modified to accomodate - * the direction - 0x00 = IN, 0x01 = OUT. - */ -#define DLT_PPP_PPPD 166 - -/* - * Names for backwards compatibility with older versions of some PPP - * software; new software should use DLT_PPP_PPPD. - */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, cookies, etc.. - */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 - -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ - -/* - * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line - * monitoring equipment. - */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_ is used - * for internal communication to Physical Interface Cards (PIC) - */ -#define DLT_JUNIPER_PIC_PEER 174 - -/* - * Link types requested by Gregor Maier <gregor@endace.com> of Endace - * Measurement Systems. They add an ERF header (see - * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of - * the link-layer header. - */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ - -/* - * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD - * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header - * includes additional information before the LAPD header, so it's - * not necessarily a generic LAPD header. - */ -#define DLT_LINUX_LAPD 177 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ are used for prepending meta-information - * like interface index, interface name - * before standard Ethernet, PPP, Frelay & C-HDLC Frames - */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 - -/* - * Multi Link Frame Relay (FRF.16) - */ -#define DLT_MFR 182 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ is used for internal communication with a - * voice Adapter Card (PIC) - */ -#define DLT_JUNIPER_VP 183 - -/* - * Arinc 429 frames. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - * Every frame contains a 32bit A429 label. - * More documentation on Arinc 429 can be found at - * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf - */ -#define DLT_A429 184 - -/* - * Arinc 653 Interpartition Communication messages. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - * Please refer to the A653-1 standard for more information. - */ -#define DLT_A653_ICM 185 - -/* - * USB packets, beginning with a USB setup header; requested by - * Paolo Abeni <paolo.abeni@email.it>. - */ -#define DLT_USB 186 - -/* - * Bluetooth HCI UART transport layer (part H:4); requested by - * Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4 187 - -/* - * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz - * <cruz_petagay@bah.com>. - */ -#define DLT_IEEE802_16_MAC_CPS 188 - -/* - * USB packets, beginning with a Linux USB header; requested by - * Paolo Abeni <paolo.abeni@email.it>. - */ -#define DLT_USB_LINUX 189 - -/* - * Controller Area Network (CAN) v. 2.0B packets. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - * Used to dump CAN packets coming from a CAN Vector board. - * More documentation on the CAN v2.0B frames can be found at - * http://www.can-cia.org/downloads/?269 - */ -#define DLT_CAN20B 190 - -/* - * IEEE 802.15.4, with address fields padded, as is done by Linux - * drivers; requested by Juergen Schimmer. - */ -#define DLT_IEEE802_15_4_LINUX 191 - -/* - * Per Packet Information encapsulated packets. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - */ -#define DLT_PPI 192 - -/* - * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; - * requested by Charles Clancy. - */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ is used for internal communication with a - * integrated service module (ISM). - */ -#define DLT_JUNIPER_ISM 194 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>. - */ -#define DLT_IEEE802_15_4 195 - -/* - * Various link-layer types, with a pseudo-header, for SITA - * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). - */ -#define DLT_SITA 196 - -/* - * Various link-layer types, with a pseudo-header, for Endace DAG cards; - * encapsulates Endace ERF records. Requested by Stephen Donnelly - * <stephen@endace.com>. - */ -#define DLT_ERF 197 - -/* - * Special header prepended to Ethernet packets when capturing from a - * u10 Networks board. Requested by Phil Mulholland - * <phil@u10networks.com>. - */ -#define DLT_RAIF1 198 - -/* - * IPMB packet for IPMI, beginning with the I2C slave address, followed - * by the netFn and LUN, etc.. Requested by Chanthy Toeung - * <chanthy.toeung@ca.kontron.com>. - */ -#define DLT_IPMB 199 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ is used for capturing data on a secure tunnel interface. - */ -#define DLT_JUNIPER_ST 200 - -/* - * Bluetooth HCI UART transport layer (part H:4), with pseudo-header - * that includes direction information; requested by Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 - -/* - * AX.25 packet with a 1-byte KISS header; see - * - * http://www.ax25.net/kiss.htm - * - * as per Richard Stearn <richard@rns-stearn.demon.co.uk>. - */ -#define DLT_AX25_KISS 202 - -/* - * LAPD packets from an ISDN channel, starting with the address field, - * with no pseudo-header. - * Requested by Varuna De Silva <varunax@gmail.com>. - */ -#define DLT_LAPD 203 - -/* - * Variants of various link-layer headers, with a one-byte direction - * pseudo-header prepended - zero means "received by this host", - * non-zero (any non-zero value) means "sent by this host" - as per - * Will Barker <w.barker@zen.co.uk>. - */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ - -/* - * 208 is reserved for an as-yet-unspecified proprietary link-layer - * type, as requested by Will Barker. - */ - -/* - * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman - * <avn@pigeonpoint.com>. - */ -#define DLT_IPMB_LINUX 209 - -/* - * FlexRay automotive bus - http://www.flexray.com/ - as requested - * by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_FLEXRAY 210 - -/* - * Media Oriented Systems Transport (MOST) bus for multimedia - * transport - http://www.mostcooperation.com/ - as requested - * by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_MOST 211 - -/* - * Local Interconnect Network (LIN) bus for vehicle networks - - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber - * <hannes.kaelber@x2e.de>. - */ -#define DLT_LIN 212 - -/* - * X2E-private data link type used for serial line capture, - * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_X2E_SERIAL 213 - -/* - * X2E-private data link type used for the Xoraya data logger - * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_X2E_XORAYA 214 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), but with the PHY-level data for non-ASK PHYs (4 octets - * of 0 as preamble, one octet of SFD, one octet of frame length+ - * reserved bit, and then the MAC-layer data, starting with the - * frame control field). - * - * Requested by Max Filippov <jcmvbkbc@gmail.com>. - */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 - - -/* - * DLT and savefile link type values are split into a class and - * a member of that class. A class value of 0 indicates a regular - * DLT_/LINKTYPE_ value. - */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) - -/* - * NetBSD-specific generic "raw" link type. The class value indicates - * that this is the generic raw type, and the lower 16 bits are the - * address family we're dealing with. Those values are NetBSD-specific; - * do not assume that they correspond to AF_ values for your operating - * system. - */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) - - -/* - * The instruction encodings. - */ -/* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 - -/* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 - -/* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 - -/* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 - -/* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 - -/* - * The instruction data structure. - */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; - -/* - * Macros for insn array initializers. - */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } - -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(const struct bpf_insn *, int); -extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif - -/* - * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). - */ -#define BPF_MEMWORDS 16 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/win32/includes/pcap/pcap.h b/src/win32/includes/pcap/pcap.h deleted file mode 100644 index ad8fc40..0000000 --- a/src/win32/includes/pcap/pcap.h +++ /dev/null @@ -1,407 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL) - */ - -#ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h - -#if defined(WIN32) - #include <pcap-stdinc.h> -#elif defined(MSDOS) - #include <sys/types.h> - #include <sys/socket.h> /* u_int, u_char etc. */ -#else /* UN*X */ - #include <sys/types.h> - #include <sys/time.h> -#endif /* WIN32/MSDOS/UN*X */ - -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include <pcap/bpf.h> -#endif - -#include <stdio.h> - -#ifdef HAVE_REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 - -#define PCAP_ERRBUF_SIZE 256 - -/* - * Compatibility for systems that have a bpf.h that - * predates the bpf typedefs for 64-bit support. - */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; - -/* - * The first record in the file contains saved values for some - * of the flags used in the printout phases of tcpdump. - * Many fields here are 32 bit ints so compilers won't insert unwanted - * padding; these files need to be interchangeable across architectures. - * - * Do not change the layout of this structure, in any way (this includes - * changes that only affect the length of fields in this structure). - * - * Also, do not change the interpretation of any of the members of this - * structure, in any way (this includes using values other than - * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" - * field). - * - * Instead: - * - * introduce a new structure for the new format, if the layout - * of the structure changed; - * - * send mail to "tcpdump-workers@lists.tcpdump.org", requesting - * a new magic number for your new capture file format, and, when - * you get the new magic number, put it in "savefile.c"; - * - * use that magic number for save files with the changed file - * header; - * - * make the code in "savefile.c" capable of reading files with - * the old file header as well as files with the new file header - * (using the magic number to determine the header format). - * - * Then supply the changes as a patch at - * - * http://sourceforge.net/projects/libpcap/ - * - * so that future versions of libpcap and programs that use it (such as - * tcpdump) will be able to read your new capture file format. - */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; - -/* - * Macros for the value returned by pcap_datalink_ext(). - * - * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro - * gives the FCS length of packets in the capture. - */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) - -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; - -/* - * Generic per-packet information, as supplied by libpcap. - * - * The time stamp can and should be a "struct timeval", regardless of - * whether your system supports 32-bit tv_sec in "struct timeval", - * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit - * and 64-bit applications. The on-disk format of savefiles uses 32-bit - * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit - * and 64-bit versions of libpcap, even if they're on the same platform, - * should supply the appropriate version of "struct timeval", even if - * that's not what the underlying packet capture mechanism supplies. - */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; - -/* - * As returned by the pcap_stats() - */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef HAVE_REMOTE - u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* HAVE_REMOTE */ -}; - -#ifdef MSDOS -/* - * As returned by the pcap_stats_ex() - */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; - - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ - - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif - -/* - * Item in a list of interfaces. - */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; - -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ - -/* - * Representation of an interface address. - */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; - -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); - -/* - * Error codes for the pcap API. - * These will all be negative, so you can check for the success or - * failure of a call that returns these codes by checking for a - * negative value. - */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ - -/* - * Warning codes for the pcap API. - * These will all be positive and non-zero, so they won't look like - * errors. - */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ - -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); - -pcap_t *pcap_create(const char *, char *); -int pcap_set_snaplen(pcap_t *, int); -int pcap_set_promisc(pcap_t *, int); -int pcap_can_set_rfmon(pcap_t *); -int pcap_set_rfmon(pcap_t *, int); -int pcap_set_timeout(pcap_t *, int); -int pcap_set_buffer_size(pcap_t *, int); -int pcap_activate(pcap_t *); - -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -#if defined(WIN32) -pcap_t *pcap_hopen_offline(intptr_t, char *); -#if !defined(LIBPCAP_EXPORTS) -#define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) -#else /*LIBPCAP_EXPORTS*/ -static pcap_t *pcap_fopen_offline(FILE *, char *); -#endif -#else /*WIN32*/ -pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*WIN32*/ - -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_statustostr(int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -void pcap_perror(pcap_t *, char *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, - const u_char *); -int pcap_datalink(pcap_t *); -int pcap_datalink_ext(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -void pcap_free_datalinks(int *); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); - -/* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); - -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); - -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); - -const char *pcap_lib_version(void); - -/* XXX this guy lives in the bpf tree */ -u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -int bpf_validate(const struct bpf_insn *f, int len); -char *bpf_image(const struct bpf_insn *, int); -void bpf_dump(const struct bpf_program *, int); - -#if defined(WIN32) - -/* - * Win32 definitions - */ - -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); - -#ifdef WPCAP -/* Include file with the wpcap-specific extensions */ -#include <Win32-Extensions.h> -#endif /* WPCAP */ - -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 - -#elif defined(MSDOS) - -/* - * MS-DOS definitions - */ - -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); - -#else /* UN*X */ - -/* - * UN*X definitions - */ - -int pcap_get_selectable_fd(pcap_t *); - -#endif /* WIN32/MSDOS/UN*X */ - -#ifdef HAVE_REMOTE -/* Includes most of the public stuff that is needed for the remote capture */ -#include <remote-ext.h> -#endif /* HAVE_REMOTE */ - -#ifdef __cplusplus -} -#endif - -#endif |