summaryrefslogtreecommitdiff
path: root/proto_ipv6.c
blob: ba3f6c85203fa5bce6240dd10ff08c0436faeb6b (plain)
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
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * netsniff-ng - the packet sniffing beast
 * Copyright 2009, 2010 Daniel Borkmann.
 * Copyright 2010 Emmanuel Roullit.
 * Subject to the GPL, version 2.
 */

#include <stdio.h>
#include <stdint.h>
#include <netinet/in.h>    /* for ntohs() */
#include <arpa/inet.h>     /* for inet_ntop() */

#include "proto.h"
#include "dissector_eth.h"
#include "ipv6.h"
#include "geoip.h"
#include "pkt_buff.h"

extern void ipv6(struct pkt_buff *pkt);
extern void ipv6_less(struct pkt_buff *pkt);

void ipv6(struct pkt_buff *pkt)
{
	uint8_t traffic_class;
	uint32_t flow_label;
	char src_ip[INET6_ADDRSTRLEN];
	char dst_ip[INET6_ADDRSTRLEN];
	struct ipv6hdr *ip = (struct ipv6hdr *) pkt_pull(pkt, sizeof(*ip));
	struct sockaddr_in6 sas, sad;
	const char *city, *region, *country;

	if (ip == NULL)
		return;

	traffic_class = (ip->priority << 4) | 
			((ip->flow_lbl[0] & 0xF0) >> 4);
	flow_label = ((ip->flow_lbl[0] & 0x0F) << 8) |
		     (ip->flow_lbl[1] << 4) | ip->flow_lbl[2];

	inet_ntop(AF_INET6, &ip->saddr, src_ip, sizeof(src_ip));
	inet_ntop(AF_INET6, &ip->daddr, dst_ip, sizeof(dst_ip));

	tprintf(" [ IPv6 ");
	tprintf("Addr (%s => %s), ", src_ip, dst_ip);
	tprintf("Version (%u), ", ip->version);
	tprintf("TrafficClass (%u), ", traffic_class);
	tprintf("FlowLabel (%u), ", flow_label);
	tprintf("Len (%u), ", ntohs(ip->payload_len));
	tprintf("NextHdr (%u), ", ip->nexthdr);
	tprintf("HopLimit (%u)", ip->hop_limit);
	tprintf(" ]\n");

	memset(&sas, 0, sizeof(sas));
	sas.sin6_family = PF_INET6;
	memcpy(&sas.sin6_addr, &ip->saddr, sizeof(ip->saddr));

	memset(&sad, 0, sizeof(sad));
	sad.sin6_family = PF_INET6;
	memcpy(&sad.sin6_addr, &ip->daddr, sizeof(ip->daddr));

	if (geoip_working()) {
		tprintf("\t[ Geo (");
		if ((country = geoip6_country_name(&sas))) {
			tprintf("%s", country);
			if ((region = geoip6_region_name(&sas)))
				tprintf(" / %s", region);
			if ((city = geoip6_city_name(&sas)))
				tprintf(" / %s", city);
		} else {
			tprintf("local");
		}
		tprintf(" => ");
		if ((country = geoip6_country_name(&sad))) {
			tprintf("%s", country);
			if ((region = geoip6_region_name(&sad)))
				tprintf(" / %s", region);
			if ((city = geoip6_city_name(&sad)))
				tprintf(" / %s", city);
		} else {
			tprintf("local");
		}
		tprintf(") ]\n");
	}

	pkt_set_dissector(pkt, &eth_lay3, ip->nexthdr);
}

void ipv6_less(struct pkt_buff *pkt)
{
	char src_ip[INET6_ADDRSTRLEN];
	char dst_ip[INET6_ADDRSTRLEN];
	struct ipv6hdr *ip = (struct ipv6hdr *) pkt_pull(pkt, sizeof(*ip));

	if (ip == NULL)
		return;

	inet_ntop(AF_INET6, &ip->saddr, src_ip, sizeof(src_ip));
	inet_ntop(AF_INET6, &ip->daddr, dst_ip, sizeof(dst_ip));

	tprintf(" %s/%s Len %u", src_ip, dst_ip,
		ntohs(ip->payload_len));

	pkt_set_dissector(pkt, &eth_lay3, ip->nexthdr);
}

struct protocol ipv6_ops = {
	.key = 0x86DD,
	.print_full = ipv6,
	.print_less = ipv6_less,
};
ref='/cgit.cgi/linux/net-next.git/commit/?id=71d0ed7079dffbc5cd0941d77d9b84e04109c9bb'>net/act_pedit: Support using offset relative to the conventional network headersAmir Vadai3-16/+208 Extend pedit to enable the user setting offset relative to network headers. This change would enable to work with more complex header schemes (vs the simple IPv4 case) where setting a fixed offset relative to the network header is not enough. After this patch, the action has information about the exact header type and field inside this header. This information could be used later on for hardware offloading of pedit. Backward compatibility was being kept: 1. Old kernel <-> new userspace 2. New kernel <-> old userspace 3. add rule using new userspace <-> dump using old userspace 4. add rule using old userspace <-> dump using new userspace When using the extended api, new netlink attributes are being used. This way, operation will fail in (1) and (3) - and no malformed rule be added or dumped. Of course, new user space that doesn't need the new functionality can use the old netlink attributes and operation will succeed. Since action can support both api's, (2) should work, and it is easy to write the new user space to have (4) work. The action is having a strict check that only header types and commands it can handle are accepted. This way future additions will be much easier. Usage example: $ tc filter add dev enp0s9 protocol ip parent ffff: \ flower \ ip_proto tcp \ dst_port 80 \ action pedit munge tcp dport set 8080 pipe \ action mirred egress redirect dev veth0 Will forward tcp port whose original dest port is 80, while modifying the destination port to 8080. Signed-off-by: Amir Vadai <amir@vadai.me> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10net/skbuff: Introduce skb_mac_offset()Amir Vadai1-0/+5 Introduce skb_mac_offset() that could be used to get mac header offset. Signed-off-by: Amir Vadai <amir@vadai.me> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10Merge branch 'mlxsw-offload-mc-flood'David S. Miller