搜尋此網誌

2011年5月19日 星期四

container_of()

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
#include <stdio.h>

/*
    #define container_of(ptr, type, member) ({             \
                 const typeof( ((type *)0)->member ) *__mptr = (ptr);     \
                 (type *)( (char *)__mptr - offsetof(type,member) );})


    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
*/



struct test {
    int a;
    char *b;
};

int main(int argc, char *argv[])
{
    //通过struct test成员b返回struct的入口地址
//container_of(&tmp.b, (struct test), b); 
 
    struct test tmp;
    struct test *ptmp;
    int offset;
    tmp.a = 10;

    printf("&tmp.a = %02x, &tmp.b = %02x\n", &tmp.a, &tmp.b);

    //定义一个 _mptr指针, 类型为struct test结构体中b成员的类型
    //typeof 为获取(((struct test*)0)->b)的类型,此处此类型为char*
    const typeof(((struct test *)0)->b) *_mptr = &tmp.b;
    printf("_mptr = %02x\n", _mptr);


    //#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    //TYPE是某struct的类型 0是一个假想TYPE类型struct,MEMBER是该struct中的一个成员. 
    //由于该struct的基地址为0, MEMBER的地址就是该成员相对与struct头地址的偏移量.
    offset = (int)(&((struct test *)0)->b);
    printf("offset = %d\n", offset);

    //_mptr的地址减去MEMBER在该struct中的偏移量得到的地址, 再转换成type型指针. 该指针就是struct的入口地址了.
    ptmp = (struct test *)((char *)_mptr - offset);
    
    printf("tmp = %02x, ptmp = %02x\n", &tmp, ptmp);
    printf("ptmp->a = %d\n", ptmp->a);
    return 0;
}

输出结果:
$ ./a.out 
&tmp.a = bfffe6a0, &tmp.b = bfffe6a4
_mptr = bfffe6a4
offset = 4
tmp = bfffe6a0, ptmp = bfffe6a0
ptmp->a = 10

2011年5月14日 星期六

iptables command and rules

$ iptables [-t table] command [match] [target]



iptables有5个链:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING;4个表:filter,nat,magle,raw.
4个表的优先级由高到低为:raw->mangle->nat->filter.

[-t table] 选项允许使用标准表之外的任何表。表是包含仅处理特定类型信息包的规则和链的信息包过滤表。该选项不是必需的,如果未指定, 则 filter 用作缺省表。
filter:表用于一般的信息包过滤。包括链表:
          INPUT:主要与想要进入本机的封包有关;
          OUTPUT:主要与本机所要送出的封包有关;
          FORWARD: 用于转发,与nat table 相关性较高。
nat:主要在进行来源与目的之 IP 或 port 的转换,与 Linux 本机较无关,主要与 Linux 主机后的区域网路内电脑较有相关。包括链表:
          PREROUTING:在进行路由判断之前所要进行的规则(DNAT/REDIRECT)
          POSTROUTING:在进行路由判断之后所要进行的规则(SNAT/MASQUERADE)
          OUTPUT:与发送出去的封包有关。
mangle:该表包含一些规则来标记用于高级路由的信息包,该表包含 PREROUTINGOUTPUT 链。 

RAW表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了RAW 表,在某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了.RAW表可以应用在那些不需要做nat的情况下,以提高性能。如大量访问的web服务器,可以让80端口不再让iptables做数据包的链接跟踪处理,以提高用户的访问速度。


各链表关系如下:



