Skip to content

Commit 2799e38

Browse files
committed
ipv6 support
Previous code doesn't support IPv6 protocol, let's complete it. Signed-off-by: Menglong Dong <imagedong@tencent.com>
1 parent 5e008bf commit 2799e38

3 files changed

Lines changed: 61 additions & 19 deletions

File tree

nettrace.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <uapi/linux/if_ether.h>
66
#include <uapi/linux/tcp.h>
77
#include <uapi/linux/ip.h>
8+
#include <uapi/linux/ipv6.h>
89
#include <uapi/linux/udp.h>
910
#include <uapi/linux/icmp.h>
1011
#include <bcc/proto.h>
@@ -22,6 +23,10 @@ typedef struct {
2223
u32 saddr;
2324
u32 daddr;
2425
} ip;
26+
struct {
27+
u8 saddr[16];
28+
u8 daddr[16];
29+
} ipv6;
2530
} field_l3;
2631
#ifdef NT_ENABLE_RET
2732
u64 ret_val;
@@ -183,13 +188,21 @@ static inline bool do_filter(context_t *ctx, sk_buff_t *skb)
183188
}
184189

185190
static inline int parse_ip(context_t *ctx, sk_buff_t *skb,
186-
struct iphdr *ip)
191+
struct iphdr *ip, bool is_ipv6)
187192
{
188193
void *l4;
189194

190-
ctx->proto_l4 = ip->protocol;
191-
ctx->field_saddr = ip->saddr;
192-
ctx->field_daddr = ip->daddr;
195+
if (is_ipv6) {
196+
struct ipv6hdr *ipv6 = (void *)ip;
197+
ctx->proto_l4 = ipv6->nexthdr;
198+
199+
bpf_probe_read(ctx->field_l3.ipv6.saddr, 16, &ipv6->saddr);
200+
bpf_probe_read(ctx->field_l3.ipv6.daddr, 16, &ipv6->daddr);
201+
} else {
202+
ctx->proto_l4 = ip->protocol;
203+
ctx->field_saddr = ip->saddr;
204+
ctx->field_daddr = ip->daddr;
205+
}
193206

194207
l4 = get_l4(skb);
195208
switch (ctx->proto_l4) {
@@ -267,9 +280,11 @@ static inline int init_ctx(context_t *ctx, sk_buff_t *skb)
267280

268281
switch (ctx->proto_l3) {
269282
case htons(ETH_P_IP):
270-
return parse_ip(ctx, skb, l3);
283+
return parse_ip(ctx, skb, l3, false);
271284
case htons(ETH_P_ARP):
272285
return parse_arp(ctx, skb, l3);
286+
case htons(ETH_P_IPV6):
287+
return parse_ip(ctx, skb, l3, true);
273288
default:
274289
return 0;
275290
}
@@ -282,7 +297,7 @@ static inline int init_ctx(context_t *ctx, sk_buff_t *skb)
282297
ctx->proto_l3 = htons(ETH_P_IP);
283298
l3 = get_l3_send(skb);
284299
if (l3)
285-
return parse_ip(ctx, skb, l3);
300+
return parse_ip(ctx, skb, l3, false);
286301
return 0;
287302
}
288303

nettrace.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,12 @@ class IP(ctypes.Structure):
539539
('daddr', ctypes.c_uint32),
540540
]
541541

542+
class IPV6(ctypes.Structure):
543+
_fields_ = [
544+
('saddr', ctypes.c_uint16*8),
545+
('daddr', ctypes.c_uint16*8),
546+
]
547+
542548
class ArpExt(ctypes.Structure):
543549
_fields_ = [
544550
('op', ctypes.c_uint16)
@@ -570,6 +576,7 @@ class Icmp(ctypes.Structure):
570576
class FieldL3(ctypes.Union):
571577
_fields_ = [
572578
('ip', IP),
579+
('ipv6', IPV6),
573580
]
574581

575582
class FieldL4(ctypes.Union):
@@ -644,26 +651,34 @@ def _print_stack(stack_id, tgid):
644651
show_module=True, show_offset=True))
645652

646653
@staticmethod
647-
def _generate_ip_info(ctx):
648-
ip = ctx.field_l3.ip
654+
def _generate_ip_info(ctx, is_ipv6=False):
649655
output_str = ''
650656

