2017-03-30 21:45:41 -07:00
/* Copyright (c) 2017 Facebook
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation .
*/
# include <stddef.h>
2017-05-17 15:18:05 -07:00
# include <string.h>
2017-03-30 21:45:41 -07:00
# include <linux/bpf.h>
# include <linux/if_ether.h>
# include <linux/if_packet.h>
# include <linux/ip.h>
# include <linux/ipv6.h>
# include <linux/in.h>
# include <linux/tcp.h>
# include <linux/pkt_cls.h>
# include "bpf_helpers.h"
2017-05-01 12:43:49 -07:00
# include "bpf_endian.h"
2017-03-30 21:45:41 -07:00
# define barrier() __asm__ __volatile__("": : :"memory")
int _version SEC ( " version " ) = 1 ;
SEC ( " test1 " )
int process ( struct __sk_buff * skb )
{
void * data_end = ( void * ) ( long ) skb - > data_end ;
void * data = ( void * ) ( long ) skb - > data ;
struct ethhdr * eth = ( struct ethhdr * ) ( data ) ;
struct tcphdr * tcp = NULL ;
__u8 proto = 255 ;
__u64 ihl_len ;
if ( eth + 1 > data_end )
return TC_ACT_SHOT ;
2017-04-27 01:39:34 +02:00
if ( eth - > h_proto = = bpf_htons ( ETH_P_IP ) ) {
2017-03-30 21:45:41 -07:00
struct iphdr * iph = ( struct iphdr * ) ( eth + 1 ) ;
if ( iph + 1 > data_end )
return TC_ACT_SHOT ;
ihl_len = iph - > ihl * 4 ;
proto = iph - > protocol ;
tcp = ( struct tcphdr * ) ( ( void * ) ( iph ) + ihl_len ) ;
2017-04-27 01:39:34 +02:00
} else if ( eth - > h_proto = = bpf_htons ( ETH_P_IPV6 ) ) {
2017-03-30 21:45:41 -07:00
struct ipv6hdr * ip6h = ( struct ipv6hdr * ) ( eth + 1 ) ;
if ( ip6h + 1 > data_end )
return TC_ACT_SHOT ;
ihl_len = sizeof ( * ip6h ) ;
proto = ip6h - > nexthdr ;
tcp = ( struct tcphdr * ) ( ( void * ) ( ip6h ) + ihl_len ) ;
}
if ( tcp ) {
if ( ( ( void * ) ( tcp ) + 20 ) > data_end | | proto ! = 6 )
return TC_ACT_SHOT ;
barrier ( ) ; /* to force ordering of checks */
if ( ( ( void * ) ( tcp ) + 18 ) > data_end )
return TC_ACT_SHOT ;
if ( tcp - > urg_ptr = = 123 )
return TC_ACT_OK ;
}
return TC_ACT_UNSPEC ;
}