diff options
author | Yossi Neiman <mishehu+sbo@shavedgoats.net> | 2023-10-06 21:56:19 +0800 |
---|---|---|
committer | Willy Sudiarto Raharjo <willysr@slackbuilds.org> | 2023-10-07 15:58:30 +0700 |
commit | 0da014f7b388c97298bf6edec1fbcd352de5313d (patch) | |
tree | e2433ea85e73058d406355c582f870828d868859 /network | |
parent | 5b5fb5874b13e1c64a3dabbae2bd5742727764d0 (diff) |
network/ngrep: Updated for version 1.47.
Signed-off-by: Andrew Clemons <andrew.clemons@gmail.com>
Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
Diffstat (limited to 'network')
-rw-r--r-- | network/ngrep/README | 5 | ||||
-rw-r--r-- | network/ngrep/ngrep-1.45-reasm.diff | 939 | ||||
-rw-r--r-- | network/ngrep/ngrep.SlackBuild | 49 | ||||
-rw-r--r-- | network/ngrep/ngrep.info | 12 | ||||
-rw-r--r-- | network/ngrep/slack-desc | 2 |
5 files changed, 35 insertions, 972 deletions
diff --git a/network/ngrep/README b/network/ngrep/README index c1534b64bf476..b9d5da3356fec 100644 --- a/network/ngrep/README +++ b/network/ngrep/README @@ -9,8 +9,3 @@ and snoop. ngrep is built with IPV6 support by default; to disable it, do this: NGREP_IPV6=no ./ngrep.SlackBuild - -A patch is included for IPV4 and IPV6 packet reassembly applied by -default. The patch adds the -r switch to ngrep. To disable the patch, -do this: - ASSEM_PATCH=no ./ngrep.SlackBuild diff --git a/network/ngrep/ngrep-1.45-reasm.diff b/network/ngrep/ngrep-1.45-reasm.diff deleted file mode 100644 index ed33fb6f651e5..0000000000000 --- a/network/ngrep/ngrep-1.45-reasm.diff +++ /dev/null @@ -1,939 +0,0 @@ -diff -urN ngrep-1.45/ipreasm.c ngrep-1.45-reasm/ipreasm.c ---- ngrep-1.45/ipreasm.c 1970-01-01 01:00:00.000000000 +0100 -+++ ngrep-1.45-reasm/ipreasm.c 2007-06-16 19:17:20.124795623 +0200 -@@ -0,0 +1,717 @@ -+/* -+ * ipreasm -- Routines for reassembly of fragmented IPv4 and IPv6 packets. -+ * -+ * Copyright (c) 2007 Jan Andres <jandres@gmx.net> -+ * -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <stddef.h> -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif /* HAVE_CONFIG_H */ -+ -+#include <netinet/ip.h> -+#include <netinet/udp.h> -+#if USE_IPv6 -+#include <netinet/ip6.h> -+#endif /* USE_IPv6 */ -+ -+#include "ipreasm.h" -+ -+ -+#define REASM_IP_HASH_SIZE 1021U -+ -+ -+enum entry_state { -+ STATE_ACTIVE, -+ STATE_INVALID, -+}; -+ -+ -+enum reasm_proto { -+ PROTO_IPV4, -+#if USE_IPv6 -+ PROTO_IPV6, -+#endif /* USE_IPv6 */ -+}; -+ -+ -+/* -+ * This tuple uniquely identifies all fragments belonging to -+ * the same IPv4 packet. -+ */ -+struct reasm_id_ipv4 { -+ uint8_t ip_src[4], ip_dst[4]; -+ uint16_t ip_id; -+ uint8_t ip_proto; -+}; -+ -+ -+/* -+ * Same for IPv6. -+ */ -+struct reasm_id_ipv6 { -+ uint8_t ip_src[16], ip_dst[16]; -+ uint32_t ip_id; -+}; -+ -+ -+union reasm_id { -+ struct reasm_id_ipv4 ipv4; -+ struct reasm_id_ipv6 ipv6; -+}; -+ -+ -+struct reasm_frag_entry { -+ unsigned len; /* payload length of this fragment */ -+ unsigned offset; /* offset of this fragment into the payload of the reassembled packet */ -+ unsigned data_offset; /* offset to the data pointer where payload starts */ -+ unsigned char *data; /* payload starts at data + data_offset */ -+ struct reasm_frag_entry *next; -+}; -+ -+ -+/* -+ * Reception of a complete packet is detected by counting the number -+ * of "holes" that remain between the cached fragments. A hole is -+ * assumed to exist at the upper end of the packet until the final -+ * fragment has been received. When the number of holes drops to 0, -+ * all fragments have been received and the packet can be reassembled. -+ */ -+struct reasm_ip_entry { -+ union reasm_id id; -+ unsigned len, holes, frag_count, hash; -+ reasm_time_t timeout; -+ enum entry_state state; -+ enum reasm_proto protocol; -+ struct reasm_frag_entry *frags; -+ struct reasm_ip_entry *prev, *next; -+ struct reasm_ip_entry *time_prev, *time_next; -+}; -+ -+ -+/* -+ * This struct contains some metadata, the main hash table, and a pointer -+ * to the first entry that will time out. A linked list is kept in the -+ * order in which packets will time out. Using a linked list for this -+ * purpose requires that packets are input in chronological order, and -+ * that a constant timeout value is used, which doesn't change even when -+ * the entry's state transitions from active to invalid. -+ */ -+struct reasm_ip { -+ struct reasm_ip_entry *table[REASM_IP_HASH_SIZE]; -+ struct reasm_ip_entry *time_first, *time_last; -+ unsigned waiting, max_waiting, timed_out, dropped_frags; -+ reasm_time_t timeout; -+}; -+ -+ -+/* -+ * Hash functions. -+ */ -+static unsigned reasm_ipv4_hash (const struct reasm_id_ipv4 *id); -+#if USE_IPv6 -+static unsigned reasm_ipv6_hash (const struct reasm_id_ipv6 *id); -+#endif /* USE_IPv6 */ -+ -+/* -+ * Insert a new fragment to the correct position in the list of fragments. -+ * Check for fragment overlap and other error conditions. Update the -+ * "hole count". -+ */ -+static bool add_fragment (struct reasm_ip_entry *entry, struct reasm_frag_entry *frag, bool last_frag); -+ -+/* -+ * Is the entry complete, ready for reassembly? -+ */ -+static bool is_complete (struct reasm_ip_entry *entry); -+ -+/* -+ * Create the reassembled packet. -+ */ -+static unsigned char *assemble (struct reasm_ip_entry *entry, unsigned *output_len); -+ -+/* -+ * Drop and free entries. -+ */ -+static void drop_entry (struct reasm_ip *reasm, struct reasm_ip_entry *entry); -+static void free_entry (struct reasm_ip_entry *entry); -+ -+/* -+ * Dispose of any entries which have expired before "now". -+ */ -+static void process_timeouts (struct reasm_ip *reasm, reasm_time_t now); -+ -+/* -+ * Create fragment structure from IPv6 packet. Returns NULL if the input -+ * is not a fragment. -+ * This function is called by parse_packet(), don't call it directly. -+ */ -+#if USE_IPv6 -+static struct reasm_frag_entry *frag_from_ipv6 (unsigned char *packet, uint32_t *ip_id, bool *last_frag); -+#endif /* USE_IPv6 */ -+ -+/* -+ * Compare packet identification tuples for specified protocol. -+ */ -+static bool reasm_id_equal (enum reasm_proto proto, const union reasm_id *left, const union reasm_id *right); -+ -+/* -+ * Create fragment structure from an IPv4 or IPv6 packet. Returns NULL -+ * if the input is not a fragment. -+ */ -+static struct reasm_frag_entry *parse_packet (unsigned char *packet, unsigned len, enum reasm_proto *protocol, union reasm_id *id, unsigned *hash, bool *last_frag); -+ -+ -+static unsigned -+reasm_ipv4_hash (const struct reasm_id_ipv4 *id) -+{ -+ unsigned hash = 0; -+ int i; -+ -+ for (i = 0; i < 4; i++) { -+ hash = 37U * hash + id->ip_src[i]; -+ hash = 37U * hash + id->ip_dst[i]; -+ } -+ -+ hash = 59U * hash + id->ip_id; -+ -+ hash = 47U * hash + id->ip_proto; -+ -+ return hash; -+} -+ -+ -+#if USE_IPv6 -+static unsigned -+reasm_ipv6_hash (const struct reasm_id_ipv6 *id) -+{ -+ unsigned hash = 0; -+ int i; -+ -+ for (i = 0; i < 16; i++) { -+ hash = 37U * hash + id->ip_src[i]; -+ hash = 37U * hash + id->ip_dst[i]; -+ } -+ -+ hash = 59U * hash + id->ip_id; -+ -+ return hash; -+} -+#endif /* USE_IPv6 */ -+ -+ -+unsigned char * -+reasm_ip_next (struct reasm_ip *reasm, unsigned char *packet, unsigned len, reasm_time_t timestamp, unsigned *output_len) -+{ -+ enum reasm_proto proto; -+ union reasm_id id; -+ unsigned hash; -+ bool last_frag; -+ -+ process_timeouts (reasm, timestamp); -+ -+ struct reasm_frag_entry *frag = parse_packet (packet, len, &proto, &id, &hash, &last_frag); -+ if (frag == NULL) { -+ *output_len = len; -+ return packet; /* some packet that we don't recognize as a fragment */ -+ } -+ -+ hash %= REASM_IP_HASH_SIZE; -+ struct reasm_ip_entry *entry = reasm->table[hash]; -+ while (entry != NULL && (proto != entry->protocol || !reasm_id_equal (proto, &id, &entry->id))) -+ entry = entry->next; -+ -+ if (entry == NULL) { -+ entry = malloc (sizeof (*entry)); -+ if (entry == NULL) { -+ free (frag); -+ abort (); -+ } -+ -+ struct reasm_frag_entry *list_head = malloc (sizeof (*list_head)); -+ if (list_head == NULL) { -+ free (frag); -+ free (entry); -+ abort (); -+ } -+ -+ *entry = (struct reasm_ip_entry) { -+ .id = id, -+ .len = 0, -+ .holes = 1, -+ .frags = list_head, -+ .hash = hash, -+ .protocol = proto, -+ .timeout = timestamp + reasm->timeout, -+ .state = STATE_ACTIVE, -+ .prev = NULL, -+ .next = reasm->table[hash], -+ .time_prev = reasm->time_last, -+ .time_next = NULL, -+ }; -+ -+ *list_head = (struct reasm_frag_entry) { -+ .len = 0, -+ .offset = 0, -+ .data_offset = 0, -+ .data = NULL, -+ }; -+ -+ if (entry->next != NULL) -+ entry->next->prev = entry; -+ reasm->table[hash] = entry; -+ -+ if (reasm->time_last != NULL) -+ reasm->time_last->time_next = entry; -+ else -+ reasm->time_first = entry; -+ reasm->time_last = entry; -+ -+ reasm->waiting++; -+ if (reasm->waiting > reasm->max_waiting) -+ reasm->max_waiting = reasm->waiting; -+ } -+ -+ if (entry->state != STATE_ACTIVE) { -+ reasm->dropped_frags++; -+ return NULL; -+ } -+ -+ if (!add_fragment (entry, frag, last_frag)) { -+ entry->state = STATE_INVALID; -+ reasm->dropped_frags += entry->frag_count + 1; -+ return NULL; -+ } -+ -+ if (!is_complete (entry)) -+ return NULL; -+ -+ unsigned char *r = assemble (entry, output_len); -+ drop_entry (reasm, entry); -+ return r; -+} -+ -+ -+static bool -+add_fragment (struct reasm_ip_entry *entry, struct reasm_frag_entry *frag, bool last_frag) -+{ -+ /* -+ * When a fragment is inserted into the list, different cases can occur -+ * concerning the number of holes. -+ * - The new fragment can be inserted in the middle of a hole, such that -+ * it will split the hole in two. The number of holes increases by 1. -+ * - The new fragment can be attached to one end of a hole, such that -+ * the rest of the hole remains at the opposite side of the fragment. -+ * The number of holes remains constant. -+ * - The new fragment can fill a hole completely. The number of holes -+ * decreases by 1. -+ */ -+ -+ /* -+ * If more fragments follow and the payload size is not an integer -+ * multiple of 8, the packet will never be reassembled completely. -+ */ -+ if (!last_frag && (frag->len & 7) != 0) -+ return false; -+ -+ if (entry->len != 0 && frag->len + frag->offset > entry->len) -+ return false; /* fragment extends past end of packet */ -+ -+ bool fit_left = false, fit_right = false; -+ -+ if (last_frag) { -+ if (entry->len != 0) { -+ fprintf (stderr, "* ERROR: Multiple final fragments.\n"); -+ return false; -+ } -+ entry->len = frag->offset + frag->len; -+ fit_right = true; -+ } -+ -+ struct reasm_frag_entry *cur = entry->frags, *next = cur->next; -+ -+ while (cur->next != NULL && cur->next->offset <= frag->offset) -+ cur = cur->next; -+ next = cur->next; -+ -+ /* Fragment is to be inserted between cur and next; next may be NULL. */ -+ -+ /* Overlap checks. */ -+ if (cur->offset + cur->len > frag->offset) -+ return false; /* overlaps with cur */ -+ else if (cur->offset + cur->len == frag->offset) -+ fit_left = true; -+ -+ if (next != NULL) { -+ if (last_frag) -+ return false; /* next extends past end of packet */ -+ if (frag->offset + frag->len > next->offset) -+ return false; /* overlaps with next */ -+ else if (frag->offset + frag->len == next->offset) -+ fit_right = true; -+ } -+ -+ /* -+ * Everything's fine, insert it. -+ */ -+ if (frag->len != 0) { -+ frag->next = cur->next; -+ cur->next = frag; -+ -+ if (fit_left && fit_right) -+ entry->holes--; -+ else if (!fit_left && !fit_right) -+ entry->holes++; -+ -+ entry->frag_count++; -+ } else { -+ /* -+ * If the fragment has zero size, we don't insert it into the list, -+ * but one case remains to be handled: If the zero-size fragment -+ * is the last fragment, and fits exactly with the fragment to its -+ * left, the number of holes decreases. -+ */ -+ if (last_frag && fit_left) -+ entry->holes--; -+ } -+ -+ -+ return true; -+} -+ -+ -+struct reasm_ip * -+reasm_ip_new (void) -+{ -+ struct reasm_ip *reasm = malloc (sizeof (*reasm)); -+ if (reasm == NULL) -+ return NULL; -+ -+ memset (reasm, 0, sizeof (*reasm)); -+ return reasm; -+} -+ -+ -+void -+reasm_ip_free (struct reasm_ip *reasm) -+{ -+ while (reasm->time_first != NULL) -+ drop_entry (reasm, reasm->time_first); -+ free (reasm); -+} -+ -+ -+static bool -+is_complete (struct reasm_ip_entry *entry) -+{ -+ return entry->holes == 0; -+} -+ -+ -+static unsigned char * -+assemble (struct reasm_ip_entry *entry, unsigned *output_len) -+{ -+ struct reasm_frag_entry *frag = entry->frags->next; /* skip list head */ -+ unsigned offset0 = frag->data_offset; -+ unsigned char *p = malloc (entry->len + offset0); -+ if (p == NULL) -+ abort (); -+ -+ switch (entry->protocol) { -+ case PROTO_IPV4: -+ break; -+ -+#if USE_IPv6 -+ case PROTO_IPV6: -+ offset0 -= 8; /* size of frag header */ -+ break; -+#endif /* USE_IPv6 */ -+ -+ default: -+ abort (); -+ } -+ -+ *output_len = entry->len + offset0; -+ -+ /* copy the (unfragmentable) header from the first fragment received */ -+ memcpy (p, frag->data, offset0); -+ -+ /* join all the payload fragments together */ -+ while (frag != NULL) { -+ memcpy (p + offset0 + frag->offset, frag->data + frag->data_offset, frag->len); -+ frag = frag->next; -+ } -+ -+ /* some cleanups, e.g. update the length field of reassembled packet */ -+ switch (entry->protocol) { -+ case PROTO_IPV4: { -+ struct ip *ip_header = (struct ip *) p; -+ ip_header->ip_len = htons (offset0 + entry->len); -+ ip_header->ip_off = 0; -+ // XXX recompute the checksum -+ break; -+ } -+ -+#if USE_IPv6 -+ case PROTO_IPV6: { -+ struct ip6_hdr *ip6_header = (struct ip6_hdr *) p; -+ ip6_header->ip6_plen = htons (offset0 + entry->len - 40); -+ break; -+ } -+#endif /* USE_IPv6 */ -+ -+ default: -+ abort (); -+ } -+ -+ return p; -+} -+ -+ -+static void -+drop_entry (struct reasm_ip *reasm, struct reasm_ip_entry *entry) -+{ -+ if (entry->prev != NULL) -+ entry->prev->next = entry->next; -+ else -+ reasm->table[entry->hash] = entry->next; -+ -+ if (entry->next != NULL) -+ entry->next->prev = entry->prev; -+ -+ if (entry->time_prev != NULL) -+ entry->time_prev->time_next = entry->time_next; -+ else -+ reasm->time_first = entry->time_next; -+ -+ if (entry->time_next != NULL) -+ entry->time_next->time_prev = entry->time_prev; -+ else -+ reasm->time_last = entry->time_prev; -+ -+ reasm->waiting--; -+ -+ free_entry (entry); -+} -+ -+ -+static void -+free_entry (struct reasm_ip_entry *entry) -+{ -+ struct reasm_frag_entry *frag = entry->frags, *next; -+ while (frag != NULL) { -+ next = frag->next; -+ if (frag->data != NULL) -+ free (frag->data); -+ free (frag); -+ frag = next; -+ } -+ -+ free (entry); -+} -+ -+ -+unsigned -+reasm_ip_waiting (const struct reasm_ip *reasm) -+{ -+ return reasm->waiting; -+} -+ -+ -+unsigned -+reasm_ip_max_waiting (const struct reasm_ip *reasm) -+{ -+ return reasm->max_waiting; -+} -+ -+ -+unsigned -+reasm_ip_timed_out (const struct reasm_ip *reasm) -+{ -+ return reasm->timed_out; -+} -+ -+ -+unsigned -+reasm_ip_dropped_frags (const struct reasm_ip *reasm) -+{ -+ return reasm->dropped_frags; -+} -+ -+ -+bool -+reasm_ip_set_timeout (struct reasm_ip *reasm, reasm_time_t timeout) -+{ -+ if (reasm->time_first != NULL) -+ return false; -+ -+ reasm->timeout = timeout; -+ return true; -+} -+ -+ -+static void -+process_timeouts (struct reasm_ip *reasm, reasm_time_t now) -+{ -+ while (reasm->time_first != NULL && reasm->time_first->timeout < now) { -+ reasm->timed_out++; -+ drop_entry (reasm, reasm->time_first); -+ } -+} -+ -+ -+#if USE_IPv6 -+static struct reasm_frag_entry * -+frag_from_ipv6 (unsigned char *packet, uint32_t *ip_id, bool *last_frag) -+{ -+ struct ip6_hdr *ip6_header = (struct ip6_hdr *) packet; -+ unsigned offset = 40; /* IPv6 header size */ -+ uint8_t nxt = ip6_header->ip6_nxt; -+ unsigned total_len = 40 + ntohs (ip6_header->ip6_plen); -+ unsigned last_nxt = offsetof (struct ip6_hdr, ip6_nxt); -+ -+ /* -+ * IPv6 extension headers from RFC 2460: -+ * 0 Hop-by-Hop Options -+ * 43 Routing -+ * 44 Fragment -+ * 60 Destination Options -+ * -+ * We look out for the Fragment header; the other 3 header -+ * types listed above are recognized and considered safe to -+ * skip over if they occur before the Fragment header. -+ * Any unrecognized header will cause processing to stop and -+ * a subsequent Fragment header to stay unrecognized. -+ */ -+ while (nxt == IPPROTO_HOPOPTS || nxt == IPPROTO_ROUTING || nxt == IPPROTO_DSTOPTS) { -+ if (offset + 2 > total_len) -+ return NULL; /* header extends past end of packet */ -+ -+ unsigned exthdr_len = 8 + 8 * packet[offset + 1]; -+ if (offset + exthdr_len > total_len) -+ return NULL; /* header extends past end of packet */ -+ -+ nxt = packet[offset]; -+ last_nxt = offset; -+ offset += exthdr_len; -+ } -+ -+ if (nxt != IPPROTO_FRAGMENT) -+ return NULL; -+ -+ if (offset + 8 > total_len) -+ return NULL; /* Fragment header extends past end of packet */ -+ -+ struct reasm_frag_entry *frag = malloc (sizeof (*frag)); -+ if (frag == NULL) -+ abort (); -+ -+ struct ip6_frag *frag_header = (struct ip6_frag *) (packet + offset); -+ offset += 8; -+ -+ /* -+ * The Fragment header will be removed on reassembly, so we have to -+ * replace the Next Header field of the previous header (which is -+ * currently IPPROTO_FRAGMENT), with the Next Header field of the -+ * Fragment header. -+ * -+ * XXX We really shouldn't manipulate the input packet in-place. -+ */ -+ packet[last_nxt] = frag_header->ip6f_nxt; -+ -+ *frag = (struct reasm_frag_entry) { -+ .len = total_len - offset, -+ .data_offset = offset, -+ .offset = ntohs (frag_header->ip6f_offlg & IP6F_OFF_MASK), -+ .data = packet, -+ }; -+ -+ *ip_id = ntohl (frag_header->ip6f_ident); -+ *last_frag = (frag_header->ip6f_offlg & IP6F_MORE_FRAG) == 0; -+ -+ return frag; -+} -+#endif /* USE_IPv6 */ -+ -+ -+static bool -+reasm_id_equal (enum reasm_proto proto, const union reasm_id *left, const union reasm_id *right) -+{ -+ switch (proto) { -+ case PROTO_IPV4: -+ return memcmp (left->ipv4.ip_src, right->ipv4.ip_src, 4) == 0 -+ && memcmp (left->ipv4.ip_dst, right->ipv4.ip_dst, 4) == 0 -+ && left->ipv4.ip_id == right->ipv4.ip_id -+ && left->ipv4.ip_proto == right->ipv4.ip_proto; -+#if USE_IPv6 -+ case PROTO_IPV6: -+ return memcmp (left->ipv6.ip_src, right->ipv6.ip_src, 16) == 0 -+ && memcmp (left->ipv6.ip_dst, right->ipv6.ip_dst, 16) == 0 -+ && left->ipv6.ip_id == right->ipv6.ip_id; -+#endif /* USE_IPv6 */ -+ default: -+ abort (); -+ } -+} -+ -+ -+static struct reasm_frag_entry * -+parse_packet (unsigned char *packet, unsigned len, enum reasm_proto *protocol, union reasm_id *id, unsigned *hash, bool *last_frag) -+{ -+ struct ip *ip_header = (struct ip *) packet; -+ struct reasm_frag_entry *frag = NULL; -+ -+ switch (ip_header->ip_v) { -+ case 4: { -+ *protocol = PROTO_IPV4; -+ uint16_t offset = ntohs (ip_header->ip_off); -+ if (len >= ntohs (ip_header->ip_len) && (offset & (IP_MF | IP_OFFMASK)) != 0) { -+ frag = malloc (sizeof (*frag)); -+ if (frag == NULL) -+ abort (); -+ -+ *frag = (struct reasm_frag_entry) { -+ .len = ntohs (ip_header->ip_len) - ip_header->ip_hl * 4, -+ .offset = (offset & IP_OFFMASK) * 8, -+ .data_offset = ip_header->ip_hl * 4, -+ .data = packet, -+ }; -+ -+ *last_frag = (offset & IP_MF) == 0; -+ -+ memcpy (id->ipv4.ip_src, &ip_header->ip_src, 4); -+ memcpy (id->ipv4.ip_dst, &ip_header->ip_dst, 4); -+ id->ipv4.ip_id = ntohs (ip_header->ip_id); -+ id->ipv4.ip_proto = ip_header->ip_p; -+ -+ *hash = reasm_ipv4_hash (&id->ipv4); -+ } -+ break; -+ } -+ -+#if USE_IPv6 -+ case 6: { -+ struct ip6_hdr *ip6_header = (struct ip6_hdr *) packet; -+ *protocol = PROTO_IPV6; -+ if (len >= ntohs (ip6_header->ip6_plen) + 40) -+ frag = frag_from_ipv6 (packet, &id->ipv6.ip_id, last_frag); -+ if (frag != NULL) { -+ memcpy (id->ipv6.ip_src, &ip6_header->ip6_src, 16); -+ memcpy (id->ipv6.ip_dst, &ip6_header->ip6_dst, 16); -+ *hash = reasm_ipv6_hash (&id->ipv6); -+ } -+ break; -+ } -+#endif /* USE_IPv6 */ -+ -+ default: -+ break; -+ } -+ -+ return frag; -+} -diff -urN ngrep-1.45/ipreasm.h ngrep-1.45-reasm/ipreasm.h ---- ngrep-1.45/ipreasm.h 1970-01-01 01:00:00.000000000 +0100 -+++ ngrep-1.45-reasm/ipreasm.h 2007-06-16 19:17:20.124795623 +0200 -@@ -0,0 +1,57 @@ -+#ifndef _IPREASM_H -+#define _IPREASM_H -+ -+#include <stdbool.h> -+ -+#include <pcap.h> -+ -+ -+/* -+ * This is an abstract time stamp. ipreasm doesn't care whether it is -+ * in seconds, milliseconds, or nanodecades. All it does it add the -+ * configured timeout value to it, and then compare it to the timstamps -+ * of subsequent packets to decide whether a fragment has expired. -+ */ -+typedef uint64_t reasm_time_t; -+ -+struct reasm_ip; -+ -+/* -+ * Functions to create and destroy the reassembly environment. -+ */ -+struct reasm_ip *reasm_ip_new (void); -+void reasm_ip_free (struct reasm_ip *reasm); -+ -+/* -+ * This is the main packet processing function. It inputs one packet, -+ * and MAY output one packet in turn. If the input was not a fragment, -+ * it is passed unmodified. If the input was a fragment that completed -+ * reassembly of a packet, the reassembled packet is output. -+ * If more fragments are required for reassembly, or the input packet -+ * is invalid for some reason, a NULL pointer is returned. -+ * -+ * The input must be a pointer allocated by malloc(). The output will -+ * be a pointer allocated by malloc(). -+ * -+ * Note that in the case of an IPv6 fragment, the input buffer will be -+ * modified in-place. This is considered a bug and should be fixed in -+ * the future. -+ */ -+unsigned char *reasm_ip_next (struct reasm_ip *reasm, unsigned char *packet, unsigned len, reasm_time_t timestamp, unsigned *output_len); -+ -+/* -+ * Set the timeout after which a noncompleted reassembly expires, in -+ * abstract time units (see above for the definition of reasm_time_t). -+ */ -+bool reasm_ip_set_timeout (struct reasm_ip *reasm, reasm_time_t timeout); -+ -+/* -+ * Query certain information about the current state. -+ */ -+unsigned reasm_ip_waiting (const struct reasm_ip *reasm); -+unsigned reasm_ip_max_waiting (const struct reasm_ip *reasm); -+unsigned reasm_ip_timed_out (const struct reasm_ip *reasm); -+unsigned reasm_ip_dropped_frags (const struct reasm_ip *reasm); -+ -+ -+#endif /* _IPREASM_H */ -diff -urN ngrep-1.45/Makefile.in ngrep-1.45-reasm/Makefile.in ---- ngrep-1.45/Makefile.in 2006-11-28 14:35:37.000000000 +0100 -+++ ngrep-1.45-reasm/Makefile.in 2007-06-16 15:41:22.859876074 +0200 -@@ -15,8 +15,8 @@ - - STRIPFLAG=@STRIPFLAG@ - --SRC=ngrep.c --OBJS=ngrep.o -+SRC=ngrep.c ipreasm.c -+OBJS=ngrep.o ipreasm.o - TARGET=ngrep - MANPAGE=ngrep.8 - -@@ -65,7 +65,7 @@ - $(REGEX_OBJS): $(REGEX_OBJS:.o=.c) $(REGEX_DIR)/*.h - $(MAKE) $(MAKEFLAGS) -C $(REGEX_DIR) $(notdir $(REGEX_OBJS)) - --$(OBJS): Makefile ngrep.c ngrep.h -+$(OBJS): Makefile ngrep.c ngrep.h ipreasm.c ipreasm.h - - tardist: - @( VERSION=`perl -ne '/VERSION\s+"(.*)"/ && print "$$1\n"' ngrep.h` ; \ -diff -urN ngrep-1.45/ngrep.c ngrep-1.45-reasm/ngrep.c ---- ngrep-1.45/ngrep.c 2006-11-28 14:38:43.000000000 +0100 -+++ ngrep-1.45-reasm/ngrep.c 2007-06-16 21:41:43.142117150 +0200 -@@ -98,6 +98,7 @@ - #endif - - #include "ngrep.h" -+#include "ipreasm.h" - - - static char rcsver[] = "$Revision: 1.93 $"; -@@ -156,7 +157,7 @@ - uint8_t link_offset; - uint8_t radiotap_present = 0; - --pcap_t *pd = NULL; -+pcap_t *pd = NULL, *pd_dumppcap = NULL; - pcap_dumper_t *pd_dump = NULL; - struct bpf_program pcapfilter; - struct in_addr net, mask; -@@ -183,6 +184,12 @@ - uint32_t ws_row, ws_col = 80, ws_col_forced = 0; - - -+/* -+ * Reassembly -+ */ -+struct reasm_ip *reasm = NULL; -+ -+ - int main(int argc, char **argv) { - int32_t c; - -@@ -195,7 +202,7 @@ - signal(SIGWINCH, update_windowsize); - #endif - -- while ((c = getopt(argc, argv, "LNhXViwqpevxlDtTRMs:n:c:d:A:I:O:S:P:F:W:")) != EOF) { -+ while ((c = getopt(argc, argv, "LNhXViwqpevxlDtTrRMs:n:c:d:A:I:O:S:P:F:W:")) != EOF) { - switch (c) { - case 'W': { - if (!strcasecmp(optarg, "normal")) -@@ -260,6 +267,10 @@ - case 'M': - re_multiline_match = 0; - break; -+ case 'r': -+ reasm = reasm_ip_new (); -+ reasm_ip_set_timeout (reasm, 30000000); -+ break; - case 'R': - dont_dropprivs = 1; - break; -@@ -585,7 +596,15 @@ - } - - if (dump_file) { -- if (!(pd_dump = pcap_dump_open(pd, dump_file))) { -+ if (reasm != NULL) { -+ if (!(pd_dumppcap = pcap_open_dead(DLT_RAW, 65535))) { -+ fprintf(stderr, "fatal: pcap_open_dead failed\n"); -+ clean_exit(-1); -+ } -+ pd_dump = pcap_dump_open(pd_dumppcap, dump_file); -+ } else -+ pd_dump = pcap_dump_open(pd, dump_file); -+ if (!pd_dump) { - fprintf(stderr, "fatal: %s\n", pcap_geterr(pd)); - clean_exit(-1); - } else printf("output: %s\n", dump_file); -@@ -641,6 +660,23 @@ - } - #endif - -+ if (reasm != NULL) { -+ unsigned new_len; -+ u_char *new_p = malloc(len - link_offset); -+ memcpy(new_p, ip4_pkt, len - link_offset); -+ p = reasm_ip_next(reasm, new_p, len - link_offset, (reasm_time_t) 1000000UL * h->ts.tv_sec + h->ts.tv_usec, &new_len); -+ if (p == NULL) -+ return; -+ len = new_len + link_offset; -+ h->len = new_len; -+ h->caplen = new_len; -+ -+ ip4_pkt = (struct ip *) p; -+#if USE_IPv6 -+ ip6_pkt = (struct ip6_hdr*)p; -+#endif -+ } -+ - ip_ver = ip4_pkt->ip_v; - - switch (ip_ver) { -@@ -802,6 +838,9 @@ - - if (match_after && keep_matching) - keep_matching--; -+ -+ if (reasm != NULL) -+ free(p); - } - - void dump_packet(struct pcap_pkthdr *h, u_char *p, uint8_t proto, unsigned char *data, uint32_t len, -@@ -1242,6 +1281,7 @@ - " -s is set the bpf caplen\n" - " -S is set the limitlen on matched packets\n" - " -W is set the dump format (normal, byline, single, none)\n" -+ " -r is reassemble any fragmented IPV4 or IPV6 packets\n" - " -c is force the column width to the specified size\n" - " -P is set the non-printable display char to what is specified\n" - " -F is read the bpf filter from the specified file\n" -@@ -1292,8 +1331,9 @@ - && pd && !pcap_stats(pd, &s)) - printf("%u received, %u dropped\n", s.ps_recv, s.ps_drop); - -- if (pd) pcap_close(pd); -- if (pd_dump) pcap_dump_close(pd_dump); -+ if (pd) pcap_close(pd); -+ if (pd_dumppcap) pcap_close(pd_dumppcap); -+ if (pd_dump) pcap_dump_close(pd_dump); - - #if defined(_WIN32) - if (delay_socket) closesocket(delay_socket); -@@ -1301,6 +1341,9 @@ - if (usedev) free(usedev); - #endif - -+ if (reasm != NULL) -+ reasm_ip_free(reasm); -+ - exit(sig); - } - diff --git a/network/ngrep/ngrep.SlackBuild b/network/ngrep/ngrep.SlackBuild index 2575543129514..84422910d08dc 100644 --- a/network/ngrep/ngrep.SlackBuild +++ b/network/ngrep/ngrep.SlackBuild @@ -2,13 +2,34 @@ # Slackware build script for ngrep -# Written by Larry Hajali <larryhaja[at]gmail[dot]com> +# Copyright 2023 Yossi Neiman, mishehu+sbo@shavedgoats.net +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR 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. + +# Based upon the script written by Larry Hajali <larryhaja[at]gmail[dot]com> cd $(dirname $0) ; CWD=$(pwd) PRGNAM=ngrep -VERSION=${VERSION:-1.45} -BUILD=${BUILD:-2} +VERSION=${VERSION:-1.47} +SOURCEVERSION=${VERSION/./_} +BUILD=${BUILD:-1} TAG=${TAG:-_SBo} PKGTYPE=${PKGTYPE:-tgz} @@ -20,9 +41,6 @@ if [ -z "$ARCH" ]; then esac fi -# If the variable PRINT_PACKAGE_NAME is set, then this script will report what -# the name of the created package would be, and then exit. This information -# could be useful to other scripts. if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" exit 0 @@ -48,18 +66,15 @@ fi set -e -# Option to add packet reassembly patch (default = yes) -REASSEM_PATCH=${ASSEM_PATCH:-yes} - # Enable IPV6; either yes or no NGREP_IPV6=${NGREP_IPV6:-yes} rm -rf $PKG mkdir -p $TMP $PKG $OUTPUT cd $TMP -rm -rf $PRGNAM-$VERSION -tar xvf $CWD/$PRGNAM-$VERSION.tar.bz2 -cd $PRGNAM-$VERSION +rm -rf $PRGNAM-$SOURCEVERSION +tar xvf $CWD/$PRGNAM-$SOURCEVERSION.tar.gz +cd $PRGNAM-$SOURCEVERSION chown -R root:root . find -L . \ \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \ @@ -67,11 +82,6 @@ find -L . \ \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \; -# Patch adds IPv4 and IPv6 fragment reassembly for ngrep 1.45 -if [ $REASSEM_PATCH == yes ]; then - patch -p1 < $CWD/ngrep-1.45-reasm.diff -fi - CFLAGS="$SLKCFLAGS" \ CXXFLAGS="$SLKCFLAGS" \ ./configure \ @@ -80,9 +90,6 @@ CXXFLAGS="$SLKCFLAGS" \ --sysconfdir=/etc \ --localstatedir=/var \ --enable-ipv6=${NGREP_IPV6} \ - --with-pcap-includes=/usr/include/pcap \ - --disable-static \ - --disable-pcap-restart \ --build=$ARCH-slackware-linux make @@ -94,7 +101,7 @@ find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | gr find $PKG/usr/man -type f -exec gzip -9 {} \; mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION -cp -a LICENSE.txt doc/*.txt $PKG/usr/doc/$PRGNAM-$VERSION +cp CHANGES CREDITS LICENSE README.md $PKG/usr/doc/$PRGNAM-$VERSION cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild mkdir -p $PKG/install diff --git a/network/ngrep/ngrep.info b/network/ngrep/ngrep.info index 0866f50fd182e..906619b38d52b 100644 --- a/network/ngrep/ngrep.info +++ b/network/ngrep/ngrep.info @@ -1,10 +1,10 @@ PRGNAM="ngrep" -VERSION="1.45" -HOMEPAGE="http://ngrep.sourceforge.net/" -DOWNLOAD="http://downloads.sourceforge.net/ngrep/ngrep-1.45.tar.bz2" -MD5SUM="bc8150331601f3b869549c94866b4f1c" +VERSION="1.47" +HOMEPAGE="https://github.com/jpr5/ngrep/" +DOWNLOAD="https://github.com/jpr5/ngrep/archive/refs/tags/V1_47.tar.gz" +MD5SUM="03cb1229ad586495852ea316262e8f38" DOWNLOAD_x86_64="" MD5SUM_x86_64="" REQUIRES="" -MAINTAINER="Larry Hajali" -EMAIL="larryhaja[at]gmail[dot]com" +MAINTAINER="Yossi Neiman" +EMAIL="mishehu+sbo@shavedgoats.net" diff --git a/network/ngrep/slack-desc b/network/ngrep/slack-desc index d6c075689366c..90762ea885128 100644 --- a/network/ngrep/slack-desc +++ b/network/ngrep/slack-desc @@ -15,5 +15,5 @@ ngrep: to match against data payloads of packets. It currently recognizes ngrep: IPv4/6, TCP, UDP and ICMPv4/6, IGMP and Raw across Ethernet, PPP, ngrep: SLIP, FDDI, Token Ring and null interfaces. ngrep: -ngrep: Homepage: http://ngrep.sourceforge.net/ +ngrep: Homepage: https://github.com/jpr5/ngrep/ ngrep: |