Skip to content

Commit

Permalink
Merge pull request OpenCloudOS#2 from xmmgithub/master
Browse files Browse the repository at this point in the history
ipv6 support
  • Loading branch information
menglongdong committed May 20, 2022
2 parents 5e008bf + 2799e38 commit becb8f4
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 19 deletions.
27 changes: 21 additions & 6 deletions nettrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <uapi/linux/if_ether.h>
#include <uapi/linux/tcp.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/ipv6.h>
#include <uapi/linux/udp.h>
#include <uapi/linux/icmp.h>
#include <bcc/proto.h>
Expand All @@ -22,6 +23,10 @@ typedef struct {
u32 saddr;
u32 daddr;
} ip;
struct {
u8 saddr[16];
u8 daddr[16];
} ipv6;
} field_l3;
#ifdef NT_ENABLE_RET
u64 ret_val;
Expand Down Expand Up @@ -183,13 +188,21 @@ static inline bool do_filter(context_t *ctx, sk_buff_t *skb)
}

static inline int parse_ip(context_t *ctx, sk_buff_t *skb,
struct iphdr *ip)
struct iphdr *ip, bool is_ipv6)
{
void *l4;

ctx->proto_l4 = ip->protocol;
ctx->field_saddr = ip->saddr;
ctx->field_daddr = ip->daddr;
if (is_ipv6) {
struct ipv6hdr *ipv6 = (void *)ip;
ctx->proto_l4 = ipv6->nexthdr;

bpf_probe_read(ctx->field_l3.ipv6.saddr, 16, &ipv6->saddr);
bpf_probe_read(ctx->field_l3.ipv6.daddr, 16, &ipv6->daddr);
} else {
ctx->proto_l4 = ip->protocol;
ctx->field_saddr = ip->saddr;
ctx->field_daddr = ip->daddr;
}

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

switch (ctx->proto_l3) {
case htons(ETH_P_IP):
return parse_ip(ctx, skb, l3);
return parse_ip(ctx, skb, l3, false);
case htons(ETH_P_ARP):
return parse_arp(ctx, skb, l3);
case htons(ETH_P_IPV6):
return parse_ip(ctx, skb, l3, true);
default:
return 0;
}
Expand All @@ -282,7 +297,7 @@ static inline int init_ctx(context_t *ctx, sk_buff_t *skb)
ctx->proto_l3 = htons(ETH_P_IP);
l3 = get_l3_send(skb);
if (l3)
return parse_ip(ctx, skb, l3);
return parse_ip(ctx, skb, l3, false);
return 0;
}

Expand Down
42 changes: 29 additions & 13 deletions nettrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,12 @@ class IP(ctypes.Structure):
('daddr', ctypes.c_uint32),
]

class IPV6(ctypes.Structure):
_fields_ = [
('saddr', ctypes.c_uint16*8),
('daddr', ctypes.c_uint16*8),
]

class ArpExt(ctypes.Structure):
_fields_ = [
('op', ctypes.c_uint16)
Expand Down Expand Up @@ -570,6 +576,7 @@ class Icmp(ctypes.Structure):
class FieldL3(ctypes.Union):
_fields_ = [
('ip', IP),
('ipv6', IPV6),
]

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

@staticmethod
def _generate_ip_info(ctx):
ip = ctx.field_l3.ip
def _generate_ip_info(ctx, is_ipv6=False):
output_str = ''

if not is_ipv6:
ip = ctx.field_l3.ip
saddr = NetUtils.int2ip(socket.ntohl(ip.saddr))
daddr = NetUtils.int2ip(socket.ntohl(ip.daddr))
else:
ip = ctx.field_l3.ipv6
saddr = NetUtils.int2ipv6(ip.saddr)
daddr = NetUtils.int2ipv6(ip.daddr)

if ctx.proto_l4 == socket.IPPROTO_TCP:
tcp = ctx.field_l4.tcp
output_str += 'TCP: %s:%d -> %s:%d, seq:%d, ack:%d %s' % (
NetUtils.int2ip(socket.ntohl(ip.saddr)),
saddr,
socket.ntohs(tcp.sport),
NetUtils.int2ip(socket.ntohl(ip.daddr)),
daddr,
socket.ntohs(tcp.dport),
socket.ntohl(tcp.seq),
socket.ntohl(tcp.ack),
NetUtils.int2tcp_flags(tcp.flags))
elif ctx.proto_l4 == socket.IPPROTO_UDP:
udp = ctx.field_l4.udp
output_str += 'UDP: %s:%d -> %s:%d' % (
NetUtils.int2ip(socket.ntohl(ip.saddr)),
saddr,
socket.ntohs(udp.sport),
NetUtils.int2ip(socket.ntohl(ip.daddr)),
daddr,
socket.ntohs(udp.dport))
elif ctx.proto_l4 == socket.IPPROTO_ICMP:
icmp = ctx.field_l4.icmp
Expand All @@ -674,17 +689,15 @@ def _generate_ip_info(ctx):
else:
icmp_info = 'type: %d, code: %d' % (icmp.type, icmp.code)
output_str += 'ICMP: %s -> %s, %-15s, seq: %d' % (
NetUtils.int2ip(
socket.ntohl(ip.saddr)),
NetUtils.int2ip(
socket.ntohl(ip.daddr)),
saddr,
daddr,
icmp_info,
socket.ntohs(icmp.seq))
else:
fmt = '%s: %s -> %s'
output_str += fmt % (NetUtils.int2proto(socket.ntohs(ctx.proto_l3)),
NetUtils.int2ip(socket.ntohl(ip.saddr)),
NetUtils.int2ip(socket.ntohl(ip.daddr)))
output_str += fmt % (NetUtils.int2proto(socket.ntohs(ctx.proto_l3), 4),
saddr,
daddr)
return output_str

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

if proto_l3 == NetUtils.PROTO_L3['IPV6']:
return Output._generate_ip_info(ctx, True)

if proto_l3 == NetUtils.PROTO_L3['ARP']:
return Output._generate_arp_info(ctx)

Expand Down
11 changes: 11 additions & 0 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,17 @@ def ip2int(addr):
def int2ip(addr):
return socket.inet_ntoa(struct.pack("!I", addr))

@staticmethod
def int2ipv6(addr):
return '%x:%x:%x:%x:%x:%x:%x:%x' % (socket.ntohs(addr[0]),
socket.ntohs(addr[1]),
socket.ntohs(addr[2]),
socket.ntohs(addr[3]),
socket.ntohs(addr[4]),
socket.ntohs(addr[5]),
socket.ntohs(addr[6]),
socket.ntohs(addr[7]))

@staticmethod
def proto2int(proto):
proto = proto.upper()
Expand Down

0 comments on commit becb8f4

Please sign in to comment.