chiark / gitweb /
build-sys: support build-from-git without gobject-introspection
[elogind.git] / src / libudev / libudev-monitor.c
1 /*
2  * libudev - interface to udev device information
3  *
4  * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stddef.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <string.h>
18 #include <dirent.h>
19 #include <sys/poll.h>
20 #include <sys/stat.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <arpa/inet.h>
24 #include <linux/netlink.h>
25 #include <linux/filter.h>
26
27 #include "libudev.h"
28 #include "libudev-private.h"
29 #include "socket-util.h"
30
31 /**
32  * SECTION:libudev-monitor
33  * @short_description: device event source
34  *
35  * Connects to a device event source.
36  */
37
38 /**
39  * udev_monitor:
40  *
41  * Opaque object handling an event source.
42  */
43 struct udev_monitor {
44         struct udev *udev;
45         int refcount;
46         int sock;
47         union sockaddr_union snl;
48         union sockaddr_union snl_trusted_sender;
49         union sockaddr_union snl_destination;
50         socklen_t addrlen;
51         struct udev_list filter_subsystem_list;
52         struct udev_list filter_tag_list;
53         bool bound;
54 };
55
56 enum udev_monitor_netlink_group {
57         UDEV_MONITOR_NONE,
58         UDEV_MONITOR_KERNEL,
59         UDEV_MONITOR_UDEV,
60 };
61
62 #define UDEV_MONITOR_MAGIC                0xfeedcafe
63 struct udev_monitor_netlink_header {
64         /* "libudev" prefix to distinguish libudev and kernel messages */
65         char prefix[8];
66         /*
67          * magic to protect against daemon <-> library message format mismatch
68          * used in the kernel from socket filter rules; needs to be stored in network order
69          */
70         unsigned int magic;
71         /* total length of header structure known to the sender */
72         unsigned int header_size;
73         /* properties string buffer */
74         unsigned int properties_off;
75         unsigned int properties_len;
76         /*
77          * hashes of primary device properties strings, to let libudev subscribers
78          * use in-kernel socket filters; values need to be stored in network order
79          */
80         unsigned int filter_subsystem_hash;
81         unsigned int filter_devtype_hash;
82         unsigned int filter_tag_bloom_hi;
83         unsigned int filter_tag_bloom_lo;
84 };
85
86 static struct udev_monitor *udev_monitor_new(struct udev *udev)
87 {
88         struct udev_monitor *udev_monitor;
89
90         udev_monitor = calloc(1, sizeof(struct udev_monitor));
91         if (udev_monitor == NULL)
92                 return NULL;
93         udev_monitor->refcount = 1;
94         udev_monitor->udev = udev;
95         udev_list_init(udev, &udev_monitor->filter_subsystem_list, false);
96         udev_list_init(udev, &udev_monitor->filter_tag_list, true);
97         return udev_monitor;
98 }
99
100 /**
101  * udev_monitor_new_from_socket:
102  * @udev: udev library context
103  * @socket_path: unix socket path
104  *
105  * This function is removed from libudev and will not do anything.
106  *
107  * Returns: #NULL
108  **/
109 struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path);
110 _public_ struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path)
111 {
112         udev_err(udev, "udev_monitor_new_from_socket() does not do anything; please migrate to netlink\n");
113         errno = ENOSYS;
114         return NULL;
115 }
116
117 struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
118 {
119         struct udev_monitor *udev_monitor;
120         unsigned int group;
121
122         if (udev == NULL)
123                 return NULL;
124
125         if (name == NULL)
126                 group = UDEV_MONITOR_NONE;
127         else if (strcmp(name, "udev") == 0)
128                 group = UDEV_MONITOR_UDEV;
129         else if (strcmp(name, "kernel") == 0)
130                 group = UDEV_MONITOR_KERNEL;
131         else
132                 return NULL;
133
134         udev_monitor = udev_monitor_new(udev);
135         if (udev_monitor == NULL)
136                 return NULL;
137
138         if (fd < 0) {
139                 udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
140                 if (udev_monitor->sock == -1) {
141                         udev_err(udev, "error getting socket: %m\n");
142                         free(udev_monitor);
143                         return NULL;
144                 }
145         } else {
146                 udev_monitor->bound = true;
147                 udev_monitor->sock = fd;
148         }
149
150         udev_monitor->snl.nl.nl_family = AF_NETLINK;
151         udev_monitor->snl.nl.nl_groups = group;
152
153         /* default destination for sending */
154         udev_monitor->snl_destination.nl.nl_family = AF_NETLINK;
155         udev_monitor->snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV;
156
157         return udev_monitor;
158 }
159
160 /**
161  * udev_monitor_new_from_netlink:
162  * @udev: udev library context
163  * @name: name of event source
164  *
165  * Create new udev monitor and connect to a specified event
166  * source. Valid sources identifiers are "udev" and "kernel".
167  *
168  * Applications should usually not connect directly to the
169  * "kernel" events, because the devices might not be useable
170  * at that time, before udev has configured them, and created
171  * device nodes. Accessing devices at the same time as udev,
172  * might result in unpredictable behavior. The "udev" events
173  * are sent out after udev has finished its event processing,
174  * all rules have been processed, and needed device nodes are
175  * created.
176  *
177  * The initial refcount is 1, and needs to be decremented to
178  * release the resources of the udev monitor.
179  *
180  * Returns: a new udev monitor, or #NULL, in case of an error
181  **/
182 _public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name)
183 {
184         return udev_monitor_new_from_netlink_fd(udev, name, -1);
185 }
186
187 static inline void bpf_stmt(struct sock_filter *inss, unsigned int *i,
188                             unsigned short code, unsigned int data)
189 {
190         struct sock_filter *ins = &inss[*i];
191
192         ins->code = code;
193         ins->k = data;
194         (*i)++;
195 }
196
197 static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i,
198                            unsigned short code, unsigned int data,
199                            unsigned short jt, unsigned short jf)
200 {
201         struct sock_filter *ins = &inss[*i];
202
203         ins->code = code;
204         ins->jt = jt;
205         ins->jf = jf;
206         ins->k = data;
207         (*i)++;
208 }
209
210 /**
211  * udev_monitor_filter_update:
212  * @udev_monitor: monitor
213  *
214  * Update the installed socket filter. This is only needed,
215  * if the filter was removed or changed.
216  *
217  * Returns: 0 on success, otherwise a negative error value.
218  */
219 _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor)
220 {
221         struct sock_filter ins[512];
222         struct sock_fprog filter;
223         unsigned int i;
224         struct udev_list_entry *list_entry;
225         int err;
226
227         if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL &&
228             udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL)
229                 return 0;
230
231         memset(ins, 0x00, sizeof(ins));
232         i = 0;
233
234         /* load magic in A */
235         bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, magic));
236         /* jump if magic matches */
237         bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, UDEV_MONITOR_MAGIC, 1, 0);
238         /* wrong magic, pass packet */
239         bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
240
241         if (udev_list_get_entry(&udev_monitor->filter_tag_list) != NULL) {
242                 int tag_matches;
243
244                 /* count tag matches, to calculate end of tag match block */
245                 tag_matches = 0;
246                 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list))
247                         tag_matches++;
248
249                 /* add all tags matches */
250                 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) {
251                         uint64_t tag_bloom_bits = util_string_bloom64(udev_list_entry_get_name(list_entry));
252                         uint32_t tag_bloom_hi = tag_bloom_bits >> 32;
253                         uint32_t tag_bloom_lo = tag_bloom_bits & 0xffffffff;
254
255                         /* load device bloom bits in A */
256                         bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_hi));
257                         /* clear bits (tag bits & bloom bits) */
258                         bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_hi);
259                         /* jump to next tag if it does not match */
260                         bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_hi, 0, 3);
261
262                         /* load device bloom bits in A */
263                         bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_tag_bloom_lo));
264                         /* clear bits (tag bits & bloom bits) */
265                         bpf_stmt(ins, &i, BPF_ALU|BPF_AND|BPF_K, tag_bloom_lo);
266                         /* jump behind end of tag match block if tag matches */
267                         tag_matches--;
268                         bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, tag_bloom_lo, 1 + (tag_matches * 6), 0);
269                 }
270
271                 /* nothing matched, drop packet */
272                 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
273         }
274
275         /* add all subsystem matches */
276         if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) != NULL) {
277                 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) {
278                         unsigned int hash = util_string_hash32(udev_list_entry_get_name(list_entry));
279
280                         /* load device subsystem value in A */
281                         bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_subsystem_hash));
282                         if (udev_list_entry_get_value(list_entry) == NULL) {
283                                 /* jump if subsystem does not match */
284                                 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
285                         } else {
286                                 /* jump if subsystem does not match */
287                                 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 3);
288
289                                 /* load device devtype value in A */
290                                 bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_devtype_hash));
291                                 /* jump if value does not match */
292                                 hash = util_string_hash32(udev_list_entry_get_value(list_entry));
293                                 bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1);
294                         }
295
296                         /* matched, pass packet */
297                         bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
298
299                         if (i+1 >= ELEMENTSOF(ins))
300                                 return -1;
301                 }
302
303                 /* nothing matched, drop packet */
304                 bpf_stmt(ins, &i, BPF_RET|BPF_K, 0);
305         }
306
307         /* matched, pass packet */
308         bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff);
309
310         /* install filter */
311         memset(&filter, 0x00, sizeof(filter));
312         filter.len = i;
313         filter.filter = ins;
314         err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
315         return err;
316 }
317
318 int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender)
319 {
320         udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
321         return 0;
322 }
323 /**
324  * udev_monitor_enable_receiving:
325  * @udev_monitor: the monitor which should receive events
326  *
327  * Binds the @udev_monitor socket to the event source.
328  *
329  * Returns: 0 on success, otherwise a negative error value.
330  */
331 _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
332 {
333         int err = 0;
334         const int on = 1;
335
336         if (udev_monitor->snl.nl.nl_family == 0)
337                 return -EINVAL;
338
339         udev_monitor_filter_update(udev_monitor);
340
341         if (!udev_monitor->bound) {
342                 err = bind(udev_monitor->sock,
343                            &udev_monitor->snl.sa, sizeof(struct sockaddr_nl));
344                 if (err == 0)
345                         udev_monitor->bound = true;
346         }
347
348         if (err >= 0) {
349                 union sockaddr_union snl;
350                 socklen_t addrlen;
351
352                 /*
353                  * get the address the kernel has assigned us
354                  * it is usually, but not necessarily the pid
355                  */
356                 addrlen = sizeof(struct sockaddr_nl);
357                 err = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
358                 if (err == 0)
359                         udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
360         } else {
361                 udev_err(udev_monitor->udev, "bind failed: %m\n");
362                 return err;
363         }
364
365         /* enable receiving of sender credentials */
366         setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
367         return 0;
368 }
369
370 /**
371  * udev_monitor_set_receive_buffer_size:
372  * @udev_monitor: the monitor which should receive events
373  * @size: the size in bytes
374  *
375  * Set the size of the kernel socket buffer. This call needs the
376  * appropriate privileges to succeed.
377  *
378  * Returns: 0 on success, otherwise -1 on error.
379  */
380 _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size)
381 {
382         if (udev_monitor == NULL)
383                 return -1;
384         return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size));
385 }
386
387 int udev_monitor_disconnect(struct udev_monitor *udev_monitor)
388 {
389         int err;
390
391         err = close(udev_monitor->sock);
392         udev_monitor->sock = -1;
393         return err;
394 }
395
396 /**
397  * udev_monitor_ref:
398  * @udev_monitor: udev monitor
399  *
400  * Take a reference of a udev monitor.
401  *
402  * Returns: the passed udev monitor
403  **/
404 _public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor)
405 {
406         if (udev_monitor == NULL)
407                 return NULL;
408         udev_monitor->refcount++;
409         return udev_monitor;
410 }
411
412 /**
413  * udev_monitor_unref:
414  * @udev_monitor: udev monitor
415  *
416  * Drop a reference of a udev monitor. If the refcount reaches zero,
417  * the bound socket will be closed, and the resources of the monitor
418  * will be released.
419  *
420  **/
421 _public_ void udev_monitor_unref(struct udev_monitor *udev_monitor)
422 {
423         if (udev_monitor == NULL)
424                 return;
425         udev_monitor->refcount--;
426         if (udev_monitor->refcount > 0)
427                 return;
428         if (udev_monitor->sock >= 0)
429                 close(udev_monitor->sock);
430         udev_list_cleanup(&udev_monitor->filter_subsystem_list);
431         udev_list_cleanup(&udev_monitor->filter_tag_list);
432         free(udev_monitor);
433 }
434
435 /**
436  * udev_monitor_get_udev:
437  * @udev_monitor: udev monitor
438  *
439  * Retrieve the udev library context the monitor was created with.
440  *
441  * Returns: the udev library context
442  **/
443 _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor)
444 {
445         if (udev_monitor == NULL)
446                 return NULL;
447         return udev_monitor->udev;
448 }
449
450 /**
451  * udev_monitor_get_fd:
452  * @udev_monitor: udev monitor
453  *
454  * Retrieve the socket file descriptor associated with the monitor.
455  *
456  * Returns: the socket file descriptor
457  **/
458 _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor)
459 {
460         if (udev_monitor == NULL)
461                 return -1;
462         return udev_monitor->sock;
463 }
464
465 static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device *udev_device)
466 {
467         struct udev_list_entry *list_entry;
468
469         if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL)
470                 goto tag;
471         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) {
472                 const char *subsys = udev_list_entry_get_name(list_entry);
473                 const char *dsubsys = udev_device_get_subsystem(udev_device);
474                 const char *devtype;
475                 const char *ddevtype;
476
477                 if (strcmp(dsubsys, subsys) != 0)
478                         continue;
479
480                 devtype = udev_list_entry_get_value(list_entry);
481                 if (devtype == NULL)
482                         goto tag;
483                 ddevtype = udev_device_get_devtype(udev_device);
484                 if (ddevtype == NULL)
485                         continue;
486                 if (strcmp(ddevtype, devtype) == 0)
487                         goto tag;
488         }
489         return 0;
490
491 tag:
492         if (udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL)
493                 return 1;
494         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) {
495                 const char *tag = udev_list_entry_get_name(list_entry);
496
497                 if (udev_device_has_tag(udev_device, tag))
498                         return 1;
499         }
500         return 0;
501 }
502
503 /**
504  * udev_monitor_receive_device:
505  * @udev_monitor: udev monitor
506  *
507  * Receive data from the udev monitor socket, allocate a new udev
508  * device, fill in the received data, and return the device.
509  *
510  * Only socket connections with uid=0 are accepted.
511  *
512  * The initial refcount is 1, and needs to be decremented to
513  * release the resources of the udev device.
514  *
515  * Returns: a new udev device, or #NULL, in case of an error
516  **/
517 _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor)
518 {
519         struct udev_device *udev_device;
520         struct msghdr smsg;
521         struct iovec iov;
522         char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
523         struct cmsghdr *cmsg;
524         union sockaddr_union snl;
525         struct ucred *cred;
526         char buf[8192];
527         ssize_t buflen;
528         ssize_t bufpos;
529         struct udev_monitor_netlink_header *nlh;
530
531 retry:
532         if (udev_monitor == NULL)
533                 return NULL;
534         iov.iov_base = &buf;
535         iov.iov_len = sizeof(buf);
536         memset (&smsg, 0x00, sizeof(struct msghdr));
537         smsg.msg_iov = &iov;
538         smsg.msg_iovlen = 1;
539         smsg.msg_control = cred_msg;
540         smsg.msg_controllen = sizeof(cred_msg);
541
542         if (udev_monitor->snl.nl.nl_family != 0) {
543                 smsg.msg_name = &snl;
544                 smsg.msg_namelen = sizeof(snl);
545         }
546
547         buflen = recvmsg(udev_monitor->sock, &smsg, 0);
548         if (buflen < 0) {
549                 if (errno != EINTR)
550                         udev_dbg(udev_monitor->udev, "unable to receive message\n");
551                 return NULL;
552         }
553
554         if (buflen < 32 || (size_t)buflen >= sizeof(buf)) {
555                 udev_dbg(udev_monitor->udev, "invalid message length\n");
556                 return NULL;
557         }
558
559         if (udev_monitor->snl.nl.nl_family != 0) {
560                 if (snl.nl.nl_groups == 0) {
561                         /* unicast message, check if we trust the sender */
562                         if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 ||
563                             snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) {
564                                 udev_dbg(udev_monitor->udev, "unicast netlink message ignored\n");
565                                 return NULL;
566                         }
567                 } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) {
568                         if (snl.nl.nl_pid > 0) {
569                                 udev_dbg(udev_monitor->udev, "multicast kernel netlink message from pid %d ignored\n",
570                                      snl.nl.nl_pid);
571                                 return NULL;
572                         }
573                 }
574         }
575
576         cmsg = CMSG_FIRSTHDR(&smsg);
577         if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
578                 udev_dbg(udev_monitor->udev, "no sender credentials received, message ignored\n");
579                 return NULL;
580         }
581
582         cred = (struct ucred *)CMSG_DATA(cmsg);
583         if (cred->uid != 0) {
584                 udev_dbg(udev_monitor->udev, "sender uid=%d, message ignored\n", cred->uid);
585                 return NULL;
586         }
587
588         if (memcmp(buf, "libudev", 8) == 0) {
589                 /* udev message needs proper version magic */
590                 nlh = (struct udev_monitor_netlink_header *) buf;
591                 if (nlh->magic != htonl(UDEV_MONITOR_MAGIC)) {
592                         udev_err(udev_monitor->udev, "unrecognized message signature (%x != %x)\n",
593                             nlh->magic, htonl(UDEV_MONITOR_MAGIC));
594                         return NULL;
595                 }
596                 if (nlh->properties_off+32 > buflen)
597                         return NULL;
598                 bufpos = nlh->properties_off;
599         } else {
600                 /* kernel message with header */
601                 bufpos = strlen(buf) + 1;
602                 if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) {
603                         udev_dbg(udev_monitor->udev, "invalid message length\n");
604                         return NULL;
605                 }
606
607                 /* check message header */
608                 if (strstr(buf, "@/") == NULL) {
609                         udev_dbg(udev_monitor->udev, "unrecognized message header\n");
610                         return NULL;
611                 }
612         }
613
614         udev_device = udev_device_new(udev_monitor->udev);
615         if (udev_device == NULL)
616                 return NULL;
617         udev_device_set_info_loaded(udev_device);
618
619         while (bufpos < buflen) {
620                 char *key;
621                 size_t keylen;
622
623                 key = &buf[bufpos];
624                 keylen = strlen(key);
625                 if (keylen == 0)
626                         break;
627                 bufpos += keylen + 1;
628                 udev_device_add_property_from_string_parse(udev_device, key);
629         }
630
631         if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
632                 udev_dbg(udev_monitor->udev, "missing values, invalid device\n");
633                 udev_device_unref(udev_device);
634                 return NULL;
635         }
636
637         /* skip device, if it does not pass the current filter */
638         if (!passes_filter(udev_monitor, udev_device)) {
639                 struct pollfd pfd[1];
640                 int rc;
641
642                 udev_device_unref(udev_device);
643
644                 /* if something is queued, get next device */
645                 pfd[0].fd = udev_monitor->sock;
646                 pfd[0].events = POLLIN;
647                 rc = poll(pfd, 1, 0);
648                 if (rc > 0)
649                         goto retry;
650                 return NULL;
651         }
652
653         return udev_device;
654 }
655
656 int udev_monitor_send_device(struct udev_monitor *udev_monitor,
657                              struct udev_monitor *destination, struct udev_device *udev_device)
658 {
659         const char *buf;
660         ssize_t blen;
661         ssize_t count;
662         struct msghdr smsg;
663         struct iovec iov[2];
664         const char *val;
665         struct udev_monitor_netlink_header nlh;
666         struct udev_list_entry *list_entry;
667         uint64_t tag_bloom_bits;
668
669         if (udev_monitor->snl.nl.nl_family == 0)
670                 return -EINVAL;
671
672         blen = udev_device_get_properties_monitor_buf(udev_device, &buf);
673         if (blen < 32)
674                 return -EINVAL;
675
676         /* add versioned header */
677         memset(&nlh, 0x00, sizeof(struct udev_monitor_netlink_header));
678         memcpy(nlh.prefix, "libudev", 8);
679         nlh.magic = htonl(UDEV_MONITOR_MAGIC);
680         nlh.header_size = sizeof(struct udev_monitor_netlink_header);
681         val = udev_device_get_subsystem(udev_device);
682         nlh.filter_subsystem_hash = htonl(util_string_hash32(val));
683         val = udev_device_get_devtype(udev_device);
684         if (val != NULL)
685                 nlh.filter_devtype_hash = htonl(util_string_hash32(val));
686         iov[0].iov_base = &nlh;
687         iov[0].iov_len = sizeof(struct udev_monitor_netlink_header);
688
689         /* add tag bloom filter */
690         tag_bloom_bits = 0;
691         udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
692                 tag_bloom_bits |= util_string_bloom64(udev_list_entry_get_name(list_entry));
693         if (tag_bloom_bits > 0) {
694                 nlh.filter_tag_bloom_hi = htonl(tag_bloom_bits >> 32);
695                 nlh.filter_tag_bloom_lo = htonl(tag_bloom_bits & 0xffffffff);
696         }
697
698         /* add properties list */
699         nlh.properties_off = iov[0].iov_len;
700         nlh.properties_len = blen;
701         iov[1].iov_base = (char *)buf;
702         iov[1].iov_len = blen;
703
704         memset(&smsg, 0x00, sizeof(struct msghdr));
705         smsg.msg_iov = iov;
706         smsg.msg_iovlen = 2;
707         /*
708          * Use custom address for target, or the default one.
709          *
710          * If we send to a multicast group, we will get
711          * ECONNREFUSED, which is expected.
712          */
713         if (destination != NULL)
714                 smsg.msg_name = &destination->snl;
715         else
716                 smsg.msg_name = &udev_monitor->snl_destination;
717         smsg.msg_namelen = sizeof(struct sockaddr_nl);
718         count = sendmsg(udev_monitor->sock, &smsg, 0);
719         udev_dbg(udev_monitor->udev, "passed %zi bytes to netlink monitor %p\n", count, udev_monitor);
720         return count;
721 }
722
723 /**
724  * udev_monitor_filter_add_match_subsystem_devtype:
725  * @udev_monitor: the monitor
726  * @subsystem: the subsystem value to match the incoming devices against
727  * @devtype: the devtype value to match the incoming devices against
728  *
729  * This filter is efficiently executed inside the kernel, and libudev subscribers
730  * will usually not be woken up for devices which do not match.
731  *
732  * The filter must be installed before the monitor is switched to listening mode.
733  *
734  * Returns: 0 on success, otherwise a negative error value.
735  */
736 _public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype)
737 {
738         if (udev_monitor == NULL)
739                 return -EINVAL;
740         if (subsystem == NULL)
741                 return -EINVAL;
742         if (udev_list_entry_add(&udev_monitor->filter_subsystem_list, subsystem, devtype) == NULL)
743                 return -ENOMEM;
744         return 0;
745 }
746
747 /**
748  * udev_monitor_filter_add_match_tag:
749  * @udev_monitor: the monitor
750  * @tag: the name of a tag
751  *
752  * This filter is efficiently executed inside the kernel, and libudev subscribers
753  * will usually not be woken up for devices which do not match.
754  *
755  * The filter must be installed before the monitor is switched to listening mode.
756  *
757  * Returns: 0 on success, otherwise a negative error value.
758  */
759 _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag)
760 {
761         if (udev_monitor == NULL)
762                 return -EINVAL;
763         if (tag == NULL)
764                 return -EINVAL;
765         if (udev_list_entry_add(&udev_monitor->filter_tag_list, tag, NULL) == NULL)
766                 return -ENOMEM;
767         return 0;
768 }
769
770 /**
771  * udev_monitor_filter_remove:
772  * @udev_monitor: monitor
773  *
774  * Remove all filters from monitor.
775  *
776  * Returns: 0 on success, otherwise a negative error value.
777  */
778 _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor)
779 {
780         static struct sock_fprog filter = { 0, NULL };
781
782         udev_list_cleanup(&udev_monitor->filter_subsystem_list);
783         return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
784 }