如何安装kernel-devel,可以参考我之前的文章:《Linux下编译驱动发现没有内核源码的解决办法》

下面是我写的一个自动脚本:

1
2
3
cd /usr/src/kernels
cd $(ls -d */ | head -n 1)
ln -s -f $(pwd) /lib/modules/$(uname -r)/build

至于为什么要费劲去 cd $(ls -d */ | head -n 1) 的原因是:很多系统装出来的 kernel-devel 目录名称跟 $(uname -r) 并不一致

至此这个问题修复完成。

在Linux 2.6.33.6中,源文件在:/usr/src/kernels/2.6.33.6/include/linux/skbuff.h

struct sk_buff在2.6.18中的定义:

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
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
struct sock *sk;
struct skb_timeval tstamp;
struct net_device *dev;
struct net_device *input_dev;
union {
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct ipv6hdr *ipv6h;
unsigned char *raw;
} h;
union {
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
unsigned char *raw;
} nh;
union {
unsigned char *raw;
} mac;
struct dst_entry *dst;
struct sec_path *sp;
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48];
unsigned int len,
data_len,
mac_len,
csum;
__u32 priority;
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
#ifndef CONFIG_XEN
ipvs_property:1;
#else
ipvs_property:1,
proto_data_valid:1,
proto_csum_blank:1;
#endif
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
#ifdef CONFIG_NETFILTER
struct nf_conntrack *nfct;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
__u32 nfmark;
#endif /* CONFIG_NETFILTER */
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd; /* traffic control verdict */
#endif
#endif
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
#endif
/* These elements must be at the end, see alloc_skb() for details. */
unsigned int truesize;
atomic_t users;
unsigned char *head,
*data,
*tail,
*end;
/* Extra stuff at the end to avoid breaking abi */
#ifndef __GENKSYMS__
int peeked;
#endif
};

struct sk_buff在2.6.33中的定义:

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
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
ktime_t tstamp;
struct sock *sk;
struct net_device *dev;
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48] __aligned(8);
unsigned long _skb_dst;
#ifdef CONFIG_XFRM
struct sec_path *sp;
#endif
unsigned int len,
data_len;
__u16 mac_len,
hdr_len;
union {
__wsum csum;
struct {
__u16 csum_start;
__u16 csum_offset;
};
};
__u32 priority;
kmemcheck_bitfield_begin(flags1);
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
__be16 protocol:16;
kmemcheck_bitfield_end(flags1);
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
int skb_iif;
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd; /* traffic control verdict */
#endif
#endif
kmemcheck_bitfield_begin(flags2);
__u16 queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
kmemcheck_bitfield_end(flags2);
/* 0/14 bit hole */
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
#endif
union {
__u32 mark;
__u32 dropcount;
};
__u16 vlan_tci;
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
/* These elements must be at the end, see alloc_skb() for details. */
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head,
*data;
unsigned int truesize;
atomic_t users;
};

有了以上定义的话,我们就可以做类似如下定义来使我们的驱动支持多内核了:

1
2
3
4
5
6
struct sk_buff *new_skb;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
new_skb->mac.raw = (unsigned char *)new_eth_p;
#else
new_skb->mac_header = (unsigned char *)new_eth_p;
#endif

参考:http://www.linuxquestions.org/questions/linux-kernel-70/struct-sk_buff-differs-in-2-6-18-and-2-6-33-kernel-882507/

CentOS 上安装新版本 python

请看: 安装python以及解决版本问题

但在安装新版本后,yum不能正常使用了。原因是yum是基于默认的python版本运行的,例如CentOS6.2基于python2.6。但我们安装版本后建立了链接,覆盖掉了默认python调用,导致yum脚本无法正常调用到自己想要的版本。

解决方案

1
vim /usr/bin/yum

将第一行 #!/usr/bin/python 修改成 #!/usr/bin/python2.6

安装新版本python

1
2
3
4
5
6
wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2
tar xjf Python-2.7.3.tar.bz2
cd Python-2.7.3
./configure
make
make atlinstall

这时 python2.7.3 版本已经安装成功了。
但调用 python –version 依然会显示并使用旧版本

解决办法就是重新建立一个链接并覆盖掉旧的

1
ln -s /usr/local/bin/python2.7 /usr/bin/python -f

再调用 python –version 显示结果

1
2
[root@centos]# python --version
Python 2.7.3

至此,问题解决 :)

压缩

1
enData = zlib.compress(data)[2:-4]

对应:

1
compress2(dstbuf, &dstLen, strSrc, srcLen, 6);

解压

1
deData = zlib.decompress(enData, -zlib.MAX_WBITS)

对应:

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
bool gzipInflate( const std::string& compressedBytes, std::string& uncompressedBytes ) {
if ( compressedBytes.size() == 0 ) {
uncompressedBytes = compressedBytes ;
return true ;
}
uncompressedBytes.clear() ;
unsigned full_length = compressedBytes.size() ;
unsigned half_length = compressedBytes.size() / 2;
unsigned uncompLength = full_length ;
char* uncomp = (char*) calloc( sizeof(char), uncompLength );
z_stream strm;
strm.next_in = (Bytef *) compressedBytes.c_str();
strm.avail_in = compressedBytes.size() ;
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
bool done = false ;
//if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK)
if (inflateInit2(&strm, -MAX_WBITS) != Z_OK)
{
free( uncomp );
return false;
}
while (!done) {
// If our output buffer is too small
if (strm.total_out >= uncompLength ) {
// Increase size of output buffer
char* uncomp2 = (char*) calloc( sizeof(char), uncompLength + half_length );
memcpy( uncomp2, uncomp, uncompLength );
uncompLength += half_length ;
free( uncomp );
uncomp = uncomp2 ;
}
strm.next_out = (Bytef *) (uncomp + strm.total_out);
strm.avail_out = uncompLength - strm.total_out;
// Inflate another chunk.
int err = inflate (&strm, Z_SYNC_FLUSH);
if (err == Z_STREAM_END) done = true;
else if (err != Z_OK) {
break;
}
}
if (inflateEnd (&strm) != Z_OK) {
free( uncomp );
return false;
}
for ( size_t i=0; i<strm.total_out; ++i ) {
uncompressedBytes += uncomp[ i ];
}
free( uncomp );
return true ;
}

Linux使用gcc编译使用zlib库的代码时,使用 -lz 来链接(link) zlib 库。

否则就会出现类似 undefined reference to `deflateInit_’ 的错误

当调用tcpdump时,出现错误:tcpdump: USB link-layer type filtering not implemented

原因

说明系统可能有多块网卡共存。

需要指定工作网卡才能开始截包,使用参数举例

1
[root@centos]# tcpdump -i eth0 udp port 53

在实际使用中例子中“eth0”“udp”“53”等参数,要根据实际需要来进行修改。
虽然一般单网卡默认名称应该是eth0,但也有其他情况。实际中要使用ifconfig查看自己需要使用的网卡。

错误原因

我手上一个项目本身采用gcc编译。后来因为代码功能需要移植到g++中时,出现了 “inet_addr” was not declared in this scope 这个错误。

解决方案

1
2
// 添加该头文件
#include <arpa/inet.h>

如果出现下面错误:

1
2
error: string: No such file or directory
error: vector: No such file or directory

说明在将g++项目用gcc编译