- 浏览: 314157 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
JQ_AK47:
...
Linux下直接发送以太包 -
winsen2009:
谢谢分享,如果能再来一个列子就更好了,刚接触看完还是不懂的用
UNPv1_r3读书笔记: SCTP编程
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严
禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
UNP第一卷的第3版是著名的RWS先生魂归上帝后由后人添加新的一些新的东西后发布的,增加的部分包括 PF_KEY和SCTP等的相关编程。今天重读UNP,看看PF_KEY一章。 PF_KEY协议族主要用来处理安全联盟SA的,对SADB(SA数据库)进行管理,主要用在IPSEC协议中,其他 协议如OSPF等用到密钥的协议中也可以用。 PF_KEY_v2的编程API在RFC2367中定义,其实在freeswan的pluto中有完整的PF_KEY运用实例。在UNP这 本书中只是很简单的介绍了一下,属于入门级,详细说明要看RFC,程序实例看pluto。 PF_KEY协议族只支持RAW模式,只能由ROOT权限的用户打开PF_KEY类型的套接口,这和netlink类型套接 口是类似的,而且数据格式也是以消息方式传输。 进程PF_KEY类型的套接口和netlink套接口一样,可以双向和内核进行通信。可以向内核和其他打开了 PF_KEY套接口发送消息,可进行SADB中的SA项的增加和删除;也可以从内核中接收消息。 PF_KEY的消息的数据格式都是有一个格式相同的数据头(12字节长), 说明数据类型等信息, 然后后面可 以跟0到多个扩展的结构用来描述不同类型的具体数据内容: 消息头: struct sadb_msg { u_int8_t sadb_msg_version; /* PF_KEY_V2 */ u_int8_t sadb_msg_type; /* see Figure 19.2 */ u_int8_t sadb_msg_errno; /* error indication */ u_int8_t sadb_msg_satype; /* see Figure 19.3 */ u_int16_t sadb_msg_len; /* length of header + extensions / 8 */ u_int16_t sadb_msg_reserved; /* zero on transmit, ignored on receive */ u_int32_t sadb_msg_seq; /* sequence number */ u_int32_t sadb_msg_pid; /* process ID of source or dest */ }; 结构中的元素含义都比较直观, sadb_msg_type是消息的类型, 基本反映命令动作, 如读当前SADB, 增 加删除SA等, sadb_msg_satype表示的是要操作的SA的类型,表示要对哪些SA进行命令动作. 基本通信过程: 先打开PF_KEY的套接口, 填消息头信息, 必要时再填后续数据信息, 可以用write()函数将数据写到套 接口, 用read()函数从套接口读回应数据: dump_sadb: 1 void 2 sadb_dump(int type) 3 { 4 int s; 5 char buf[4096]; 6 struct sadb_msg msg; 7 int goteof; 8 s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2); 9 /* Build and write SADB_DUMP request */ 10 bzero(&msg, sizeof (msg)); 11 msg.sadb_msg_version = PF_KEY_V2; 12 msg.sadb_msg_type = SADB_DUMP; 13 msg.sadb_msg_satype = type; 14 msg.sadb_msg_len = sizeof (msg) / 8; 15 msg.sadb_msg_pid = getpid(); 16 printf("Sending dump message:\n"); 17 print_sadb_msg (&msg, sizeof (msg)); // write发送 18 Write(s, &msg, sizeof (msg)); 19 printf("\nMessages returned:\n"); 20 /* Read and print SADB_DUMP replies until done */ 21 goteof = 0; 22 while (goteof == 0) { 23 int msglen; 24 struct sadb_msg *msgp; // read读 25 msglen = Read(s, &buf, sizeof (buf)); 26 msgp = (struct sadb_msg *) &buf; 27 print_sadb_msg(msgp, msglen); // 注意判断消息结束的方法 28 if (msgp->sadb_msg_seq == 0) 29 goteof = 1; 30 } 31 close(s); 32 } 建立SA: 建立SA分两类, 一种是静态SA, 一般建立后就不变了; 一种是动态SA, SA有一定寿命, 需要周期性的更 新密钥。前者一般用在手工建立的IPSEC连接,一般只是调试时使用,后者用于自动密钥协商,是常用 的情况。 为建立一个静态SA,需要发送的消息除了消息头外,还必须要有三个扩展数据部分:SA、地址和密钥; 可选的还可有生命期(lifetime)、身份(identity)和敏感性(sensitivity)。 SA结构: struct sadb_sa { u_int16_t sadb_sa_len; /* length of extension / 8 */ u_int16_t sadb_sa_exttype; /* SADB_EXT_SA */ u_int32_t sadb_sa_spi; /* Security Parameters Index (SPI) */ u_int8_t sadb_sa_replay; /* replay window size, or zero */ u_int8_t sadb_sa_state; /* SA state, see Figure 19.7 */ u_int8_t sadb_sa_auth; /* authentication algorithm, see Figure 19.8 */ u_int8_t sadb_sa_encrypt; /* encryption algorithm, see Figure 19.8 */ u_int32_t sadb_sa_flags; /* bitmask of flags */ }; 地址结构,该结构后面跟相关地址族的sockaddr结构(sockaddr_in, sockaddr_in6等): struct sadb_address { u_int16_t sadb_address_len; /* length of extension + address / 8 */ u_int16_t sadb_address_exttype; /* SADB_EXT_ADDRESS_{SRC,DST,PROXY} */ u_int8_t sadb_address_proto; /* IP protocol, or 0 for all */ u_int8_t sadb_address_prefixlen; /* # significant bits in address */ u_int16_t sadb_address_reserved; /* reserved for extension */ }; 密钥结构, 密钥跟在该结构后面: struct sadb_key { u_int16_t sadb_key_len; /* length of extension + key / 8 */ u_int16_t sadb_key_exttype; /* SADB_EXT_KEY_{AUTH, ENCRYPT} */ u_int16_t sadb_key_bits; /* # bits in key */ u_int16_t sadb_key_reserved; /* reserved for extension */ }; 要写程序实现建立SA过程,就是在一大块缓冲区中依次填入消息头结构、SA结构、相关地址信息、密钥 结构、密钥,然后发到套接口,然后接收数据,接收时要注意判断消息的进程号和类型是否和自己的相 符,相符了才是发给自己的,因为内核会向所有打开了PF_KEY套接口的进程发送消息。 对于动态SA,一般用户空间都是一个daemon来定时维护,一开始并没有设置算法密钥,需要协商决定,这 时daemon需要知道内核中支持了哪些算法, 因此这个daemon需要向内核登记注册自身,指出能处理的SA 类型,然后内核回应所支持的加密和认证算法的类型,daemon通过IKE协商出SA后将SA信息发送到内核,此 时一般会带生命期, SA到期后会从SADB中删除, 需要重新协商新的SA. 支持结构: struct sadb_supported { u_int16_t sadb_supported_len; /* length of extension + algorithms / 8 */ u_int16_t sadb_supported_exttype; /* SADB_EXT_SUPPORTED_{AUTH, ENCRYPT} */ u_int32_t sadb_supported_reserved; /* reserved for future expansion */ }; /* followed by algorithm list */ 算法结构: struct sadb_alg { u_int8_t sadb_alg_id; /* algorithm ID from Figure 19.8 */ u_int8_t sadb_alg_ivlen; /* IV length, or zero */ u_int16_t sadb_alg_minbits; /* minimum key length */ u_int16_t sadb_alg_maxbits; /* maximum key length */ u_int16_t sadb_alg_reserved; /* reserved for future expansion */ }; 后记: UNP中对PF_KEY的介绍太简单了, 以后将分析pluto从中再学习了.
发表评论
-
Linux内核中流量控制(24)
2011-01-10 16:33 2203本文档的Copyleft归yfydz所 ... -
Linux内核中流量控制(23)
2011-01-10 16:30 1484本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(22)
2011-01-10 16:29 1929本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(21)
2011-01-10 16:28 1345本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(20)
2011-01-10 16:27 1515本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(19)
2011-01-10 16:27 1970本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(18)
2011-01-10 16:26 1564Linux内核中流量控制(18) ... -
Linux内核中流量控制(17)
2011-01-10 16:25 1940本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(16)
2011-01-10 16:25 1795本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(15)
2011-01-10 16:24 1880本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(14)
2011-01-10 16:23 1952本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(13)
2011-01-10 16:22 2627本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(12)
2011-01-10 16:21 2100本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(11)
2011-01-10 16:21 3227本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(10)
2011-01-10 16:20 1999本文档的Copyleft归yfydz所 ... -
Linux内核中流量控制(9)
2011-01-10 16:19 1826本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(8)
2011-01-10 16:18 1492本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(7)
2011-01-10 16:18 2918本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(6)
2011-01-10 16:17 1488本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(5)
2011-01-10 16:16 1723本文档的Copyleft归yfydz所有,使用GPL发布,可以 ...
相关推荐
unpv12e_dev UNIX 网络编程,第 1 卷 2e 源
unix网络编程:卷1:套接字联网API,第三版,stevens的杰作,源码,学习网络编程的良师益友
Unix网络编程中unp.h的环境,unpv13e.tar.gz。有些人动不动就20几个积分,像这种开源的资源,也要这么多,真垃圾的很。
unpv13e 并附带了error.c文件,下载下来后,把error.c文件与unp.h和config.h文件一起放到/usr/include/目录下,就防止报err_sys()错误了。
unpv13e UNIX网络编程卷1:通用联网API(第3版)源代码
unpv 网络编程.pdf+源码 linux unix
经典linux网络编程源码
unpv22e-代码
书中源代码作者发布在:www.unpbook.com,https://github.com/unpbook/unpv13e
unix network program .h
配套编译和测试参考:https://editor.csdn.net/md/?articleId=125043113
unpv22e:UNIX网络编程卷(2)源码
preface.unpv22e.pdf
UNIX网络编程卷一第三版源码资源,在Ubuntu1004下可用。资源免编译,下载及用。方法:将两个头文件放入/usr/include文件夹下,将libunp.a放入/usr/lib和/lib文件夹下。编译的时候,加-lunp例如:gcc text.c -lunp。
unpv13e:UNIX网络编程第三版源码