657+
if not is_ipv6:
658+
ip = ctx.field_l3.ip
659+
saddr = NetUtils.int2ip(socket.ntohl(ip.saddr))
660+
daddr = NetUtils.int2ip(socket.ntohl(ip.daddr))
661+
else:
662+
ip = ctx.field_l3.ipv6
663+
saddr = NetUtils.int2ipv6(ip.saddr)
664+
daddr = NetUtils.int2ipv6(ip.daddr)
665+
651666
if ctx.proto_l4 == socket.IPPROTO_TCP:
652667
tcp = ctx.field_l4.tcp
653668
output_str += 'TCP: %s:%d -> %s:%d, seq:%d, ack:%d %s' % (
654-
NetUtils.int2ip(socket.ntohl(ip.saddr)),
669+
saddr,
655670
socket.ntohs(tcp.sport),
656-
NetUtils.int2ip(socket.ntohl(ip.daddr)),
671+
daddr,
657672
socket.ntohs(tcp.dport),
658673
socket.ntohl(tcp.seq),
659674
socket.ntohl(tcp.ack),
660675
NetUtils.int2tcp_flags(tcp.flags))
661676
elif ctx.proto_l4 == socket.IPPROTO_UDP:
662677
udp = ctx.field_l4.udp
663678
output_str += 'UDP: %s:%d -> %s:%d' % (
664-
NetUtils.int2ip(socket.ntohl(ip.saddr)),
679+
saddr,
665680
socket.ntohs(udp.sport),
666-
NetUtils.int2ip(socket.ntohl(ip.daddr)),
681+
daddr,
667682
socket.ntohs(udp.dport))
668683
elif ctx.proto_l4 == socket.IPPROTO_ICMP:
669684
icmp = ctx.field_l4.icmp
@@ -674,17 +689,15 @@ def _generate_ip_info(ctx):
674689
else:
675690
icmp_info = 'type: %d, code: %d' % (icmp.type, icmp.code)
676691
output_str += 'ICMP: %s -> %s, %-15s, seq: %d' % (
677-
NetUtils.int2ip(
678-
socket.ntohl(ip.saddr)),
679-
NetUtils.int2ip(
680-
socket.ntohl(ip.daddr)),
692+
saddr,
693+
daddr,
681694
icmp_info,
682695
socket.ntohs(icmp.seq))
683696
else:
684697
fmt = '%s: %s -> %s'
685-
output_str += fmt % (NetUtils.int2proto(socket.ntohs(ctx.proto_l3)),
686-
NetUtils.int2ip(socket.ntohl(ip.saddr)),
687-
NetUtils.int2ip(socket.ntohl(ip.daddr)))
698+
output_str += fmt % (NetUtils.int2proto(socket.ntohs(ctx.proto_l3), 4),
699+
saddr,
700+
daddr)
688701
return output_str
689702

690703
@staticmethod
@@ -712,6 +725,9 @@ def _generate_proto_info(ctx):
712725
if proto_l3 == NetUtils.PROTO_L3['IP']:
713726
return Output._generate_ip_info(ctx)
714727

728+
if proto_l3 == NetUtils.PROTO_L3['IPV6']:
729+
return Output._generate_ip_info(ctx, True)
730+
715731
if proto_l3 == NetUtils.PROTO_L3['ARP']:
716732
return Output._generate_arp_info(ctx)
717733

utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,17 @@ def ip2int(addr):
162162
def int2ip(addr):
163163
return socket.inet_ntoa(struct.pack("!I", addr))
164164

165+
@staticmethod
166+
def int2ipv6(addr):
167+
return '%x:%x:%x:%x:%x:%x:%x:%x' % (socket.ntohs(addr[0]),
168+
socket.ntohs(addr[1]),
169+
socket.ntohs(addr[2]),
170+
socket.ntohs(addr[3]),
171+
socket.ntohs(addr[4]),
172+
socket.ntohs(addr[5]),
173+
socket.ntohs(addr[6]),
174+
socket.ntohs(addr[7]))
175+
165176
@staticmethod
166177
def proto2int(proto):
167178
proto = proto.upper()

0 commit comments

Comments
 (0)