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