forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_xlate1.c
98 lines (89 loc) · 2.31 KB
/
test_xlate1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright (c) PLUMgrid, Inc.
// Licensed under the Apache License, Version 2.0 (the "License")
#include <bcc/proto.h>
struct IPKey {
u32 dip;
u32 sip;
};
struct IPLeaf {
u32 xdip;
u32 xsip;
u64 ip_xlated_pkts;
u64 arp_xlated_pkts;
};
BPF_HASH(xlate, struct IPKey, struct IPLeaf, 1024);
int on_packet(struct __sk_buff *skb) {
u8 *cursor = 0;
u32 orig_dip = 0;
u32 orig_sip = 0;
struct IPLeaf xleaf = {};
ethernet: {
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
switch (ethernet->type) {
case ETH_P_IP: goto ip;
case ETH_P_ARP: goto arp;
case ETH_P_8021Q: goto dot1q;
default: goto EOP;
}
}
dot1q: {
struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
switch (dot1q->type) {
case ETH_P_IP: goto ip;
case ETH_P_ARP: goto arp;
default: goto EOP;
}
}
arp: {
struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
orig_dip = arp->tpa;
orig_sip = arp->spa;
struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
struct IPLeaf *xleafp = xlate.lookup(&key);
if (xleafp) {
xleaf = *xleafp;
arp->tpa = xleaf.xdip;
arp->spa = xleaf.xsip;
lock_xadd(&xleafp->arp_xlated_pkts, 1);
}
goto EOP;
}
ip: {
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
orig_dip = ip->dst;
orig_sip = ip->src;
struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
struct IPLeaf *xleafp = xlate.lookup(&key);
if (xleafp) {
xleaf = *xleafp;
ip->dst = xleaf.xdip;
incr_cksum_l3(&ip->hchecksum, orig_dip, xleaf.xdip);
ip->src = xleaf.xsip;
incr_cksum_l3(&ip->hchecksum, orig_sip, xleaf.xsip);
lock_xadd(&xleafp->ip_xlated_pkts, 1);
}
switch (ip->nextp) {
case 6: goto tcp;
case 17: goto udp;
default: goto EOP;
}
}
udp: {
struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
if (xleaf.xdip) {
incr_cksum_l4(&udp->crc, orig_dip, xleaf.xdip, 1);
incr_cksum_l4(&udp->crc, orig_sip, xleaf.xsip, 1);
}
goto EOP;
}
tcp: {
struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
if (xleaf.xdip) {
incr_cksum_l4(&tcp->cksum, orig_dip, xleaf.xdip, 1);
incr_cksum_l4(&tcp->cksum, orig_sip, xleaf.xsip, 1);
}
goto EOP;
}
EOP:
return 0;
}