Hello Luca, and all developers,
I made a IPv6 patch for PF_RING. I tested on ubuntu 8.04.
This patch works, like this:
----------------------------------------
$ ping6 ff02::1%eth0 &
PING ff02::1%eth0(ff02::1) 56 data bytes
64 bytes from fe80::220:edff:fe31:8afa: icmp_seq=1 ttl=64 time=0.145 ms
[snip]
$ sudo /usr/src/PF_RING/userland/examples/pfcount -v > out.txt
$ grep ff02 out.txt | head
[eth_type=0x86DD][l3_proto=58][fe80:0000:0000:0000:0220:edff:fe31:8afa:0
-> ff02:0000:0000:0000:0000:0000:0000:0001:0] 01:46:22.765428
[00:20:ED:31:8A:FA -> 33:33:00:00:00:01]
[eth_type=0x86DD][tos=0][tcp_flags=0][caplen=118][len=118][parsed_header_len=0][eth_offset=0][l3_offset=14][l4_offset=0][payload_offset=0]
[eth_type=0x86DD][l3_proto=58][fe80:0000:0000:0000:0220:edff:fe31:8afa:0
-> ff02:0000:0000:0000:0000:0000:0000:0001:0] 01:46:22.765423
[00:20:ED:31:8A:FA -> 33:33:00:00:00:01]
[eth_type=0x86DD][tos=0][tcp_flags=0][caplen=118][len=118][parsed_header_len=0][eth_offset=14][l3_offset=0][l4_offset=0][payload_offset=0]
[snip]
----------------------------------------
Index: kernel/include/linux/ring.h
===================================================================
--- kernel/include/linux/ring.h (revision 3603)
+++ kernel/include/linux/ring.h (working copy)
@@ -7,6 +7,9 @@
#ifndef __RING_H
#define __RING_H
+#ifdef __KERNEL__
+#include <linux/in6.h>
+#endif /* __KERNEL__ */
#define INCLUDE_MAC_INFO
#ifdef INCLUDE_MAC_INFO
@@ -61,15 +64,30 @@
int16_t payload_offset;
};
+union ip_common {
+ struct in6_addr v6; /* IPv6 src/dst IP addresses (Network byte order) */
+ u_int32_t v4; /* IPv4 src/dst IP addresses */
+};
+
struct pkt_parsing_info {
/* Core fields (also used by NetFlow) */
u_int16_t eth_type; /* Ethernet type */
u_int16_t vlan_id; /* VLAN Id or NO_VLAN */
- u_int8_t l3_proto, ipv4_tos; /* Layer 3 protocol/TOS */
- u_int32_t ipv4_src, ipv4_dst; /* IPv4 src/dst IP addresses */
- u_int16_t l4_src_port, l4_dst_port; /* Layer 4 src/dst ports */
+ u_int8_t l3_proto, ip_tos; /* Layer 3 protocol/TOS */
+ /* definitions for code compatibility */
+#define ipv4_tos ip_tos
+#define ipv6_tos ip_tos
+ u_int8_t ip_version; /* IP version */
u_int8_t tcp_flags; /* TCP flags (0 if not available) */
+ union ip_common ip_src, ip_dst;
+ /* definitions for code compatibility */
+#define ipv4_src ip_src.v4
+#define ipv4_dst ip_dst.v4
+#define ipv6_src ip_src.v6
+#define ipv6_dst ip_dst.v6
+ u_int16_t l4_src_port, l4_dst_port; /* Layer 4 src/dst ports */
+
union {
struct pkt_offset offset; /* Offsets of L3/L4/payload elements */
struct pkt_aggregation_info aggregation; /* Future or plugin use */
@@ -94,8 +112,14 @@
typedef struct {
u_int8_t proto; /* Use 0 for 'any' protocol */
u_int16_t vlan_id; /* Use '0' for any vlan */
- u_int32_t host_low, host_high; /* User '0' for any host. This is applied
to both source
+ union ip_common host_common_low, host_common_high; /* User '0' for any
host. This is applied to both source
and destination. */
+ /* definitions for code compatibility */
+#define host_low host_common_low.v4
+#define host_high host_common_high.v4
+#define host6_low host_common_low.v6
+#define host6_high host_common_high.v6
+
u_int16_t port_low, port_high; /* All ports between port_low...port_high
0 means 'any' port. This is applied to
both source
and destination. This means that
@@ -156,7 +180,12 @@
typedef struct {
u_int16_t vlan_id;
u_int8_t proto;
- u_int32_t host_peer_a, host_peer_b;
+ union ip_common host_common_peer_a, host_common_peer_b;
+ /* definitions for code compatibility */
+#define host_peer_a host_common_peer_a.v4
+#define host_peer_b host_common_peer_b.v4
+#define host6_peer_a host_common_peer_a.v6
+#define host6_peer_b host_common_peer_b.v6
u_int16_t port_peer_a, port_peer_b;
rule_action_behaviour rule_action; /* What to do in case of match */
Index: kernel/net/ring/ring_packet.c
===================================================================
--- kernel/net/ring/ring_packet.c (revision 3603)
+++ kernel/net/ring/ring_packet.c (working copy)
@@ -58,6 +58,7 @@
#include <linux/filter.h>
#include <linux/ring.h>
#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/list.h>
@@ -76,6 +77,7 @@
#include <net/inet_common.h>
#endif
#include <net/ip.h>
+#include <net/ipv6.h>
/* #define RING_DEBUG */
@@ -216,6 +218,8 @@
}
#endif
+const static union ip_common ip_common_zero = {IN6ADDR_ANY_INIT};
+
/* ***** Code taken from other kernel modules ******** */
/**
@@ -661,8 +665,10 @@
struct pfring_pkthdr *hdr)
{
struct iphdr *ip;
+ struct ipv6hdr *ipv6;
struct ethhdr *eh = (struct ethhdr*)(skb->data-skb_displ);
u_int16_t displ;
+ u_int16_t ip_len;
memset(&hdr->parsed_pkt, 0, sizeof(struct pkt_parsing_info));
hdr->parsed_header_len = 9;
@@ -692,20 +698,71 @@
hdr->parsed_pkt.ipv4_src = ntohl(ip->saddr), hdr->parsed_pkt.ipv4_dst =
ntohl(ip->daddr), hdr->parsed_pkt.l3_proto = ip->protocol;
hdr->parsed_pkt.ipv4_tos = ip->tos;
- if((ip->protocol == IPPROTO_TCP) || (ip->protocol == IPPROTO_UDP))
+ hdr->parsed_pkt.ip_version = 4;
+ ip_len = ip->ihl*4;
+ } else if (hdr->parsed_pkt.eth_type == 0x86DD /* IPv6 */) {
+ hdr->parsed_pkt.ip_version = 6;
+ ip_len = 40;
+
+ hdr->parsed_pkt.pkt_detail.offset.l3_offset =
hdr->parsed_pkt.pkt_detail.offset.eth_offset+displ+sizeof(struct ethhdr);
+ ipv6 = (struct
ipv6hdr*)(skb->data+hdr->parsed_pkt.pkt_detail.offset.l3_offset);
+
+ /* Values of IPv6 addresses are stored as network byte order */
+ hdr->parsed_pkt.ipv6_src = ipv6->saddr;
+ hdr->parsed_pkt.ipv6_dst = ipv6->daddr;
+
+ hdr->parsed_pkt.l3_proto = ipv6->nexthdr;
+ hdr->parsed_pkt.ipv6_tos = (u_int8_t)((ntohl((u_int32_t *)ipv6) &&
0x0ff00000) >> 20);
+
+ /*
+ RFC2460 4.1 Extension Header Order
+ IPv6 header
+ Hop-by-Hop Options header
+ Destination Options header
+ Routing header
+ Fragment header
+ Authentication header
+ Encapsulating Security Payload header
+ Destination Options header
+ upper-layer header
+ */
+
+ while(hdr->parsed_pkt.l3_proto == NEXTHDR_HOP ||
+ hdr->parsed_pkt.l3_proto == NEXTHDR_DEST ||
+ hdr->parsed_pkt.l3_proto == NEXTHDR_ROUTING ||
+ hdr->parsed_pkt.l3_proto == NEXTHDR_AUTH ||
+ hdr->parsed_pkt.l3_proto == NEXTHDR_ESP ||
+ hdr->parsed_pkt.l3_proto == NEXTHDR_FRAGMENT)
{
- u_int16_t ip_len = ip->ihl*4;
+ struct ipv6_opt_hdr *ipv6_opt;
+ ipv6_opt = (struct ipv6_opt_hdr
*)(skb->data+hdr->parsed_pkt.pkt_detail.offset.l3_offset+ip_len);
+ ip_len += 8;
+ if (hdr->parsed_pkt.l3_proto == NEXTHDR_AUTH)
+ /*
+ RFC4302 2.2. Payload Length: This 8-bit field specifies the
+ length of AH in 32-bit words (4-byte units), minus "2".
+ */
+ ip_len += ipv6_opt->hdrlen * 4;
+ else if (hdr->parsed_pkt.l3_proto != NEXTHDR_FRAGMENT)
+ ip_len += ipv6_opt->hdrlen;
+ hdr->parsed_pkt.l3_proto = ipv6_opt->nexthdr;
+ }
+ } else {
+ return(0); /* No IP */
+ }
+ if((hdr->parsed_pkt.l3_proto == IPPROTO_TCP) || (hdr->parsed_pkt.l3_proto
== IPPROTO_UDP))
+ {
hdr->parsed_pkt.pkt_detail.offset.l4_offset =
hdr->parsed_pkt.pkt_detail.offset.l3_offset+ip_len;
- if(ip->protocol == IPPROTO_TCP)
+ if(hdr->parsed_pkt.l3_proto == IPPROTO_TCP)
{
struct tcphdr *tcp = (struct
tcphdr*)(skb->data+hdr->parsed_pkt.pkt_detail.offset.l4_offset);
hdr->parsed_pkt.l4_src_port = ntohs(tcp->source),
hdr->parsed_pkt.l4_dst_port = ntohs(tcp->dest);
hdr->parsed_pkt.pkt_detail.offset.payload_offset =
hdr->parsed_pkt.pkt_detail.offset.l4_offset+(tcp->doff * 4);
hdr->parsed_pkt.tcp_flags = (tcp->fin * TH_FIN_MULTIPLIER) +
(tcp->syn * TH_SYN_MULTIPLIER) + (tcp->rst * TH_RST_MULTIPLIER) +
(tcp->psh * TH_PUSH_MULTIPLIER) + (tcp->ack * TH_ACK_MULTIPLIER)
+ (tcp->urg * TH_URG_MULTIPLIER);
- } else if(ip->protocol == IPPROTO_UDP)
+ } else if(hdr->parsed_pkt.l3_proto == IPPROTO_UDP)
{
struct udphdr *udp = (struct
udphdr*)(skb->data+hdr->parsed_pkt.pkt_detail.offset.l4_offset);
hdr->parsed_pkt.l4_src_port = ntohs(udp->source),
hdr->parsed_pkt.l4_dst_port = ntohs(udp->dest);
@@ -717,19 +774,30 @@
hdr->parsed_pkt.pkt_detail.offset.eth_offset = skb_displ;
- return(1); /* IP */
- } /* TODO: handle IPv6 */
-
- return(0); /* No IP */
+ return(1); /* IP or IPv6 */
}
/* ********************************** */
inline u_int32_t hash_pkt(u_int16_t vlan_id, u_int8_t proto,
- u_int32_t host_peer_a, u_int32_t host_peer_b,
+ union ip_common host_common_peer_a, union ip_common
host_common_peer_b,
u_int16_t port_peer_a, u_int16_t port_peer_b)
{
+ /*
+ When protocol of host_common_peer is IPv4, s6_addr32[0] contains
+ IPv4 address and the value of other elements of s6_addr32 are 0,
+ therefore result of this calculation will be equal to original
+ hash calculation.
+ // original hash calculation (for IPv4)
return(vlan_id+proto+host_peer_a+host_peer_b+port_peer_a+port_peer_b);
+ */
+
+ return(vlan_id+proto+
+ host_common_peer_a.v6.s6_addr32[0]+host_common_peer_a.v6.s6_addr32[1]+
+ host_common_peer_a.v6.s6_addr32[2]+host_common_peer_a.v6.s6_addr32[3]+
+ host_common_peer_b.v6.s6_addr32[0]+host_common_peer_b.v6.s6_addr32[1]+
+ host_common_peer_b.v6.s6_addr32[2]+host_common_peer_b.v6.s6_addr32[3]+
+ port_peer_a+port_peer_b);
}
/* ********************************** */
@@ -738,8 +806,8 @@
{
return(hash_pkt(hdr->parsed_pkt.vlan_id,
hdr->parsed_pkt.l3_proto,
- mask_src ? 0 : hdr->parsed_pkt.ipv4_src,
- mask_dst ? 0 : hdr->parsed_pkt.ipv4_dst,
+ mask_src ? ip_common_zero : hdr->parsed_pkt.ip_src,
+ mask_dst ? ip_common_zero : hdr->parsed_pkt.ip_dst,
mask_src ? 0 : hdr->parsed_pkt.l4_src_port,
mask_dst ? 0 : hdr->parsed_pkt.l4_dst_port));
}
@@ -750,6 +818,10 @@
struct pfring_pkthdr *hdr,
u_char mask_src, u_char mask_dst)
{
+ /*
+ When protocol of host_peer is IPv4, s6_addr32[0] contains IPv4
+ address and the value of other elements of s6_addr32 are 0.
+ */
if((hash_bucket->rule.proto == hdr->parsed_pkt.l3_proto)
&& (hash_bucket->rule.vlan_id == hdr->parsed_pkt.vlan_id)
&& (((hash_bucket->rule.host_peer_a == (mask_src ? 0 :
hdr->parsed_pkt.ipv4_src))
@@ -761,7 +833,28 @@
&& (hash_bucket->rule.host_peer_b == (mask_src ? 0 :
hdr->parsed_pkt.ipv4_src))
&& (hash_bucket->rule.port_peer_a == (mask_dst ? 0 :
hdr->parsed_pkt.l4_dst_port))
&& (hash_bucket->rule.port_peer_b == (mask_src ? 0 :
hdr->parsed_pkt.l4_src_port)))))
+ {
+ /* comparison for ipv6 addresses */
+ if((hdr->parsed_pkt.ip_version == 6)
+ && (((memcmp(&hash_bucket->rule.host6_peer_a,
+ (mask_src ? &ip_common_zero.v6 : &hdr->parsed_pkt.ipv6_src),
+ sizeof(union ip_common) == 0))
+ && (memcmp(&hash_bucket->rule.host6_peer_b,
+ (mask_dst ? &ip_common_zero.v6 :
&hdr->parsed_pkt.ipv6_dst),
+ sizeof(union ip_common) == 0)))
+ ||
+ ((memcmp(&hash_bucket->rule.host6_peer_a,
+ (mask_src ? &ip_common_zero.v6 :
&hdr->parsed_pkt.ipv6_dst),
+ sizeof(union ip_common) == 0))
+ && (memcmp(&hash_bucket->rule.host6_peer_b,
+ (mask_dst ? &ip_common_zero.v6 :
&hdr->parsed_pkt.ipv6_src),
+ sizeof(union ip_common) == 0))))) {
+ return(1);
+ } else {
+ return(0);
+ }
return(1);
+ }
else
return(0);
}
@@ -784,6 +877,21 @@
if((rule->rule.core_fields.vlan_id > 0) && (hdr->parsed_pkt.vlan_id !=
rule->rule.core_fields.vlan_id)) return(0);
if((rule->rule.core_fields.proto > 0) && (hdr->parsed_pkt.l3_proto !=
rule->rule.core_fields.proto)) return(0);
+ /* IPv6 */
+ if(hdr->parsed_pkt.ip_version == 6) {
+ if(memcmp(&rule->rule.core_fields.host6_low, &ip_common_zero,
+ sizeof(struct in6_addr)) > 0) {
+ if((memcmp(&hdr->parsed_pkt.ipv6_src, &rule->rule.core_fields.host6_low,
+ sizeof(struct in6_addr) < 0))
+ || (memcmp(&hdr->parsed_pkt.ipv6_src,
&rule->rule.core_fields.host6_high,
+ sizeof(struct in6_addr) > 0))
+ && (memcmp(&hdr->parsed_pkt.ipv6_dst,
&rule->rule.core_fields.host6_low,
+ sizeof(struct in6_addr) < 0))
+ || (memcmp(&hdr->parsed_pkt.ipv6_dst,
&rule->rule.core_fields.host6_high,
+ sizeof(struct in6_addr) > 0)))
+ return(0);
+ }
+ } else
if(rule->rule.core_fields.host_low > 0) {
if(((hdr->parsed_pkt.ipv4_src < rule->rule.core_fields.host_low)
|| (hdr->parsed_pkt.ipv4_src > rule->rule.core_fields.host_high))
@@ -1452,7 +1560,7 @@
iphdr = ip_hdr(skb);
- if(iphdr) {
+ if(iphdr && iphdr->version == 4) {
#if defined (RING_DEBUG)
printk("[PF_RING] [version=%d] %X -> %X\n", iphdr->version,
iphdr->saddr, iphdr->daddr);
#endif
@@ -1487,6 +1595,15 @@
}
}
}
+ else if(iphdr && iphdr->version == 6)
+ {
+ /* Re-assembling fragmented IPv6 packets has not been
+ implemented. Probability of observing fragmented IPv6
+ packets is extremely low. */
+#if defined (RING_DEBUG)
+ printk("[PF_RING] Re-assembling fragmented IPv6 packet hs not been
implemented\n");
+#endif
+ }
else
{
#if defined (RING_DEBUG)
@@ -2284,7 +2401,7 @@
u_char add_rule)
{
u_int32_t hash_value = hash_pkt(rule->rule.vlan_id, rule->rule.proto,
- rule->rule.host_peer_a,
rule->rule.host_peer_b,
+ rule->rule.host_common_peer_a,
rule->rule.host_common_peer_b,
rule->rule.port_peer_a,
rule->rule.port_peer_b) % DEFAULT_RING_HASH_SIZE;
int rc = -1, debug = 0;
@@ -2808,7 +2925,7 @@
rule.host_peer_b, rule.port_peer_b);
hash_idx = hash_pkt(rule.vlan_id, rule.proto,
- rule.host_peer_a, rule.host_peer_b,
+ rule.host_common_peer_a, rule.host_common_peer_b,
rule.port_peer_a, rule.port_peer_b) %
DEFAULT_RING_HASH_SIZE;
if(pfr->filtering_hash[hash_idx] != NULL) {
Index: userland/libpcap-0.9.7-ring/config.h
===================================================================
--- userland/libpcap-0.9.7-ring/config.h (revision 3603)
+++ userland/libpcap-0.9.7-ring/config.h (working copy)
@@ -136,7 +136,7 @@
#define HAVE___ATTRIBUTE__ 1
/* IPv6 */
-/* #undef INET6 */
+#define INET6 1
/* if unaligned access fails */
/* #undef LBL_ALIGN */
Index: userland/Makefile
===================================================================
--- userland/Makefile (revision 3603)
+++ userland/Makefile (working copy)
@@ -7,7 +7,7 @@
cd lib; make
pcap:
- cd libpcap-0.9.7-ring; ./configure;make
+ cd libpcap-0.9.7-ring; ./configure --enable-ipv6;make
ring_examples:
cd examples; make
Index: userland/examples/pfcount.c
===================================================================
--- userland/examples/pfcount.c (revision 3603)
+++ userland/examples/pfcount.c (working copy)
@@ -209,6 +209,20 @@
return(_intoa(addr, buf, sizeof(buf)));
}
+/* ************************************ */
+
+inline char* in6toa(struct in6_addr addr6) {
+ static char buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ snprintf(buf, sizeof(buf),
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ addr6.s6_addr[0], addr6.s6_addr[1], addr6.s6_addr[2],
addr6.s6_addr[3],
+ addr6.s6_addr[4], addr6.s6_addr[5], addr6.s6_addr[6],
addr6.s6_addr[7],
+ addr6.s6_addr[8], addr6.s6_addr[9], addr6.s6_addr[10],
addr6.s6_addr[11],
+ addr6.s6_addr[12], addr6.s6_addr[13], addr6.s6_addr[14],
addr6.s6_addr[15]);
+
+ return(buf);
+}
+
/* ****************************************************** */
char* proto2str(u_short proto) {
@@ -238,8 +252,8 @@
printf("[eth_type=0x%04X]", h->parsed_pkt.eth_type);
printf("[l3_proto=%u]", (unsigned int)h->parsed_pkt.l3_proto);
- printf("[%s:%d -> ", intoa(h->parsed_pkt.ipv4_src),
h->parsed_pkt.l4_src_port);
- printf("%s:%d] ", intoa(h->parsed_pkt.ipv4_dst),
h->parsed_pkt.l4_dst_port);
+ printf("[%s:%d -> ", (h->parsed_pkt.eth_type == 0x86DD) ?
in6toa(h->parsed_pkt.ipv6_src) : intoa(h->parsed_pkt.ipv4_src),
h->parsed_pkt.l4_src_port);
+ printf("%s:%d] ", (h->parsed_pkt.eth_type == 0x86DD) ?
in6toa(h->parsed_pkt.ipv6_dst) : intoa(h->parsed_pkt.ipv4_dst),
h->parsed_pkt.l4_dst_port);
printf("%02d:%02d:%02d.%06u ",
s / 3600, (s % 3600) / 60, s % 60,
(unsigned)h->ts.tv_usec);
Index: userland/examples/pcount.c
===================================================================
--- userland/examples/pcount.c (revision 3603)
+++ userland/examples/pcount.c (working copy)
@@ -29,6 +29,7 @@
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <net/ethernet.h> /* the L2 protocols */
static struct timeval startTime;
@@ -192,6 +193,19 @@
return(_intoa(addr, buf, sizeof(buf)));
}
+/* ************************************ */
+
+inline char* in6toa(struct in6_addr addr6) {
+ static char buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ snprintf(buf, sizeof(buf),
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ addr6.s6_addr[0], addr6.s6_addr[1], addr6.s6_addr[2],
addr6.s6_addr[3],
+ addr6.s6_addr[4], addr6.s6_addr[5], addr6.s6_addr[6],
addr6.s6_addr[7],
+ addr6.s6_addr[8], addr6.s6_addr[9], addr6.s6_addr[10],
addr6.s6_addr[11],
+ addr6.s6_addr[12], addr6.s6_addr[13], addr6.s6_addr[14],
addr6.s6_addr[15]);
+
+ return(buf);
+}
/* ****************************************************** */
char* proto2str(u_short proto) {
@@ -219,6 +233,7 @@
u_short eth_type, vlan_id;
char buf1[32], buf2[32];
struct ip ip;
+ struct ip6_hdr ip6;
int s = (h->ts.tv_sec + thiszone) % 86400;
printf("%02d:%02d:%02d.%06u ",
@@ -237,11 +252,15 @@
printf("[vlan %u] ", vlan_id);
p+=4;
}
- if(eth_type == 0x0800) {
+ if(eth_type == 0x0800) {
memcpy(&ip, p+sizeof(ehdr), sizeof(struct ip));
printf("[%s ", intoa(ntohl(ip.ip_src.s_addr)));
printf("-> %s] ", intoa(ntohl(ip.ip_dst.s_addr)));
- } else if(eth_type == 0x0806)
+ } else if(eth_type == 0x86DD) {
+ memcpy(&ip6, p+sizeof(ehdr), sizeof(struct ip6_hdr));
+ printf("[%s ", in6toa(ip6.ip6_src));
+ printf("-> %s] ", in6toa(ip6.ip6_dst));
+ }else if(eth_type == 0x0806)
printf("[ARP]");
else
printf("[eth_type=0x%04X]", eth_type);
@@ -386,6 +405,7 @@
printf("pcap_set_cluster returned %d\n", rc);
}
+ printf("%s\n", bpfFilter);
if(bpfFilter != NULL) {
if(pcap_compile(pd, &fcode, bpfFilter, 1, 0xFFFFFF00) < 0) {
printf("pcap_compile error: '%s'\n", pcap_geterr(pd));
Index: userland/examples/Makefile
===================================================================
--- userland/examples/Makefile (revision 3603)
+++ userland/examples/Makefile (working copy)
@@ -83,7 +83,7 @@
pcaps: ${RPOBJS}
@echo "=*= making program $@ =*="
- ${CC} ${RPOBJS} -lpcap -o $@
+ ${CC} ${RPOBJS} ${LIBPCAP} ${LIBS} -o $@
pfcount: pfcount.o ${LIBPFRING}
@echo "=*= making program $@ =*="
_______________________________________________
Ntop-dev mailing list
[email protected]
http://listgateway.unipi.it/mailman/listinfo/ntop-dev