????1. ???? Netlink
????????Netlink??Netlink??linux?????????????????????????????????????????Netlink?????????????????????????????????????????????????????????????????????????????????Netlink????????????Netlink??????????
???????Netlink??????????????????????????????????????????/proc??ioctl??Netlink?????????????????????Netlink??????????????
????NetlinkЭ?????BSD socket??AF_NETLINK?????(address family)?????32λ???????(???????PID)?????NetlinkЭ??(??????????man??????????netlink family)?????????????????????/????????????NETLINK_ROUTE????????????·??????·?????NETLINK_KOBJECT_UEVENT????????????????udev????????????netlink???????????
?????? ??????????????(??????????)
?????? ??????????????BSD socket???(??netlink????????ε?Э????????????????????????libnl?????????)
?????? ?????????????????API???
?????? ????(??????“????”?????????????????)
?????? ???????????????????????ж???????
?????????Netlink??????ú???????Netlink??UDP socket??????????????????????????AF_NETLINK??AF_INET??????????Э???壬??NETLINK_ROUTE??NETLINK_GENERIC??Щ??Э?飬?????UDP??
?????????????????Netlink??UDP socket??????????????????????????UDP socket??????????????????蹹??UDP??????????????Э??????????????????sockaddr_in?????????????????Netlink?????????????????????????????????????????????????
??????????????Netlink?????????Э?飬??????????????????????NETLINK_GENERIC????????linux/netlink.h?У?????????????????????Э?飬?????????????????????????????????????NETLINK_TEST???????????Э??д????????????????Э?鯔??????????linux/netlink.h?У????????????????????????????У?????????????UDP?????????????????sendto??sendmsg?????Netlink????????????????????????sendmsg??????
????2. ?????????
???????????????????????????????

????2.1 struct msghdr
????msghdr???????socket????л????????????Netlink??е?????????????????????????θ????????????????????????socket?????????????????????????recv??send??readv??writev??recvfrom??sendto?????????recvmsg??sendmsg???????????????и???????????recvmsg??sendmsg??????????????????й????????????????????????msghdr???????????????????recvfrom??sendto???????м????????msg_iov??msg_iovlen???????????readv??writev???????????msg_flags???????????recv??send??flag????????μ?msg_control??msg_controllen????????recvmsg??sendmsg???е?????
????2.2 Struct sockaddr_ln
????Struct sockaddr_ln?Netlink???????????????socket????е?sockaddr_in???????????????????????

