skbuffer - Linux network buffers


November 8th, 2005 by paolo


Author: Paolo Ardoino

skbuff are buffers used by Linux network layers ; its structure is defined in <linux/skbuff.h> .
skbuffs are linked lists as we can easily see :

1
2
3
        /* These two members must be first . */
        struct sk_buff          *next; // Next buffer in list
        struct sk_buff          *prev; // Previous buffer in list

Follows the description of all fields of the structure taken from the header file:

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
/**
 *      struct sk_buff - socket buffer
 *      @next: Next buffer in list
 *      @prev: Previous buffer in list
 *      @list: List we are on
 *      @sk: Socket we are owned by
 *      @tstamp: Time we arrived
 *      @dev: Device we arrived on/are leaving by
 *      @input_dev: Device we arrived on
 *      @h: Transport layer header
 *      @nh: Network layer header
 *      @mac: Link layer header
 *      @dst: destination entry
 *      @sp: the security path, used for xfrm
 *      @cb: Control buffer. Free for use by every layer. Put private vars here
 *      @len: Length of actual data
 *      @data_len: Data length
 *      @mac_len: Length of link layer header
 *      @csum: Checksum
 *      @local_df: allow local fragmentation
 *      @cloned: Head may be cloned (check refcnt to be sure)
 *      @nohdr: Payload reference only, must not modify header
 *      @pkt_type: Packet class
 *      @ip_summed: Driver fed us an IP checksum
 *      @priority: Packet queueing priority
 *      @users: User count - see {datagram,tcp}.c
 *      @protocol: Packet protocol from driver
 *      @truesize: Buffer size
 *      @head: Head of buffer
 *      @data: Data head pointer
 *      @tail: Tail pointer
 *      @end: End pointer
 *      @destructor: Destruct function
 *      @nfmark: Can be used for communication between hooks
 *      @nfct: Associated connection, if any
 *      @nfctinfo: Relationship of this skb to the connection
 *      @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
 *      @tc_index: Traffic control index
 *      @tc_verd: traffic control verdict
 */

Now let’s take a look to the functions we need to work with network buffers:
allow_skb() creates and initializes a new ,ready to use , sk_buff .
kfree_skb() releases the buffer .
skb_clone() makes a copy of a skb_buff .
skb_queue_head() add a buffer on the head of the list .
skb_queue_tail() add a buffer on the tail of the list .
skb_unlink() removes a skb_buff from lists , but not releases it .
skb_dequeue() takes the first ( header ) skb_buff .

Here is a simple kernel module that uses Linux network buffers to show incoming and
outgoing packets .

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* SKB ( Linux Network Buffers ) test on Linux 2.6.x kernels
 * This module ( lkm ) will show show all incoming packets
 * and outgoing packets from the local computer
 * To get it working edit #define MYADDR setting
 * the ip of your computer . This is only an example to
 * show how create kernel sniffers or hijacker modules .
 */
#include
<linux>
#include
<linux>
#include
<linux>
 
#include
<linux>
 
#include
<linux>
#include
<linux>
 
#include
<linux>
#include
<linux>
 
#define DEBUG 1
 
// ip address of the local computer
#define MYADDR "192.168.0.3"
 
MODULE_AUTHOR("Paolo Ardoino");
MODULE_LICENSE("GPL");
#define MODNAME "SKBTEST"
 
unsigned long fromaddr;
unsigned short int fromport;
struct packet_type myskb;
 
// my_addr convert an ip address string from standard dot notation
// to an unsigned long
static unsigned long my_addr(char *ip)
{
  unsigned long tmp;
  unsigned int val;
  int ctr;
 
  tmp = 0;
  for (ctr = 0; ctr < 4; ctr++) {
    tmp <<= 8;
    if(*ip != '\0') {
      val = 0;
      while (*ip != '\0' &amp;&amp; *ip != '.') {
        val *= 10;
        val += *ip - '0';
        ip++;
      }
      tmp |= val;
      if (*ip != '\0') {
        ip++;
      }
    }
  }
  return htonl(tmp);
}
 
// my_ntoa convers an unsigned long ( Internet host address )
// given in network byte order to a string in standard dot notation
static char *my_ntoa(unsigned long addr)
{
  static char buff[18];
  char *p;
 
  p = (char *) &amp;addr;
  sprintf(buff, "%d.%d.%d.%d", (*p &amp; 255), (*(p + 1) &amp; 255), (*(p + 2) &amp; 255), (*(p + 3) &amp; 255));
  return buff;
}                                                        
 
// my_pkt analyzes packets in skbuff
static int my_pkt(struct sk_buff *skb, struct device *d, struct packet_type *pt)
{
  if (skb->nh.iph->protocol == IPPROTO_TCP) {
// outgoing packets
    if (skb->nh.iph->saddr == fromaddr) {
#ifdef DEBUG
      printk("[%s] PACKET SENT FROM LOCALHOST:%d TO %s:%d HOST\n",
      MODNAME, ntohs(skb->h.th->source), my_ntoa(skb->nh.iph->daddr),
      ntohs(skb->h.th->dest));
#endif
    } else {
// incoming packets
      if (skb->nh.iph->daddr == fromaddr) {
#ifdef DEBUG
      printk("[%s] PACKET RECV FROM %s:%d HOST TO LOCALHOST:%d HOST\n",
        MODNAME, my_ntoa(skb->nh.iph->saddr),
        ntohs(skb->h.th->source), ntohs(skb->h.th->dest));
#endif
      }
    }
  }
  kfree_skb(skb);
  return 0;
}
 
static int __init modinit(void)
{
  printk("[%s] MODULE LOADED (@ 2007 Involutive http://www.involutive.com\n
  author: Paolo Ardoino < paolo.ardoino@gmail.com >) \n", MODNAME);
 
  fromaddr = my_addr(MYADDR);
 
  myskb.type = htons(ETH_P_ALL);
  myskb.func = my_pkt;
  myskb.dev = NULL;
  dev_add_pack(&amp;myskb);
 
  return 0;
}
 
static void __exit modcleanup(void)
{
  printk("[%s] CLEANUP COMPLETE\n", MODNAME);
  dev_remove_pack(&amp;myskb);
  return;
}
 
module_init(modinit);
module_exit(modcleanup);
</linux></linux></linux></linux></linux></linux></linux></linux>

Posted in Linux |

del.icio.us - Digg it - Furl - Google - Netscape - StumbleUpon

One Response

  1. Ashok Says:

    I was using ur hijaker module…
    by changing the local IP to my system…
    but it gave me follwoing errors…

    Khijaker.c:73: warning: `struct device’ declared inside parameter list
    Khijaker.c:73: warning: its scope is only this definition or declaration, which is probably not what you want
    Khijaker.c: In function `my_pkt’:
    Khijaker.c:75: `IPPROTO_TCP’ undeclared (first use in this function)
    Khijaker.c:75: (Each undeclared identifier is reported only once
    Khijaker.c:75: for each function it appears in.)
    Khijaker.c:100:10: warning: multi-line string literals are deprecated
    Khijaker.c: In function `modinit’:
    Khijaker.c:106: warning: assignment from incompatible pointer type

    any solution or this…?
    waiting!!!!!!!
    Thanks
    ASM

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.