chiark / gitweb /
6f335415046ccc73df7b2e6f3b88e0e11666c4e7
[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                 free(ppp->ifname);
220                 free(ppp->service_name);
221                 sd_pppoe_stop(ppp);
222                 sd_pppoe_detach_event(ppp);
223
224                 free(ppp);
225         }
226
227         return NULL;
228 }
229
230 int sd_pppoe_new (sd_pppoe **ret) {
231         sd_pppoe *ppp;
232
233         assert_return(ret, -EINVAL);
234
235         ppp = new0(sd_pppoe, 1);
236         if (!ppp)
237                 return -ENOMEM;
238
239         ppp->n_ref = REFCNT_INIT;
240         ppp->state = _PPPOE_STATE_INVALID;
241         ppp->ifindex = -1;
242         ppp->fd = -1;
243         ppp->pppoe_fd = -1;
244         ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
245
246         *ret = ppp;
247
248         return 0;
249 }
250
251 int sd_pppoe_get_channel(sd_pppoe *ppp, int *channel) {
252         assert_return(ppp, -EINVAL);
253         assert_return(channel, -EINVAL);
254         assert_return(ppp->pppoe_fd != -1, -EUNATCH);
255         assert_return(ppp->state == PPPOE_STATE_RUNNING, -EUNATCH);
256
257         *channel = ppp->channel;
258
259         return 0;
260 }
261
262 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
263         assert_return(ppp, -EINVAL);
264
265         ppp->cb = cb;
266         ppp->userdata = userdata;
267
268         return 0;
269 }
270
271 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) {
272         struct pppoe_tag *tag;
273
274         assert(packet);
275         assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
276         assert(!(!tag_data ^ !tag_len));
277
278         tag = PPPOE_PACKET_TAIL(packet);
279
280         PPPOE_TAG_SET_LENGTH(tag, tag_len);
281         PPPOE_TAG_SET_TYPE(tag, tag_type);
282         if (tag_data)
283                 memcpy(tag->tag_data, tag_data, tag_len);
284
285         packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
286 }
287
288 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
289         union sockaddr_union link = {
290                 .ll = {
291                         .sll_family = AF_PACKET,
292                         .sll_protocol = htons(ETH_P_PPP_DISC),
293                         .sll_halen = ETH_ALEN,
294                 },
295         };
296         _cleanup_free_ struct pppoe_hdr *packet = NULL;
297         int r;
298
299         assert(ppp);
300         assert(ppp->fd != -1);
301         assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
302
303         link.ll.sll_ifindex = ppp->ifindex;
304         if (code == PADI_CODE)
305                 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
306         else
307                 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
308
309         packet = malloc0(PPPOE_MAX_PACKET_SIZE);
310         if (!packet)
311                 return -ENOMEM;
312
313         packet->ver = 0x1;
314         packet->type = 0x1;
315         packet->code = code;
316         if (code == PADT_CODE)
317                 packet->sid = ppp->session_id;
318
319         /* Service-Name */
320         pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
321                          ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
322
323         /* AC-Cookie */
324         if (code == PADR_CODE && ppp->tags.cookie)
325                 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE,
326                                  ppp->tags.cookie, ppp->tags.cookie_len);
327
328         /* Host-Uniq */
329         if (code != PADT_CODE) {
330                 ppp->host_uniq = random_u64();
331
332                 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
333                                  &ppp->host_uniq, sizeof(ppp->host_uniq));
334         }
335
336         r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
337                    0, &link.sa, sizeof(link.ll));
338         if (r < 0)
339                 return -errno;
340
341         return 0;
342 }
343
344 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
345
346 static int pppoe_arm_timeout(sd_pppoe *ppp) {
347         _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
348         usec_t next_timeout;
349         int r;
350
351         assert(ppp);
352
353         r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
354         if (r == -ENODATA)
355                 next_timeout = now(clock_boottime_or_monotonic());
356         else if (r < 0)
357                 return r;
358
359         next_timeout += 500 * USEC_PER_MSEC;
360
361         r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
362                               10 * USEC_PER_MSEC, pppoe_timeout, ppp);
363         if (r < 0)
364                 return r;
365
366         r = sd_event_source_set_priority(timeout, ppp->event_priority);
367         if (r < 0)
368                 return r;
369
370         sd_event_source_unref(ppp->timeout);
371         ppp->timeout = timeout;
372         timeout = NULL;
373
374         return 0;
375 }
376
377 static int pppoe_send_initiation(sd_pppoe *ppp) {
378         int r;
379
380         r = pppoe_send(ppp, PADI_CODE);
381         if (r < 0)
382                 return r;
383
384         log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
385                   ppp->service_name ? : "");
386
387         pppoe_arm_timeout(ppp);
388
389         return r;
390 }
391
392 static int pppoe_send_request(sd_pppoe *ppp) {
393         int r;
394
395         r = pppoe_send(ppp, PADR_CODE);
396         if (r < 0)
397                 return r;
398
399         log_debug("PPPoE: sent REQUEST");
400
401         ppp->padr_resend_count --;
402
403         pppoe_arm_timeout(ppp);
404
405         return 0;
406 }
407
408 static int pppoe_send_terminate(sd_pppoe *ppp) {
409         int r;
410
411         r = pppoe_send(ppp, PADT_CODE);
412         if (r < 0)
413                 return r;
414
415         log_debug("PPPoE: sent TERMINATE");
416
417         return 0;
418 }
419
420 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
421         sd_pppoe *ppp = userdata;
422         int r;
423
424         assert(ppp);
425
426         switch (ppp->state) {
427         case PPPOE_STATE_INITIALIZING:
428                 r = pppoe_send_initiation(ppp);
429                 if (r < 0)
430                         log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
431
432                 break;
433         case PPPOE_STATE_REQUESTING:
434                 if (ppp->padr_resend_count <= 0) {
435                         log_debug("PPPoE: PADR timed out, restarting PADI");
436
437                         r = pppoe_send_initiation(ppp);
438                         if (r < 0)
439                                 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
440
441                         ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
442                         ppp->state = PPPOE_STATE_INITIALIZING;
443                 } else {
444                         r = pppoe_send_request(ppp);
445                         if (r < 0)
446                                 log_warning("PPPoE: sending PADR failed: %s", strerror(-r));
447                 }
448
449                 break;
450         default:
451                 assert_not_reached("timeout in invalid state");
452         }
453
454         return 0;
455 }
456
457 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
458         uint8_t *data;
459
460         assert(ret);
461         assert(length);
462
463         data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
464         if (!data)
465                 return -ENOMEM;
466
467         free(*ret);
468         *ret = data;
469         *length = PPPOE_TAG_LENGTH(tag);
470
471         return 0;
472 }
473
474 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
475         char *string;
476
477         assert(ret);
478
479         string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
480         if (!string)
481                 return -ENOMEM;
482
483         free(*ret);
484         *ret = string;
485
486         return 0;
487 }
488
489 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
490         struct pppoe_tag *tag;
491         int r;
492
493         assert(tags);
494
495         pppoe_tags_clear(tags);
496
497         PPPOE_TAGS_FOREACH(tag, header) {
498                 switch (PPPOE_TAG_TYPE(tag)) {
499                 case PTT_SRV_NAME:
500                         r = pppoe_tag_parse_string(tag, &tags->service_name);
501                         if (r < 0)
502                                 return r;
503
504                         break;
505                 case PTT_AC_NAME:
506                         r = pppoe_tag_parse_string(tag, &tags->ac_name);
507                         if (r < 0)
508                                 return r;
509
510                         break;
511                 case PTT_HOST_UNIQ:
512                         r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
513                         if (r < 0)
514                                 return r;
515
516                         break;
517                 case PTT_AC_COOKIE:
518                         r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
519                         if (r < 0)
520                                 return r;
521
522                         break;
523                 case PTT_SRV_ERR:
524                 case PTT_SYS_ERR:
525                 case PTT_GEN_ERR:
526                 {
527                         _cleanup_free_ char *error = NULL;
528
529                         /* TODO: do something more sensible with the error messages */
530                         r = pppoe_tag_parse_string(tag, &error);
531                         if (r < 0)
532                                 return r;
533
534                         if (strlen(error) > 0 && utf8_is_valid(error))
535                                 log_debug("PPPoE: error - '%s'", error);
536                         else
537                                 log_debug("PPPoE: error");
538
539                         break;
540                 }
541                 default:
542                         log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
543                 }
544         }
545
546         return 0;
547 }
548
549 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
550         int s;
551
552         assert(ppp);
553         assert(ppp->pppoe_fd == -1);
554
555         s = socket(AF_PPPOX, SOCK_STREAM, 0);
556         if (s < 0)
557                 return -errno;
558
559         ppp->pppoe_fd = s;
560
561         return 0;
562 }
563
564 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
565         union sockaddr_union_pppox link = {
566                 .pppox = {
567                         .sa_family = AF_PPPOX,
568                         .sa_protocol = PX_PROTO_OE,
569                 },
570         };
571         int r, channel;
572
573         assert(ppp);
574         assert(ppp->pppoe_fd != -1);
575         assert(ppp->session_id);
576         assert(ppp->ifname);
577
578         link.pppox.sa_addr.pppoe.sid = ppp->session_id;
579         memcpy(link.pppox.sa_addr.pppoe.dev, ppp->ifname, strlen(ppp->ifname));
580         memcpy(link.pppox.sa_addr.pppoe.remote, &ppp->peer_mac, ETH_ALEN);
581
582         r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
583         if (r < 0)
584                 return r;
585
586         r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
587         if (r < 0)
588                 return -errno;
589
590         ppp->channel = channel;
591
592         return 0;
593 }
594
595 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
596         int r;
597
598         assert(packet);
599
600         if (packet->ver != 0x1 || packet->type != 0x1)
601                 return 0;
602
603         r = pppoe_payload_parse(&ppp->tags, packet);
604         if (r < 0)
605                 return 0;
606
607         switch (ppp->state) {
608         case PPPOE_STATE_INITIALIZING:
609                 if (packet->code != PADO_CODE)
610                         return 0;
611
612                 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
613                     memcmp(ppp->tags.host_uniq, &ppp->host_uniq, sizeof(ppp->host_uniq)) != 0)
614                         return 0;
615
616                 log_debug("PPPoE: got OFFER (Peer: "
617                   "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
618                   "Service-Name: '%s'; AC-Name: '%s')",
619                   mac->ether_addr_octet[0],
620                   mac->ether_addr_octet[1],
621                   mac->ether_addr_octet[2],
622                   mac->ether_addr_octet[3],
623                   mac->ether_addr_octet[4],
624                   mac->ether_addr_octet[5],
625                   ppp->tags.service_name ? : "",
626                   ppp->tags.ac_name ? : "");
627
628                 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
629
630                 r = pppoe_open_pppoe_socket(ppp);
631                 if (r < 0) {
632                         log_warning("PPPoE: could not open socket");
633                         return r;
634                 }
635
636                 r = pppoe_send_request(ppp);
637                 if (r < 0)
638                         return 0;
639
640                 ppp->state = PPPOE_STATE_REQUESTING;
641
642                 break;
643         case PPPOE_STATE_REQUESTING:
644                 if (packet->code != PADS_CODE)
645                         return 0;
646
647                 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
648                     memcmp(ppp->tags.host_uniq, &ppp->host_uniq,
649                            sizeof(ppp->host_uniq)) != 0)
650                         return 0;
651
652                 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
653                         return 0;
654
655                 ppp->session_id = packet->sid;
656
657                 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
658                           be16toh(ppp->session_id));
659
660                 r = pppoe_connect_pppoe_socket(ppp);
661                 if (r < 0) {
662                         log_warning("PPPoE: could not connect socket");
663                         return r;
664                 }
665
666                 ppp->state = PPPOE_STATE_RUNNING;
667
668                 ppp->timeout = sd_event_source_unref(ppp->timeout);
669                 assert(ppp->cb);
670                 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
671
672                 break;
673         case PPPOE_STATE_RUNNING:
674                 if (packet->code != PADT_CODE)
675                         return 0;
676
677                 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
678                         return 0;
679
680                 if (ppp->session_id != packet->sid)
681                         return 0;
682
683                 log_debug("PPPoE: got TERMINATE");
684
685                 ppp->state = PPPOE_STATE_STOPPED;
686
687                 assert(ppp->cb);
688                 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
689
690                 break;
691         case PPPOE_STATE_STOPPED:
692                 break;
693         default:
694                 assert_not_reached("PPPoE: invalid state when receiving message");
695         }
696
697         return 0;
698 }
699
700 static int pppoe_receive_message(sd_event_source *s, int fd,
701                                  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,
724                        &link.sa, &addrlen);
725         if (len < 0) {
726                 log_warning("PPPoE: colud not receive message from raw socket: %s",
727                           strerror(-r));
728                 return 0;
729         } else if ((size_t)len < sizeof(struct pppoe_hdr))
730                 return 0;
731         else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
732                 return 0;
733
734         if (link.ll.sll_halen != ETH_ALEN)
735                 /* not ethernet? */
736                 return 0;
737
738         r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
739         if (r < 0)
740                 return r;
741
742         return 1;
743 }
744
745 int sd_pppoe_start(sd_pppoe *ppp) {
746         union sockaddr_union link = {
747                 .ll = {
748                         .sll_family = AF_PACKET,
749                         .sll_protocol = htons(ETH_P_PPP_DISC),
750                 },
751         };
752         _cleanup_close_ int s = -1;
753         _cleanup_event_source_unref_ sd_event_source *io = NULL;
754         int r;
755
756         assert_return(ppp, -EINVAL);
757         assert_return(ppp->fd == -1, -EBUSY);
758         assert_return(!ppp->io, -EBUSY);
759         assert_return(ppp->ifindex > 0, -EUNATCH);
760         assert_return(ppp->ifname, -EUNATCH);
761         assert_return(ppp->event, -EUNATCH);
762         assert_return(ppp->cb, -EUNATCH);
763
764         s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
765         if (s < 0)
766                 return -errno;
767
768         link.ll.sll_ifindex = ppp->ifindex;
769
770         r = bind(s, &link.sa, sizeof(link.ll));
771         if (r < 0)
772                 return r;
773
774         r = sd_event_add_io(ppp->event, &io,
775                             s, EPOLLIN, pppoe_receive_message,
776                             ppp);
777         if (r < 0)
778                 return r;
779
780         r = sd_event_source_set_priority(io, ppp->event_priority);
781         if (r < 0)
782                 return r;
783
784         ppp->fd = s;
785         s = -1;
786         ppp->io = io;
787         io = NULL;
788
789         r = pppoe_send_initiation(ppp);
790         if (r < 0)
791                 return r;
792
793         ppp->state = PPPOE_STATE_INITIALIZING;
794
795         return 0;
796 }
797
798 int sd_pppoe_stop(sd_pppoe *ppp) {
799         assert_return(ppp, -EINVAL);
800
801         if (ppp->state == PPPOE_STATE_RUNNING)
802                 pppoe_send_terminate(ppp);
803
804         ppp->io = sd_event_source_unref(ppp->io);
805         ppp->timeout = sd_event_source_unref(ppp->timeout);
806         ppp->fd = asynchronous_close(ppp->fd);
807         ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);
808
809         return 0;
810 }