本文整理汇总了C++中NLMSG_OK函数的典型用法代码示例。如果您正苦于以下问题:C++ NLMSG_OK函数的具体用法?C++ NLMSG_OK怎么用?C++ NLMSG_OK使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NLMSG_OK函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: nlmsg_receive
static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *),
int (*err_cb)(int, void *), void *arg)
{
struct nlmsghdr *hdr;
for (hdr = (struct nlmsghdr *)buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
if (hdr->nlmsg_seq != CR_NLMSG_SEQ)
continue;
if (hdr->nlmsg_type == NLMSG_DONE) {
int *len = (int *)NLMSG_DATA(hdr);
if (*len < 0) {
pr_err("ERROR %d reported by netlink (%s)\n",
*len, strerror(-*len));
return *len;
}
return 0;
}
if (hdr->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(hdr);
if (hdr->nlmsg_len - sizeof(*hdr) < sizeof(struct nlmsgerr)) {
pr_err("ERROR truncated\n");
return -1;
}
if (err->error == 0)
return 0;
return err_cb(err->error, arg);
}
if (cb(hdr, arg))
return -1;
}
return 1;
}
示例2: readNlSock
int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId){
struct nlmsghdr *nlHdr;
int readLen = 0, msgLen = 0;
do{
/* Recieve response from the kernel */
if((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0){
perror("SOCK READ: ");
return -1;
}
nlHdr = (struct nlmsghdr *)bufPtr;
/* Check if the header is valid */
if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR))
{
perror("Error in recieved packet");
return -1;
}
/* Check if the its the last message */
if(nlHdr->nlmsg_type == NLMSG_DONE) {
break;
}
else{
/* Else move the pointer to buffer appropriately */
bufPtr += readLen;
msgLen += readLen;
}
/* Check if its a multi part message */
if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) {
/* return if its not */
break;
}
} while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
return msgLen;
}
示例3: memset
static struct nlmsghdr *get_msg(void)
{
struct nlmsghdr *nlh;
int len;
nlh = (struct nlmsghdr *)malloc(MAX_MSG_SIZE);
if (NULL==nlh)
return NULL;
memset(nlh, 0, MAX_MSG_SIZE);
len = recv(nl_sd, (void *)nlh, MAX_MSG_SIZE, 0);
if (len < 0) {
printf("RECEIVE FAILED with %d", errno);
free(nlh);
return NULL;
}
if (!(NLMSG_OK(nlh, (unsigned int)len))) {
printf("RECEIVE FAILED, message too long\n");
free(nlh);
return NULL;
}
if (nlh->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA(nlh);
printf("RECEIVE FAILED with msg error %i (pid %d): %s\n",
err->error, nlh->nlmsg_pid, strerror(err->error * -1));
if (hexdump && len > 0)
hexprint((char *)nlh, len);
free(nlh);
return NULL;
}
if (hexdump) {
printf("RECEIVED A MESSAGE: %d\n", len);
hexprint((char *)nlh, nlh->nlmsg_len);
}
return nlh;
}
示例4: netlink_multicast
void netlink_multicast(void)
{
ssize_t len;
struct nlmsghdr *h;
int flags;
/* don't risk blocking reading netlink messages here. */
if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
return;
if ((len = netlink_recv()) != -1)
{
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
if (h->nlmsg_type == NLMSG_ERROR)
nl_err(h);
else
nl_routechange(h);
}
/* restore non-blocking status */
fcntl(daemon->netlinkfd, F_SETFL, flags);
}
示例5: parse_netlink_msg
/*
* parse_netlink_msg
*/
void
parse_netlink_msg (char *buf, size_t buf_len)
{
netlink_msg_ctx_t ctx_space, *ctx;
struct nlmsghdr *hdr;
int status;
int len;
ctx = &ctx_space;
hdr = (struct nlmsghdr *) buf;
len = buf_len;
for (; NLMSG_OK (hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
netlink_msg_ctx_init(ctx);
ctx->hdr = (struct nlmsghdr *) buf;
switch (hdr->nlmsg_type) {
case RTM_DELROUTE:
case RTM_NEWROUTE:
parse_route_msg(ctx);
if (ctx->err_msg) {
err_msg("Error parsing route message: %s", ctx->err_msg);
}
print_netlink_msg_ctx(ctx);
break;
default:
trace(1, "Ignoring unknown netlink message - Type: %d", hdr->nlmsg_type);
}
netlink_msg_ctx_cleanup(ctx);
}
}
示例6: adapterChangeObserverThread
void adapterChangeObserverThread(void* aPtr)
{
InterfaceChangedObserver* observer = (InterfaceChangedObserver*) aPtr;
OsNetworkHandle *handle = observer->netHnd;
char buffer[4096];
struct nlmsghdr *nlh;
int32_t len, ret;
fd_set rfds,errfds;
while (1) {
if (SocketInterrupted(handle)) {
return;
}
FD_ZERO(&rfds);
FD_SET(handle->iPipe[0], &rfds);
FD_SET(handle->iSocket, &rfds);
FD_ZERO(&errfds);
FD_SET(handle->iSocket, &errfds);
ret = TEMP_FAILURE_RETRY_2(select(nfds(handle), &rfds, NULL, &errfds, NULL), handle);
if ((ret > 0) && FD_ISSET(handle->iSocket, &rfds)) {
nlh = (struct nlmsghdr *) buffer;
if ((len = recv(handle->iSocket, nlh, 4096, 0)) > 0) {
while (NLMSG_OK(nlh, len) && (nlh->nlmsg_type != NLMSG_DONE)) {
if (nlh->nlmsg_type == RTM_NEWADDR ||
nlh->nlmsg_type == RTM_DELADDR ||
nlh->nlmsg_type == RTM_NEWLINK) {
observer->iCallback(observer->iArg);
}
nlh = NLMSG_NEXT(nlh, len);
}
}
}
}
}
示例7: interpret
static int interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
break;
}
if(l_hdr->nlmsg_type == RTM_NEWLINK)
{
if (interpretLink(l_hdr, p_links, p_resultList) == -1)
{
return -1;
}
}
else if(l_hdr->nlmsg_type == RTM_NEWADDR)
{
if (interpretAddr(l_hdr, p_links, p_resultList) == -1)
{
return -1;
}
}
}
}
return 0;
}
示例8: nfnl_process
/**
* nfnl_process - process data coming from a nfnetlink system
* @h: nfnetlink handler
* @buf: buffer that contains the netlink message
* @len: size of the data contained in the buffer (not the buffer size)
*
* This function processes all the nfnetlink messages contained inside a
* buffer. It performs the appropiate sanity checks and passes the message
* to a certain handler that is registered via register_callback().
*
* On success, NFNL_CB_STOP is returned if the data processing has finished.
* If a value NFNL_CB_CONTINUE is returned, then there is more data to
* process. On error, NFNL_CB_CONTINUE is returned and errno is set to the
* appropiate value.
*
* In case that the callback returns NFNL_CB_FAILURE, errno may be set by
* the library client. If your callback decides not to process data anymore
* for any reason, then it must return NFNL_CB_STOP. Otherwise, if the
* callback continues the processing NFNL_CB_CONTINUE is returned.
*/
int nfnl_process(struct nfnl_handle *h, const unsigned char *buf, size_t len)
{
int ret = 0;
struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
assert(h);
assert(buf);
assert(len > 0);
/* check for out of sequence message */
if (nlh->nlmsg_seq && nlh->nlmsg_seq != h->seq) {
errno = EILSEQ;
return -1;
}
while (len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) {
ret = nfnl_step(h, nlh);
if (ret <= NFNL_CB_STOP)
break;
nlh = NLMSG_NEXT(nlh, len);
}
return ret;
}
示例9: ifup_scan_event
void ifup_scan_event(struct nlmsghdr *nh, int len, int *seen_flags) {
struct ifinfomsg *ifi;
for (;NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
switch (nh->nlmsg_type) {
case NLMSG_DONE:
return;
case NLMSG_ERROR:
return;
case RTM_NEWLINK:
ifi = NLMSG_DATA(nh);
if (ifi->ifi_flags & IFF_RUNNING) {
*seen_flags |= SEEN_RUNNING;
}
break;
case RTM_NEWADDR:
*seen_flags |= SEEN_ADDRESS;
break;
}
}
}
示例10: netlink_new_msg
static void
netlink_new_msg(struct uloop_fd *ufd, unsigned events)
{
struct nlmsghdr *nlh;
char buffer[BUFSIZ];
int msg_size;
memset(&buffer, 0, sizeof(buffer));
nlh = (struct nlmsghdr *)buffer;
if ((msg_size = recv(ufd->fd, nlh, BUFSIZ, 0)) == -1) {
DD("error receiving netlink message");
return;
}
while (msg_size > sizeof(*nlh)) {
int len = nlh->nlmsg_len;
int req_len = len - sizeof(*nlh);
if (req_len < 0 || len > msg_size) {
DD("error reading netlink message");
return;
}
if (!NLMSG_OK(nlh, msg_size)) {
DD("netlink message is not NLMSG_OK");
return;
}
if (nlh->nlmsg_type == RTM_NEWADDR)
easycwmp_netlink_interface(nlh);
msg_size -= NLMSG_ALIGN(len);
nlh = (struct nlmsghdr*)((char*)nlh + NLMSG_ALIGN(len));
}
}
示例11: get_netlink
static int
get_netlink(int fd, int flags,
int (*callback)(struct nlmsghdr *, const char *),
const char *ifname)
{
char *buffer = NULL;
ssize_t bytes;
struct nlmsghdr *nlm;
int r = -1;
buffer = xzalloc(sizeof(char) * BUFFERLEN);
for (;;) {
bytes = recv(fd, buffer, BUFFERLEN, flags);
if (bytes == -1) {
if (errno == EAGAIN) {
r = 0;
goto eexit;
}
if (errno == EINTR)
continue;
goto eexit;
}
for (nlm = (struct nlmsghdr *)buffer;
NLMSG_OK(nlm, (size_t)bytes);
nlm = NLMSG_NEXT(nlm, bytes))
{
r = callback(nlm, ifname);
if (r != 0)
goto eexit;
}
}
eexit:
free(buffer);
return r;
}
示例12: nl_send
int nl_send(struct nl_handle *hnd, struct iovec *iov, int iovlen)
{
struct sockaddr_nl sa = {
.nl_family = AF_NETLINK,
};
struct msghdr msg = {
.msg_name = &sa,
.msg_namelen = sizeof(sa),
.msg_iov = iov,
.msg_iovlen = iovlen,
};
struct nlmsghdr *src = iov->iov_base;
src->nlmsg_seq = ++hnd->seq;
if (sendmsg(hnd->fd, &msg, 0) < 0)
return errno;
return 0;
}
int nl_recv(struct nl_handle *hnd, struct nlmsg_entry **dest, int is_dump)
{
struct sockaddr_nl sa = {
.nl_family = AF_NETLINK,
};
struct iovec iov;
struct msghdr msg = {
.msg_name = &sa,
.msg_namelen = sizeof(sa),
.msg_iov = &iov,
.msg_iovlen = 1,
};
char buf[16384];
int len, err;
struct nlmsghdr *n;
struct nlmsg_entry *ptr = NULL; /* GCC false positive */
struct nlmsg_entry *entry;
*dest = NULL;
while (1) {
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
len = recvmsg(hnd->fd, &msg, 0);
if (len < 0)
return errno;
if (!len)
return EPIPE;
if (sa.nl_pid) {
/* not from the kernel */
continue;
}
for (n = (struct nlmsghdr *)buf; NLMSG_OK(n, len); n = NLMSG_NEXT(n, len)) {
if (n->nlmsg_pid != hnd->pid || n->nlmsg_seq != hnd->seq)
continue;
if (is_dump && n->nlmsg_type == NLMSG_DONE)
return 0;
if (n->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *nlerr = (struct nlmsgerr *)NLMSG_DATA(n);
err = -nlerr->error;
goto err_out;
}
entry = malloc(n->nlmsg_len + sizeof(void *));
if (!entry) {
err = ENOMEM;
goto err_out;
}
entry->next = NULL;
memcpy(&entry->h, n, n->nlmsg_len);
if (!*dest)
*dest = entry;
else
ptr->next = entry;
ptr = entry;
if (!is_dump)
return 0;
}
}
err_out:
nlmsg_free(*dest);
*dest = NULL;
return err;
}
int nl_exchange(struct nl_handle *hnd,
struct nlmsghdr *src, struct nlmsg_entry **dest)
{
struct iovec iov = {
.iov_base = src,
.iov_len = src->nlmsg_len,
};
int is_dump;
int err;
is_dump = !!(src->nlmsg_flags & NLM_F_DUMP);
err = nl_send(hnd, &iov, 1);
if (err)
return err;
return nl_recv(hnd, dest, is_dump);
}
//.........这里部分代码省略.........
示例13: send_to
//send data to command socket and wait - blocking - for a reply (an error message or a data dump)
int KernelNetlinkProtocol::send_and_parse(const std::string& data)
{
int ret = send_to(cmd_sock_, data, cmd_tx_buff_size_, reinterpret_cast<sockaddr*>(&cmd_peer_addr_));
if (ret <= 0)
{
tnt::Log::warning("KernelNetlinkProtocol::send_and_parse: send_to returned ", ret);
return ret;
}
//tnt::Log::info(colors::green, "\n==> KernelNetlinkProtocol sent new data (", ret, " bytes) to socket ", cmd_sock_);
static std::vector<std::string> messages;
static uint16_t multi_type;
int error = 5;
bool all = false;
int dim = 0;
while (!all)
{
dim = recv(cmd_sock_, cmd_rx_buffer_.data(), cmd_rx_buffer_.size(), 0);
// sanity checks
if (dim <= 0)
{
if (dim < -1)
{
tnt::Log::error("KernelNetlinkProtocol::send_and_parse: recv returned ", dim);
}
return dim;
}
//tnt::Log::info(colors::blue, "\n==> received new data from socket ", cmd_sock_, " (command socket)");
std::string raw_input(cmd_rx_buffer_.data(), dim);
size_t len = raw_input.size();
size_t pos = 0;
for (const nlmsghdr* nlh = reinterpret_cast<const nlmsghdr*>(raw_input.data()); NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len))
{
if (netlink_debug) print_nlmsghdr_info(nlh);
pos += nlh->nlmsg_len;
//tnt::Log::info(raw_input.size() - pos, " of ", raw_input.size()," bytes left");
if (nlh->nlmsg_flags & NLM_F_MULTI) // Multipart message
{
if (nlh->nlmsg_type == NLMSG_DONE) // Multipart message ended, we can start parsing all the previous messages all together
{
//tnt::Log::info(colors::green, "\n----> multipart ended, now parsing");
switch (multi_type)
{
case RTM_NEWLINK:
tnt::Application::raise(event::PortList(parse_multi<std::shared_ptr<NetworkPort>>(messages, link_parser)), this);
break;
case RTM_NEWADDR:
tnt::Application::raise(event::AddressList(parse_multi<AddressInfo>(messages, address_parser)), this);
break;
case RTM_NEWROUTE:
tnt::Application::raise(event::RouteList(parse_multi<RouteInfo>(messages, route_parser)), this);
break;
default:
break;
}
messages.clear();
error = 0;
}
else
{
multi_type = nlh->nlmsg_type;
messages.push_back(raw_input.substr(pos - nlh->nlmsg_len, pos));
continue; // do not parse yet, thus continue;
}
}
else // single message
{
//tnt::Log::info(colors::green, "\n----> single message, now parsing");
if (nlh->nlmsg_type == NLMSG_ERROR)
{
nlmsgerr* nl_err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(nlh));
if (nl_err->error)
{
tnt::Log::warning("error message, code: ", nl_err->error, "\tin reply to message ", type2string(nl_err->msg.nlmsg_type), ", sequence ", nl_err->msg.nlmsg_seq);
}
else
{
//tnt::Log::info("ACK message\tin reply to message ", type2string(nl_err->msg.nlmsg_type), ", sequence ", nl_err->msg.nlmsg_seq);
//.........这里部分代码省略.........
示例14: main
int main(int argc, char **argv) {
int opt, longidx, nlsock, rc;
struct sockaddr_nl nladdr = {AF_NETLINK};
socklen_t nlalen;
pid_t mypid;
ssize_t bcount;
char *called;
void *rcvbuf;
/* Isolate the base name of the program as invoked. */
called = strrchr(argv[0], '/');
if (!called)
called = argv[0];
/* Parse the given options, looking for the filtering mode. */
while ((opt = getopt_long(argc, argv, my_short_opts, my_long_opts, &longidx)) != -1) {
switch (opt) {
case 'e':
execflag = 1;
break;
case 'f':
forkflag = 1;
break;
case 't':
threadflag = 1;
break;
default:
if (opt != 'h')
fprintf(stderr, "%s: Invalid option '%c' !\n", called, opt);
usage(called);
}
}
/* If no filtering mode, bail out. */
if (!(execflag || forkflag)) {
fprintf(stderr, "%s: Missing required mode option!\n", called);
usage(called);
}
/* Create the netlink socket */
nlsock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_CONNECTOR);
if (nlsock == -1) {
perror("Unable to open a netlink socket!");
exit(1);
}
/* Attach to the process connector group */
{
nladdr.nl_pid = mypid = getpid();
nladdr.nl_groups = CN_IDX_PROC;
if (bind(nlsock, (struct sockaddr *)&nladdr, sizeof(nladdr))) {
perror("Unable to bind to the process connector!");
exit(1);
}
}
/* Request the process messages */
{
enum proc_cn_mcast_op cnop = PROC_CN_MCAST_LISTEN;
struct cn_msg cnmsg = {{CN_IDX_PROC, CN_VAL_PROC}, 0, 0, sizeof(cnop), 0};
struct nlmsghdr nlmsg = {NLMSG_LENGTH(sizeof cnmsg + sizeof cnop), NLMSG_DONE};
char padding[16];
struct iovec iov[4] = {
{&nlmsg, sizeof(nlmsg)},
{padding, NLMSG_LENGTH(0) - sizeof(nlmsg)},
{&cnmsg, sizeof(cnmsg)},
{&cnop, sizeof(cnop)}
};
nlmsg.nlmsg_pid = mypid;
if ((bcount = writev(nlsock, iov, 4)) == -1) {
perror("Unable to listen to the process connector!");
exit(1);
}
}
/* Receive messages forever ... */
rcvbuf = malloc(4096+CONNECTOR_MAX_MSG_SIZE);
if (!rcvbuf) {
perror("Unable to allocate a receive buffer!");
exit(1);
}
setbuf(stdout, NULL);
while (1) {
nlalen = sizeof(nladdr);
bcount = recvfrom(nlsock, rcvbuf, 4096+CONNECTOR_MAX_MSG_SIZE,
0, (struct sockaddr *)&nladdr, &nlalen);
if (nladdr.nl_pid == 0) {
struct nlmsghdr *hdr = rcvbuf;
for (hdr=rcvbuf; NLMSG_OK(hdr, bcount); hdr=NLMSG_NEXT(hdr, bcount))
dispatch_nl(hdr);
}
}
}
示例15: getifaddrs
/* ====================================================================== */
int getifaddrs(struct ifaddrs **ifap)
{
int sd;
struct nlmsg_list *nlmsg_list, *nlmsg_end, *nlm;
/* - - - - - - - - - - - - - - - */
int icnt;
size_t dlen, xlen, nlen;
uint32_t max_ifindex = 0;
pid_t pid = getpid();
int seq;
int result;
int build ; /* 0 or 1 */
/* ---------------------------------- */
/* initialize */
icnt = dlen = xlen = nlen = 0;
nlmsg_list = nlmsg_end = NULL;
if (ifap)
*ifap = NULL;
/* ---------------------------------- */
/* open socket and bind */
sd = nl_open();
if (sd < 0)
return -1;
/* ---------------------------------- */
/* gather info */
if ((seq = nl_getlist(sd, 0, RTM_GETLINK,
&nlmsg_list, &nlmsg_end)) < 0){
free_nlmsglist(nlmsg_list);
nl_close(sd);
return -1;
}
if ((seq = nl_getlist(sd, seq+1, RTM_GETADDR,
&nlmsg_list, &nlmsg_end)) < 0){
free_nlmsglist(nlmsg_list);
nl_close(sd);
return -1;
}
/* ---------------------------------- */
/* Estimate size of result buffer and fill it */
for (build=0; build<=1; build++){
struct ifaddrs *ifl = NULL, *ifa = NULL;
struct nlmsghdr *nlh, *nlh0;
void *data = NULL, *xdata = NULL, *ifdata = NULL;
char *ifname = NULL, **iflist = NULL;
uint16_t *ifflist = NULL;
struct rtmaddr_ifamap ifamap;
if (build){
ifa = data = calloc(1,
NLMSG_ALIGN(sizeof(struct ifaddrs[icnt]))
+ dlen + xlen + nlen);
ifdata = calloc(1,
NLMSG_ALIGN(sizeof(char *[max_ifindex+1]))
+ NLMSG_ALIGN(sizeof(uint16_t [max_ifindex+1])));
if (ifap != NULL)
*ifap = (ifdata != NULL) ? ifa : NULL;
else{
free_data(data, ifdata);
result = 0;
break;
}
if (data == NULL || ifdata == NULL){
free_data(data, ifdata);
result = -1;
break;
}
ifl = NULL;
data += NLMSG_ALIGN(sizeof(struct ifaddrs)) * icnt;
xdata = data + dlen;
ifname = xdata + xlen;
iflist = ifdata;
ifflist = ((void *)iflist) + NLMSG_ALIGN(sizeof(char *[max_ifindex+1]));
}
for (nlm=nlmsg_list; nlm; nlm=nlm->nlm_next){
int nlmlen = nlm->size;
if (!(nlh0 = nlm->nlh))
continue;
for (nlh = nlh0;
NLMSG_OK(nlh, nlmlen);
nlh=NLMSG_NEXT(nlh,nlmlen)){
struct ifinfomsg *ifim = NULL;
struct ifaddrmsg *ifam = NULL;
struct rtattr *rta;
size_t nlm_struct_size = 0;
sa_family_t nlm_family = 0;
uint32_t nlm_scope = 0, nlm_index = 0;
#ifndef IFA_NETMASK
size_t sockaddr_size = 0;
uint32_t nlm_prefixlen = 0;
#endif
size_t rtasize;
//.........这里部分代码省略.........