chiark / gitweb /
075e10204bacd50a57092d3177d8795d48e8faa9
[elogind.git] / src / libsystemd-network / sd-pppoe.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 Tom Gundersen
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 /* See RFC 2516 */
23
24 #include <sys/ioctl.h>
25 #include <linux/ppp_defs.h>
26 #include <linux/ppp-ioctl.h>
27 #include <net/if.h>
28 #include <netinet/in.h>
29 #include <linux/if_pppox.h>
30
31 #include "sd-pppoe.h"
32
33 #include "event-util.h"
34
35 #include "util.h"
36 #include "socket-util.h"
37 #include "async.h"
38 #include "refcnt.h"
39 #include "unaligned.h"
40 #include "utf8.h"
41
42 #define PPPOE_MAX_PACKET_SIZE 1484
43 #define PPPOE_MAX_PADR_RESEND 16
44
45 /* TODO: move this to socket-util.h without getting into
46  * a mess with the includes */
47 union sockaddr_union_pppox {
48         struct sockaddr sa;
49         struct sockaddr_pppox pppox;
50 };
51
52 typedef enum PPPoEState {
53         PPPOE_STATE_INITIALIZING,
54         PPPOE_STATE_REQUESTING,
55         PPPOE_STATE_RUNNING,
56         PPPOE_STATE_STOPPED,
57         _PPPOE_STATE_MAX,
58         _PPPOE_STATE_INVALID = -1,
59 } PPPoEState;
60
61 typedef struct PPPoETags {
62                 char *service_name;
63                 char *ac_name;
64                 uint8_t *host_uniq;
65                 size_t host_uniq_len;
66                 uint8_t *cookie;
67                 size_t cookie_len;
68 } PPPoETags;
69
70 struct sd_pppoe {
71         RefCount n_ref;
72
73         PPPoEState state;
74         uint64_t host_uniq;
75
76         int ifindex;
77         char *ifname;
78
79         sd_event *event;
80         int event_priority;
81         int fd;
82         sd_event_source *io;
83         sd_event_source *timeout;
84         int padr_resend_count;
85
86         char *service_name;
87         struct ether_addr peer_mac;
88         be16_t session_id;
89
90         int pppoe_fd;
91         int channel;
92
93         sd_pppoe_cb_t cb;
94         void *userdata;
95
96         PPPoETags tags;
97 };
98
99 #define PPPOE_PACKET_LENGTH(header) \
100         be16toh((header)->length)
101
102 #define PPPOE_PACKET_TAIL(packet)                                                                               \
103         (struct pppoe_tag *)((uint8_t*)(packet) + sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
104
105 #define PPPOE_TAG_LENGTH(tag)                   \
106         unaligned_read_be16(&(tag)->tag_len)
107
108 #define PPPOE_TAG_TYPE(tag)                     \
109         htobe16(unaligned_read_be16(&(tag)->tag_type))
110
111 #define PPPOE_TAG_SET_LENGTH(tag, len) \
112         unaligned_write_be16(&(tag)->tag_len, len)
113
114 #define PPPOE_TAG_SET_TYPE(tag, len) \
115         unaligned_write_be16(&(tag)->tag_type, be16toh(len))
116
117 #define PPPOE_TAG_NEXT(tag)                                                                      \
118         (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
119
120 #define PPPOE_TAGS_FOREACH(tag, header)                                                                 \
121         for (tag = (header)->tag;                                                                       \
122              ((uint8_t *)(tag) + sizeof(struct pppoe_tag) < (uint8_t*)PPPOE_PACKET_TAIL(header)) &&     \
123                 (PPPOE_TAG_NEXT(tag) <= PPPOE_PACKET_TAIL(header)) &&                                   \
124                 (tag >= (header)->tag) &&                                                               \
125                 (PPPOE_TAG_TYPE(tag) != PTT_EOL);                                                           \
126              tag = PPPOE_TAG_NEXT(tag))
127
128 static void pppoe_tags_clear(PPPoETags *tags) {
129         free(tags->service_name);
130         free(tags->ac_name);
131         free(tags->host_uniq);
132         free(tags->cookie);
133
134         zero(*tags);
135 }
136
137 int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
138         assert_return(ppp, -EINVAL);
139         assert_return(ifindex > 0, -EINVAL);
140
141         ppp->ifindex = ifindex;
142
143         return 0;
144 }
145
146 int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
147         char *name;
148
149         assert_return(ppp, -EINVAL);
150         assert_return(ifname, -EINVAL);
151
152         if (strlen(ifname) > IFNAMSIZ)
153                 return -EINVAL;
154
155         name = strdup(ifname);
156         if (!name)
157                 return -ENOMEM;
158
159         free(ppp->ifname);
160         ppp->ifname = name;
161
162         return 0;
163 }
164
165 int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
166         _cleanup_free_ char *name = NULL;
167
168         assert_return(ppp, -EINVAL);
169
170         if (service_name) {
171                 name = strdup(service_name);
172                 if (!name)
173                         return -ENOMEM;
174         }
175
176         free(ppp->service_name);
177         ppp->service_name = name;
178         name = NULL;
179
180         return 0;
181 }
182
183 int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
184         int r;
185
186         assert_return(ppp, -EINVAL);
187         assert_return(!ppp->event, -EBUSY);
188
189         if (event)
190                 ppp->event = sd_event_ref(event);
191         else {
192                 r = sd_event_default(&ppp->event);
193                 if (r < 0)
194                         return r;
195         }
196
197         ppp->event_priority = priority;
198
199         return 0;
200 }
201
202 int sd_pppoe_detach_event(sd_pppoe *ppp) {
203         assert_return(ppp, -EINVAL);
204
205         ppp->event = sd_event_unref(ppp->event);
206
207         return 0;
208 }
209
210 sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
211         if (ppp)
212                 assert_se(REFCNT_INC(ppp->n_ref) >= 2);
213
214         return ppp;
215 }
216
217 sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
218         if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
219                 pppoe_tags_clear(&ppp->tags);
220                 free(ppp->ifname);
221                 free(ppp->service_name);
222                 sd_pppoe_stop(ppp);
223                 sd_pppoe_detach_event(ppp);
224
225                 free(ppp);
226         }
227
228         return NULL;
229 }
230
231 int sd_pppoe_new (sd_pppoe **ret) {
232         sd_pppoe *ppp;
233
234         assert_return(ret, -EINVAL);
235
236         ppp = new0(sd_pppoe, 1);
237         if (!ppp)
238                 return -ENOMEM;
239
240         ppp->n_ref = REFCNT_INIT;
241         ppp->state = _PPPOE_STATE_INVALID;
242         ppp->ifindex = -1;
243         ppp->fd = -1;
244         ppp->pppoe_fd = -1;
245         ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
246
247         *ret = ppp;
248
249         return 0;
250 }
251
252 int sd_pppoe_get_channel(sd_pppoe *ppp, int *channel) {
253         assert_return(ppp, -EINVAL);
254         assert_return(channel, -EINVAL);
255         assert_return(ppp->pppoe_fd != -1, -EUNATCH);
256         assert_return(ppp->state == PPPOE_STATE_RUNNING, -EUNATCH);
257
258         *channel = ppp->channel;
259
260         return 0;
261 }
262
263 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
264         assert_return(ppp, -EINVAL);
265
266         ppp->cb = cb;
267         ppp->userdata = userdata;
268
269         return 0;
270 }
271
272 static void pppoe_tag_append(struct pppoe_hdr *packet, size_t packet_size, be16_t tag_type, const void *tag_data, uint16_t tag_len) {
273         struct pppoe_tag *tag;
274
275         assert(packet);
276         assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
277         assert(!(!tag_data ^ !tag_len));
278
279         tag = PPPOE_PACKET_TAIL(packet);
280
281         PPPOE_TAG_SET_LENGTH(tag, tag_len);
282         PPPOE_TAG_SET_TYPE(tag, tag_type);
283         if (tag_data)
284                 memcpy(tag->tag_data, tag_data, tag_len);
285
286         packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
287 }
288
289 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
290         union sockaddr_union link = {
291                 .ll = {
292                         .sll_family = AF_PACKET,
293                         .sll_protocol = htons(ETH_P_PPP_DISC),
294                         .sll_halen = ETH_ALEN,
295                 },
296         };
297         _cleanup_free_ struct pppoe_hdr *packet = NULL;
298         int r;
299
300         assert(ppp);
301         assert(ppp->fd != -1);
302         assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
303
304         link.ll.sll_ifindex = ppp->ifindex;
305         if (code == PADI_CODE)
306                 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
307         else
308                 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
309
310         packet = malloc0(PPPOE_MAX_PACKET_SIZE);
311         if (!packet)
312                 return -ENOMEM;
313
314         packet->ver = 0x1;
315         packet->type = 0x1;
316         packet->code = code;
317         if (code == PADT_CODE)
318                 packet->sid = ppp->session_id;
319
320         /* Service-Name */
321         pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
322                          ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
323
324         /* AC-Cookie */
325         if (code == PADR_CODE && ppp->tags.cookie)
326                 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE,
327                                  ppp->tags.cookie, ppp->tags.cookie_len);
328
329         /* Host-Uniq */
330         if (code != PADT_CODE) {
331                 ppp->host_uniq = random_u64();
332
333                 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
334                                  &ppp->host_uniq, sizeof(ppp->host_uniq));
335         }
336
337         r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
338                    0, &link.sa, sizeof(link.ll));
339         if (r < 0)
340                 return -errno;
341
342         return 0;
343 }
344
345 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
346
347 static int pppoe_arm_timeout(sd_pppoe *ppp) {
348         _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
349         usec_t next_timeout;
350         int r;
351
352         assert(ppp);
353
354         r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
355         if (r == -ENODATA)
356                 next_timeout = now(clock_boottime_or_monotonic());
357         else if (r < 0)
358                 return r;
359
360         next_timeout += 500 * USEC_PER_MSEC;
361
362         r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
363                               10 * USEC_PER_MSEC, pppoe_timeout, ppp);
364         if (r < 0)
365                 return r;
366
367         r = sd_event_source_set_priority(timeout, ppp->event_priority);
368         if (r < 0)
369                 return r;
370
371         sd_event_source_unref(ppp->timeout);
372         ppp->timeout = timeout;
373         timeout = NULL;
374
375         return 0;
376 }
377
378 static int pppoe_send_initiation(sd_pppoe *ppp) {
379         int r;
380
381         r = pppoe_send(ppp, PADI_CODE);
382         if (r < 0)
383                 return r;
384
385         log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
386                   ppp->service_name ? : "");
387
388         pppoe_arm_timeout(ppp);
389
390         return r;
391 }
392
393 static int pppoe_send_request(sd_pppoe *ppp) {
394         int r;
395
396         r = pppoe_send(ppp, PADR_CODE);
397         if (r < 0)
398                 return r;
399
400         log_debug("PPPoE: sent REQUEST");
401
402         ppp->padr_resend_count --;
403
404         pppoe_arm_timeout(ppp);
405
406         return 0;
407 }
408
409 static int pppoe_send_terminate(sd_pppoe *ppp) {
410         int r;
411
412         r = pppoe_send(ppp, PADT_CODE);
413         if (r < 0)
414                 return r;
415
416         log_debug("PPPoE: sent TERMINATE");
417
418         return 0;
419 }
420
421 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
422         sd_pppoe *ppp = userdata;
423         int r;
424
425         assert(ppp);
426
427         switch (ppp->state) {
428         case PPPOE_STATE_INITIALIZING:
429                 r = pppoe_send_initiation(ppp);
430                 if (r < 0)
431                         log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
432
433                 break;
434         case PPPOE_STATE_REQUESTING:
435                 if (ppp->padr_resend_count <= 0) {
436                         log_debug("PPPoE: PADR timed out, restarting PADI");
437
438                         r = pppoe_send_initiation(ppp);
439                         if (r < 0)
440                                 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
441
442                         ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
443                         ppp->state = PPPOE_STATE_INITIALIZING;
444                 } else {
445                         r = pppoe_send_request(ppp);
446                         if (r < 0)
447                                 log_warning("PPPoE: sending PADR failed: %s", strerror(-r));
448                 }
449
450                 break;
451         default:
452                 assert_not_reached("timeout in invalid state");
453         }
454
455         return 0;
456 }
457
458 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
459         uint8_t *data;
460
461         assert(ret);
462         assert(length);
463
464         data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
465         if (!data)
466                 return -ENOMEM;
467
468         free(*ret);
469         *ret = data;
470         *length = PPPOE_TAG_LENGTH(tag);
471
472         return 0;
473 }
474
475 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
476         char *string;
477
478         assert(ret);
479
480         string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
481         if (!string)
482                 return -ENOMEM;
483
484         free(*ret);
485         *ret = string;
486
487         return 0;
488 }
489
490 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
491         struct pppoe_tag *tag;
492         int r;
493
494         assert(tags);
495
496         pppoe_tags_clear(tags);
497
498         PPPOE_TAGS_FOREACH(tag, header) {
499                 switch (PPPOE_TAG_TYPE(tag)) {
500                 case PTT_SRV_NAME:
501                         r = pppoe_tag_parse_string(tag, &tags->service_name);
502                         if (r < 0)
503                                 return r;
504
505                         break;
506                 case PTT_AC_NAME:
507                         r = pppoe_tag_parse_string(tag, &tags->ac_name);
508                         if (r < 0)
509                                 return r;
510
511                         break;
512                 case PTT_HOST_UNIQ:
513                         r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
514                         if (r < 0)
515                                 return r;
516
517                         break;
518                 case PTT_AC_COOKIE:
519                         r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
520                         if (r < 0)
521                                 return r;
522
523                         break;
524                 case PTT_SRV_ERR:
525                 case PTT_SYS_ERR:
526                 case PTT_GEN_ERR:
527                 {
528                         _cleanup_free_ char *error = NULL;
529
530                         /* TODO: do something more sensible with the error messages */
531                         r = pppoe_tag_parse_string(tag, &error);
532                         if (r < 0)
533                                 return r;
534
535                         if (strlen(error) > 0 && utf8_is_valid(error))
536                                 log_debug("PPPoE: error - '%s'", error);
537                         else
538                                 log_debug("PPPoE: error");
539
540                         break;
541                 }
542                 default:
543                         log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
544                 }
545         }
546
547         return 0;
548 }
549
550 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
551         int s;
552
553         assert(ppp);
554         assert(ppp->pppoe_fd == -1);
555
556         s = socket(AF_PPPOX, SOCK_STREAM, 0);
557         if (s < 0)
558                 return -errno;
559
560         ppp->pppoe_fd = s;
561
562         return 0;
563 }
564
565 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
566         union sockaddr_union_pppox link = {
567                 .pppox = {
568                         .sa_family = AF_PPPOX,
569                         .sa_protocol = PX_PROTO_OE,
570                 },
571         };
572         int r, channel;
573
574         assert(ppp);
575         assert(ppp->pppoe_fd != -1);
576         assert(ppp->session_id);
577         assert(ppp->ifname);
578
579         link.pppox.sa_addr.pppoe.sid = ppp->session_id;
580         memcpy(link.pppox.sa_addr.pppoe.dev, ppp->ifname, strlen(ppp->ifname));
581         memcpy(link.pppox.sa_addr.pppoe.remote, &ppp->peer_mac, ETH_ALEN);
582
583         r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
584         if (r < 0)
585                 return r;
586
587         r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
588         if (r < 0)
589                 return -errno;
590
591         ppp->channel = channel;
592
593         return 0;
594 }
595
596 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
597         int r;
598
599         assert(packet);
600
601         if (packet->ver != 0x1 || packet->type != 0x1)
602                 return 0;
603
604         r = pppoe_payload_parse(&ppp->tags, packet);
605         if (r < 0)
606                 return 0;
607
608         switch (ppp->state) {
609         case PPPOE_STATE_INITIALIZING:
610                 if (packet->code != PADO_CODE)
611                         return 0;
612
613                 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
614                     memcmp(ppp->tags.host_uniq, &ppp->host_uniq, sizeof(ppp->host_uniq)) != 0)
615                         return 0;
616
617                 log_debug("PPPoE: got OFFER (Peer: "
618                   "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
619                   "Service-Name: '%s'; AC-Name: '%s')",
620                   mac->ether_addr_octet[0],
621                   mac->ether_addr_octet[1],
622                   mac->ether_addr_octet[2],
623                   mac->ether_addr_octet[3],
624                   mac->ether_addr_octet[4],
625                   mac->ether_addr_octet[5],
626                   ppp->tags.service_name ? : "",
627                   ppp->tags.ac_name ? : "");
628
629                 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
630
631                 r = pppoe_open_pppoe_socket(ppp);
632                 if (r < 0) {
633                         log_warning("PPPoE: could not open socket");
634                         return r;
635                 }
636
637                 r = pppoe_send_request(ppp);
638                 if (r < 0)
639                         return 0;
640
641                 ppp->state = PPPOE_STATE_REQUESTING;
642
643                 break;
644         case PPPOE_STATE_REQUESTING:
645                 if (packet->code != PADS_CODE)
646                         return 0;
647
648                 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
649                     memcmp(ppp->tags.host_uniq, &ppp->host_uniq,
650                            sizeof(ppp->host_uniq)) != 0)
651                         return 0;
652
653                 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
654                         return 0;
655
656                 ppp->session_id = packet->sid;
657
658                 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
659                           be16toh(ppp->session_id));
660
661                 r = pppoe_connect_pppoe_socket(ppp);
662                 if (r < 0) {
663                         log_warning("PPPoE: could not connect socket");
664                         return r;
665                 }
666
667                 ppp->state = PPPOE_STATE_RUNNING;
668
669                 ppp->timeout = sd_event_source_unref(ppp->timeout);
670                 assert(ppp->cb);
671                 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
672
673                 break;
674         case PPPOE_STATE_RUNNING:
675                 if (packet->code != PADT_CODE)
676                         return 0;
677
678                 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
679                         return 0;
680
681                 if (ppp->session_id != packet->sid)
682                         return 0;
683
684                 log_debug("PPPoE: got TERMINATE");
685
686                 ppp->state = PPPOE_STATE_STOPPED;
687
688                 assert(ppp->cb);
689                 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
690
691                 break;
692         case PPPOE_STATE_STOPPED:
693                 break;
694         default:
695                 assert_not_reached("PPPoE: invalid state when receiving message");
696         }
697
698         return 0;
699 }
700
701 static int pppoe_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
702         sd_pppoe *ppp = userdata;
703         _cleanup_free_ struct pppoe_hdr *packet = NULL;
704         union sockaddr_union link = {};
705         socklen_t addrlen = sizeof(link);
706         int buflen = 0, len, r;
707
708         assert(ppp);
709         assert(fd != -1);
710
711         r = ioctl(fd, FIONREAD, &buflen);
712         if (r < 0)
713                 return r;
714
715         if (buflen < 0)
716                 /* this can't be right */
717                 return -EIO;
718
719         packet = malloc0(buflen);
720         if (!packet)
721                 return -ENOMEM;
722
723         len = recvfrom(fd, packet, buflen, 0, &link.sa, &addrlen);
724         if (len < 0) {
725                 log_warning("PPPoE: colud not receive message from raw socket: %s", strerror(-r));
726                 return 0;
727         } else if ((size_t)len < sizeof(struct pppoe_hdr))
728                 return 0;
729         else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
730                 return 0;
731
732         if (link.ll.sll_halen != ETH_ALEN)
733                 /* not ethernet? */
734                 return 0;
735
736         r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
737         if (r < 0)
738                 return r;
739
740         return 1;
741 }
742
743 int sd_pppoe_start(sd_pppoe *ppp) {
744         union sockaddr_union link = {
745                 .ll = {
746                         .sll_family = AF_PACKET,
747                         .sll_protocol = htons(ETH_P_PPP_DISC),
748                 },
749         };
750         _cleanup_close_ int s = -1;
751         _cleanup_event_source_unref_ sd_event_source *io = NULL;
752         int r;
753
754         assert_return(ppp, -EINVAL);
755         assert_return(ppp->fd == -1, -EBUSY);
756         assert_return(!ppp->io, -EBUSY);
757         assert_return(ppp->ifindex > 0, -EUNATCH);
758         assert_return(ppp->ifname, -EUNATCH);
759         assert_return(ppp->event, -EUNATCH);
760         assert_return(ppp->cb, -EUNATCH);
761
762         s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
763         if (s < 0)
764                 return -errno;
765
766         link.ll.sll_ifindex = ppp->ifindex;
767
768         r = bind(s, &link.sa, sizeof(link.ll));
769         if (r < 0)
770                 return r;
771
772         r = sd_event_add_io(ppp->event, &io,
773                             s, EPOLLIN, pppoe_receive_message,
774                             ppp);
775         if (r < 0)
776                 return r;
777
778         r = sd_event_source_set_priority(io, ppp->event_priority);
779         if (r < 0)
780                 return r;
781
782         ppp->fd = s;
783         s = -1;
784         ppp->io = io;
785         io = NULL;
786
787         r = pppoe_send_initiation(ppp);
788         if (r < 0)
789                 return r;
790
791         ppp->state = PPPOE_STATE_INITIALIZING;
792
793         return 0;
794 }
795
796 int sd_pppoe_stop(sd_pppoe *ppp) {
797         assert_return(ppp, -EINVAL);
798
799         if (ppp->state == PPPOE_STATE_RUNNING)
800                 pppoe_send_terminate(ppp);
801
802         ppp->io = sd_event_source_unref(ppp->io);
803         ppp->timeout = sd_event_source_unref(ppp->timeout);
804         ppp->fd = asynchronous_close(ppp->fd);
805         ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);
806
807         return 0;
808 }