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