Function

u_int16_t cheat_check (u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)

Arguments

oldvalinv
The previous 32-bit values stored at some location
newval
The 32-bit value which has replaced the old value
oldcheck
The checksum of the packet with the old value

Description

This function is used when updating the checksum of a packet we have modified. It is important to use this rather than recalculating the entire checksum, in case the previous checksum was invalid. In that case, we must take care not to make it correct.

Function

int tcp_hash (__u32 daddr, __u16 dport, __u32 laddr, __u16 lport)

Arguments

daddr
Destination address
dport
Destination port
laddr
Local address
lport
Local port

Description

Creates a hash from a TCP packet, which will then be used to reference the connection in the hash table. The hash should be the same for all packets in the connection.

Function

unsigned int optlen (const u_int8_t * opt, unsigned int offset)

Arguments

opt
The location at which the options begin
offset
The offset of the option to examine

Description

Given a pointer to the beginning of a TCP option in a packet, return the length of the option. Either the option is known (NOP) and so the length can be returned straight away, or we check the following byte, which contains the length.

Function

unsigned int check_pq (unsigned int hooknum, struct sk_buff ** pskb, const struct net_device * in, const struct net_device * out, int (*okfn) (struct sk_buff *))

Arguments

hooknum
NetFilter hooknum, unused
pskb
Pointer to a pointer pointing to the socket buffer containing the incoming packet
in
The incoming network device, unused
out
The outgoing network device, unused
okfn
Function to call when all hooks completed, unused. NOTE: Don't call this!

Description

Here we determine whether the packet is a TCP packet or not. If it's not, we accept it without looking any further. If it is, we check for the TCP option containing p(q). We check all options, however the router module only ever inserts these as the first option, so it would be possible to look just at the first.

If we find the option, the value is recorded in the global variable, global_pq, overwriting the existing value. Hence only the latest value is ever kept. global_pq is a 16-bit integer.

Note that okfn is included here only because it is a standard function type used by Netfilter. We don't have a choice which arguments which get.

Pseudocode

if (skb pointer is NULL) return NF_ACCEPT Mark nfcache as NFC_UNKNOWN If (packet is not IP and TCP) return NF_ACCEPT ptr = beginning of options while (ptr < optionslength): if (header[ptr] == TCPO_QSIZE) record p(q) and return NF_ACCEPT ptr++ return NF_ACCEPT

Function

unsigned int modify_window (unsigned int hooknum, struct sk_buff ** pskb, const struct net_device * in, const struct net_device * out, int (*okfn) (struct sk_buff *))

Arguments

hooknum
The NetFilter hooknum, unused
pskb
Pointer to a pointer pointing to the skbuff containing the packet
in
The incoming network device, unused
out
The outgoing network device, unused
okfn
The function to be called when all hooks completed, unused. NOTE: Do not call this function!

Description

We used the window updating algorithm given in "A Novel Algorithm for Receiver-Based Management of Low Bandwidth Access Links" by Stephen Hanly, Rami Mukhtar and Lachlan Andrew to update the window in outgoing packets. This is only used if we have a value for p(q), but no check is made to ensure p(q) is a recent copy. If p(q) has not been received, no modification is made and packets will contain the window given by the standard Linux TCP/IP stack.

Obviously, only TCP packets will be modified here.

Pseudocode

if (we don't know p(q)) return NF_ACCEPT if (skb == NULL) return NF_ACCEPT Mark skb->nfcache as NFC_UNKNOWN if (packet no IP and TCP) return NF_ACCEPT if (local socket not known) return NF_ACCEPT get connection state from conntrack if (connection == NEW or RELATED) create new info struct look for connection info if (info == NULL) return NF_ACCEPT Record timestamp for packet in cyclic array calculate window using client's algorithm Adjust for window scaling factor Change window field in packet Recompute checksum if (time to clean) clean hash table return NF_ACCEPT

Function

struct rami_info* find_connection (struct sk_buff * skb)

Arguments

skb
Socket buffer for a packet

Description

Returns NULL if the skbuff could not be found. Otherwise a pointer to a &struct rami_info is returned;

Function

void insert_hash (struct sk_buff * skb, struct rami_info * info)

Arguments

skb
Adds a new connection into the hash table
info
Structure to place into the hash table

Function

struct rami_info * new_info (struct sk_buff * skb)

Arguments

skb
A sk_buff from which to create the struct

Description

Creates a new struct rami_info and initialises it with data from the sk_buff given.

Function

int init_module ( void)

Arguments

void
no arguments

Description

Registers the netfilter hooks with netfilter. Once this is done, all outgoing and incoming packets to this computer will pass through one of check_pq (incoming) or modify_window (outgoing).


Function

void cleanup_module ( void)

Arguments

void
no arguments

Description

Unregisters the netfilter hooks.


Function

void clean_hash ( void)

Arguments

void
no arguments

Description

This function searches through the hash table, and frees any connections which haven't been used for a while (ie. they haven't seen any packets)

Pseudocode

While (haven't cleaned "cleaned" entries): pick next entry if entry hasn't been used for 1 hour: free entry incremement counter of cleaned entries