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 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;
}
输出结果:
&tmp.a = bfffe6a0, &tmp.b = bfffe6a4
_mptr = bfffe6a4
offset = 4
tmp = bfffe6a0, ptmp = bfffe6a0
ptmp->a = 10 |
搜尋此網誌
2011年5月19日 星期四
container_of()
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:该表包含一些规则来标记用于高级路由的信息包,该表包含
PREROUTING
和 OUTPUT
链。 RAW表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了RAW 表,在某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了.RAW表可以应用在那些不需要做nat的情况下,以提高性能。如大量访问的web服务器,可以让80端口不再让iptables做数据包的链接跟踪处理,以提高用户的访问速度。
各链表关系如下:
hash list
- 拉链法实现HASH链表
- #include <stdio.h>
- #include <string.h>
- #define N 14
- #define M 14
- typedef struct struct_node{
- int key;
- }node;
- {
- }
- {
- int i = 0;
- for ( ; i < m ; i++ )
- hash_table[i] = NULL;
- return hash_table;
- }
- node **create_hash_table(node **hash_table,int *a)
- {
- node *m;
- for ( ; i < N ; i++ ) {
- if ( !m ) {
- }
- m->key = a[i];
- m->next = NULL;
- continue;
- }
- }
- return hash_table;
- }
- {
- node *p;
- int i = 0,hash_key;
- p = hash_table[hash_key];
- if ( !p )
- return NULL;
- while ( p ) {
- return p;
- p = p->next;
- }
- return NULL;
- }
- {
- node *p,*q,*head;
- if ( !p ) {
- return hash_table;
- }
- if ( p->next == NULL ) {
- return hash_table;
- }
- while ( p != NULL ) {
- return hash_table;
- }
- else{
- q->next = p->next;
- return hash_table;
- }
- }
- q = p;
- p = p->next;
- }
- return NULL;
- }
- void print_node(node *head)
- {
- if ( !head )
- return ;
- while ( head != NULL ) {
- head = head->next;
- }
- }
- void print_hash_table(node **hash_table)
- {
- int i = 0;
- for ( ; i < M ; i++ ) {
- print_node(hash_table[i]);
- }
- }
- void destroy_node(node *head)
- {
- node *p;
- while ( head != NULL ) {
- p = head->next;
- free(head);
- head = p;
- }
- }
- void destroy_hash_table(node **hash_table)
- {
- int i = 0;
- for ( ; i < N ; i++ )
- destroy_node(hash_table[i]);
- }
- int main(void)
- {
- node *hash_table[M],*p,**s;
- int a[N] = {47,7,29,11,16,92,22,8,3,50,37,89,94,21};
- create_hash_table(hash_table,a);
- print_hash_table(hash_table);
- p = search_node(hash_table,29);
- s = delete_node(hash_table,8);
- if ( !s )
- print_hash_table(s);
- destroy_hash_table(hash_table);
- return 0;
- }
訂閱:
文章 (Atom)