summaryrefslogtreecommitdiffstats
path: root/network/ngrep
diff options
context:
space:
mode:
Diffstat (limited to 'network/ngrep')
-rw-r--r--network/ngrep/README13
-rw-r--r--network/ngrep/ngrep-1.45-reasm.diff939
-rw-r--r--network/ngrep/ngrep.SlackBuild59
-rw-r--r--network/ngrep/ngrep.info12
-rw-r--r--network/ngrep/slack-desc2
5 files changed, 50 insertions, 975 deletions
diff --git a/network/ngrep/README b/network/ngrep/README
index 5c94af27b4..b9d5da3356 100644
--- a/network/ngrep/README
+++ b/network/ngrep/README
@@ -1,14 +1,11 @@
ngrep strives to provide most of GNU grep's common features, applying
them to the network layer. ngrep is a pcap-aware tool that will allow
you to specify extended regular or hexadecimal expressions to match
-against data payloads of packets. It currently recognizes IPv4/6, TCP,
-UDP, ICMPv4/6, IGMP and Raw across Ethernet, PPP, SLIP, FDDI, Token
-Ring and null interfaces, and understands BPF filter logic in the same
-fashion as more common packet sniffing tools, such as tcpdump and snoop.
+against data payloads of packets. It currently recognizes IPv4/6,
+TCP, UDP, ICMPv4/6, IGMP and Raw across Ethernet, PPP, SLIP, FDDI,
+Token Ring and null interfaces, and understands BPF filter logic in
+the same fashion as more common packet sniffing tools, such as tcpdump
+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 ed33fb6f65..0000000000
--- 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 1923b4d5c4..84422910d0 100644
--- a/network/ngrep/ngrep.SlackBuild
+++ b/network/ngrep/ngrep.SlackBuild
@@ -1,13 +1,37 @@
-#!/bin/sh
+#!/bin/bash
# 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}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
@@ -17,7 +41,11 @@ if [ -z "$ARCH" ]; then
esac
fi
-CWD=$(pwd)
+if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
+ echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
+ exit 0
+fi
+
TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
@@ -38,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 \
@@ -57,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 \
@@ -70,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
@@ -84,11 +101,11 @@ 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
cat $CWD/slack-desc > $PKG/install/slack-desc
cd $PKG
-/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}
+/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE
diff --git a/network/ngrep/ngrep.info b/network/ngrep/ngrep.info
index 0866f50fd1..906619b38d 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 d6c0756893..90762ea885 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: