source: trunk/third/ifplugd/src/nlapi.c @ 20388

Revision 20388, 3.3 KB checked in by amb, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20387, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Id: nlapi.c,v 1.1.1.1 2004-04-09 20:08:58 amb Exp $ */
2
3/*
4 * This file is part of ifplugd.
5 *
6 * ifplugd is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * ifplugd is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with ifplugd; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24#include <errno.h>
25#include <assert.h>
26#include <stdlib.h>
27
28#include <libdaemon/dlog.h>
29
30#include "nlapi.h"
31
32int nlapi_fd = -1;
33
34struct callback_info {
35    nlapi_callback_t callback;
36    void *userdata;
37    struct callback_info * next;
38};
39
40struct callback_info *callbacks = NULL;
41
42int nlapi_open(uint32_t groups) {
43    struct sockaddr_nl addr;
44
45    if ((nlapi_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
46        daemon_log(LOG_ERR, "socket(PF_NETLINK): %s\n", strerror(errno));
47        return -1;
48    }
49
50    memset(&addr, 0, sizeof(addr));
51    addr.nl_family = AF_NETLINK;
52    addr.nl_groups = groups;
53    addr.nl_pid = getpid();
54
55    if (bind(nlapi_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
56        close(nlapi_fd);
57        daemon_log(LOG_ERR, "bind(): %s\n", strerror(errno));
58        return -1;
59    }
60
61    return 0;
62}
63
64int nlapi_work(int block) {
65
66    assert(nlapi_fd >= 0);
67   
68    for (;;) {
69        int bytes;
70        char replybuf[1024];
71        struct nlmsghdr *p = (struct nlmsghdr *) replybuf;
72       
73        if ((bytes = recv(nlapi_fd, &replybuf, sizeof(replybuf), block ? 0 : MSG_DONTWAIT)) < 0) {
74
75            if (errno == EAGAIN || errno == EINTR)
76                return 0;
77           
78            daemon_log(LOG_ERR, "NLAPI: recv(): %s\n", strerror(errno));
79            return -1;
80        }
81
82        for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
83            struct callback_info *c;
84           
85            if (!NLMSG_OK(p, bytes) || bytes < sizeof(struct nlmsghdr) || bytes < p->nlmsg_len) {
86                daemon_log(LOG_ERR, "NLAPI: Packet too small or truncated!\n");
87                return -1;
88            }
89           
90            for (c = callbacks; c; c = c->next)
91                if (c->callback(p, c->userdata) < 0)
92                    return -1;
93        }
94
95        if (block)
96            break;
97    }
98
99    return 0;
100}
101
102void nlapi_close(void) {
103    if (nlapi_fd >= 0)
104        close(nlapi_fd);
105    nlapi_fd = -1;
106
107    while (callbacks) {
108        struct callback_info *c = callbacks;
109        callbacks = callbacks->next;
110        free(c);
111    }
112}
113
114int nlapi_register(int (*callback) (struct nlmsghdr *n, void *u), void *u) {
115    struct callback_info *c;
116
117    assert(callback);
118   
119    if (!(c = malloc(sizeof(struct callback_info)))) {
120        daemon_log(LOG_ERR, "NLAPI: Not enough memory.\n");
121        return -1;
122    }
123
124    c->callback = callback;
125    c->userdata = u;
126
127    c->next = callbacks;
128    callbacks = c;
129    return 0;
130}
Note: See TracBrowser for help on using the repository browser.