hash list

  1. 拉链法实现HASH链表
    1.  #include <stdio.h>
    2.  #include <string.h>
    3.  
    4.  #define N 14
    5.  #define M 14
    6.  
    7.   typedef struct struct_node{
    8.       int key;
    9.       struct struct_node *next;
    10.   }node;
    11.  
    12.   int get_hash_key(int key)
    13.   {
    14.       return key % 11;
    15.   }
    16.  
    17.   node **hash_init(node **hash_table,int m)
    18.   {
    19.       int i = 0;
    20.  
    21.       for ( ; i < m ; i++ )
    22.           hash_table[i] = NULL;
    23.  
    24.       return hash_table;
    25.   }
    26.  
    27.   node **create_hash_table(node **hash_table,int *a)
    28.   {
    29.       node *m;
    30.       int i = 0,key;
    31.  
    32.       for ( ; i < N ; i++ ) {
    33.           key = get_hash_key(a[i]);
    34.           m = (node *)malloc(sizeof(node));
    35.           if ( !) {
    36.               printf("malloc failed.\n");
    37.               exit(0);
    38.           }
    39.           m->key = a[i];
    40.  
    41.           if ( hash_table[key] == NULL ) {
    42.               hash_table[key] = m;
    43.               m->next = NULL;
    44.               continue;
    45.           }
    46.  
    47.           m->next = hash_table[key];
    48.           hash_table[key] = m;
    49.       }
    50.  
    51.       return hash_table;
    52.   }
    53.  
    54.   node *search_node(node **hash_table,int key)
    55.   {
    56.       node *p;
    57.       int i = 0,hash_key;
    58.  
    59.       hash_key = get_hash_key(key);
    60.       p = hash_table[hash_key];
    61.  
    62.       if ( !)
    63.           return NULL;
    64.  
    65.       while ( p ) {
    66.           if ( p->key == key )
    67.               return p;
    68.           p = p->next;
    69.       }
    70.  
    71.       return NULL;
    72.   }
    73.  
    74.   node **delete_node(node **hash_table,int key)
    75.   {
    76.       node *p,*q,*head;
    77.  
    78.       p = hash_table[get_hash_key(key)];
    79.       if ( !) {
    80.           printf("[-] no key in hash_table .\n");
    81.           return hash_table;
    82.       }
    83.  
    84.       if ( p->next == NULL ) {
    85.           hash_table[get_hash_key(key)] = NULL;
    86.           return hash_table;
    87.       }
    88.  
    89.       while ( p != NULL ) {
    90.           if ( p->key == key ) {
    91.               if ( p == hash_table[get_hash_key(key)] ) {
    92.                   hash_table[get_hash_key(key)] = p->next;
    93.                   return hash_table;
    94.               }
    95.               else{
    96.                   q->next = p->next;
    97.                   return hash_table;
    98.               }
    99.           }
    100.           q = p;
    101.           p = p->next;
    102.       }
    103.  
    104.       return NULL;
    105.   }
    106.  
    107.   void print_node(node *head)
    108.   {
    109.       if ( !head )
    110.           return ;
    111.  
    112.       while ( head != NULL ) {
    113.           printf("%d,",head->key);
    114.           head = head->next;
    115.       }
    116.   }
    117.  
    118.   void print_hash_table(node **hash_table)
    119.   {
    120.       int i = 0;
    121.  
    122.       for ( ; i < M ; i++ ) {
    123.           print_node(hash_table[i]);
    124.           printf("\n");
    125.       }
    126.   }
    127.  
    128.   void destroy_node(node *head)
    129.   {
    130.       node *p;
    131.  
    132.       while ( head != NULL ) {
    133.           p = head->next;
    134.           free(head);
    135.           head = p;
    136.       }
    137.   }
    138.  
    139.   void destroy_hash_table(node **hash_table)
    140.   {
    141.       int i = 0;
    142.  
    143.       for ( ; i < N ; i++ )
    144.           destroy_node(hash_table[i]);
    145.   }
    146.  
    147.   int main(void)
    148.   {
    149.       node *hash_table[M],*p,**s;
    150.       int a[N] = {47,7,29,11,16,92,22,8,3,50,37,89,94,21};
    151.  
    152.       hash_init(hash_table,M);
    153.       printf("[+] hash init ok.\n");
    154.       create_hash_table(hash_table,a);
    155.       printf("[+] hash table create ok.\n");
    156.       print_hash_table(hash_table);
    157.  
    158.       printf("..................................\n");
    159.  
    160.       p = search_node(hash_table,29);
    161.       printf("%d\n",p->key);
    162.       printf("..................................\n");
    163.  
    164.       s = delete_node(hash_table,8);
    165.       if ( !)
    166.           printf("[-] hash_table NULL.\n");
    167.       print_hash_table(s);
    168.  
    169.       destroy_hash_table(hash_table);
    170.       printf("[+] destroy hash_table ok.\n");
    171.  
    172.       return 0;
    173.   }