????struct sockaddr_nl{}?????????????????£?
????struct sockaddr_nl
????{
????sa_family_t nl_family; /*??????????AF_NETLINK */
????unsigned short nl_pad; /* ??δ?????????0*/
????__u32 nl_pid; /* process pid */
????__u32 nl_groups; /* multicast groups mask */
????};
????(1) nl_pid????Netlink?淶??PID?????Port-ID(32bits)???????????????????????????netlink??socket?????????????nl_pid?????????????????????????????????Netlink??????????????-???????????????????????????????????????????????????????????????0?????????
????(2) nl_groups????????????????????????????飬????????bind()?????á?????????????????????????????????(???????????????????????????????)???????????0???????????????????κζ??顣?????????????NetlinkЭ?????Э?飬??????32??????(???nl_groups??????32????)?????????????????????????
????2.3 struct nlmsghdr
????Netlink?????????????????幹???struct nlmsghdr?????????????????????????????nlmsghdr?????
????struct nlmsghdr
????{
????__u32 nlmsg_len; /* Length of message including header */
????__u16 nlmsg_type; /* Message content */
????__u16 nlmsg_flags; /* Additional flags */
????__u32 nlmsg_seq; /* Sequence number */
????__u32 nlmsg_pid; /* Sending process PID */
????};
?????????и??????????????????
????(1) nlmsg_len?????????????????????????????Netlink?????????
????(2) nlmsg_type?????????????????????????????????(???汾2.6.21)Netlink?????????????????????????£?
????a) NLMSG_NOOP-????????????????
????b) NLMSG_ERROR-?????????а??????????
????c) NLMSG_DONE-?????????Netlink???з??????????????????е???????????????NLMSG_DONE???????????????nlmsg_flags???????????NLM_F_MULTIλ??Ч??
????d) NLMSG_OVERRUN-?????????
????(3) nlmsg_flags???????????????????????????????????NLM_F_MULTI??
????????????????????????????NLMSG_DATA????????????????
????3. ?????????
?????????1
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/socket.h>
#include <errno.h>
#define MAX_PAYLOAD 1024 // maximum payload size
#define NETLINK_TEST 25 //??????Э??
int main(int argc?? char* argv[])
{
int state;
struct sockaddr_nl src_addr?? dest_addr;
struct nlmsghdr *nlh = NULL; //Netlink??????
struct iovec iov;
struct msghdr msg;
int sock_fd?? retval;
int state_smg = 0;
// Create a socket
sock_fd = socket(AF_NETLINK?? SOCK_RAW?? NETLINK_TEST);
if(sock_fd == -1){
printf("error getting socket: %s"?? strerror(errno));
return -1;
}
// To prepare binding
memset(&src_addr?? 0?? sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = 100; //A????????????
src_addr.nl_groups = 0;
//Bind
retval = bind(sock_fd?? (struct sockaddr*)&src_addr?? sizeof(src_addr));
if(retval < 0){
printf("bind failed: %s"?? strerror(errno));
close(sock_fd);
return -1;
}
// To orepare create mssage
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
if(!nlh){
printf("malloc nlmsghdr error! ");
close(sock_fd);
return -1;
}
memset(&dest_addr??0??sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; //B????????????
dest_addr.nl_groups = 0;
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 100; //C??????????
nlh->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nlh)??"Hello you!"); //?????????
iov.iov_base = (void *)nlh;
iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);
//Create mssage
memset(&msg?? 0?? sizeof(msg));
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
//send message
printf("state_smg ");
state_smg = sendmsg(sock_fd??&msg??0);
if(state_smg == -1)
{
printf("get error sendmsg = %s "??strerror(errno));
}
memset(nlh??0??NLMSG_SPACE(MAX_PAYLOAD));
//receive message
printf("waiting received! ");
while(1){
printf("In while recvmsg ");
state = recvmsg(sock_fd?? &msg?? 0);
if(state<0)
{
printf("state<1");
}
printf("Received message: %s "??(char *) NLMSG_DATA(nlh));
}
close(sock_fd);
return 0;
}
???????????????????????????????“Hello you”???????????????????????????????????????????????????????????о???????????????????????UDP?????sendmsg???÷???????struct msghdr?????????????????????????????????UDP???????????????
????1. socket??????????UDP?sockaddr_in??Netlink?struct sockaddr_nl??
????2. ??UDP????????????Netlink?????????????struct nlmsghdr??????????
??????????????е?A??B??C?????????????pid????????????????pid???????????°????????????????pid???????????????????塣?????pid?????pid??????????????????UDP??port??????UDP???port??ip???????????????????NETLINK_TESTЭ?饗???Netlink??????????Э?飩?????pid???????????????????????y???pid?????????????????????????pid????NETLINK_TESTЭ?????????????????Netlink??Э?????????????TCP??80????UDP??80??????
?????????????????????pid????????????????A??Bλ???????????????????sockaddr_nl??????е?????????????????????????????????????????????B??????pid?0??0?????????????????????????pid?????????????????0????????pid??????????????????????????????????Щ??????????????????????????C??????????????????pid?????????????????????????????UDP???????????????????????????????????????????????????д???????????????pid???????????????????????????????????????????????????????????????????????????pid???????
???????????pid?????ù???????A??????????????÷?????????????????????????????????????????У??????????????????????????????????????????????????“?????”????У????????д?????д?????????100??????????????????100???????????????????????????????????????????????????A????????????????????????????????????????????????????????pid?????0??B??????????????????pid?0???????????????????????????101?????????????????????recvmsg???????B????pid?????101???????????????????????????????????Netlink???н????????C?????????????д?????????????????????ú????????????A???????????????????????????????????????????????????????????????д??????????????pid??????101???????????????м????????????????????д?????飬??д????д?????????????????????????……