chiark / gitweb /
sd-pppoe: include ppp_defs.h
[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,
702                                  uint32_t revents, void *userdata) {
703         sd_pppoe *ppp = userdata;
704         _cleanup_free_ struct pppoe_hdr *packet = NULL;
705         union sockaddr_union link = {};
706         socklen_t addrlen = sizeof(link);
707         int buflen = 0, len, r;
708
709         assert(ppp);
710         assert(fd != -1);
711
712         r = ioctl(fd, FIONREAD, &buflen);
713         if (r < 0)
714                 return r;
715
716         if (buflen < 0)
717                 /* this can't be right */
718                 return -EIO;
719
720         packet = malloc0(buflen);
721         if (!packet)
722                 return -ENOMEM;
723
724         len = recvfrom(fd, packet, buflen, 0,
725                        &link.sa, &addrlen);
726         if (len < 0) {
727                 log_warning("PPPoE: colud not receive message from raw socket: %s",
728                           strerror(-r));
729                 return 0;
730         } else if ((size_t)len < sizeof(struct pppoe_hdr))
731                 return 0;
732         else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
733                 return 0;
734
735         if (link.ll.sll_halen != ETH_ALEN)
736                 /* not ethernet? */
737                 return 0;
738
739         r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
740         if (r < 0)
741                 return r;
742
743         return 1;
744 }
745
746 int sd_pppoe_start(sd_pppoe *ppp) {
747         union sockaddr_union link = {
748                 .ll = {
749                         .sll_family = AF_PACKET,
750                         .sll_protocol = htons(ETH_P_PPP_DISC),
751                 },
752         };
753         _cleanup_close_ int s = -1;
754         _cleanup_event_source_unref_ sd_event_source *io = NULL;
755         int r;
756
757         assert_return(ppp, -EINVAL);
758         assert_return(ppp->fd == -1, -EBUSY);
759         assert_return(!ppp->io, -EBUSY);
760         assert_return(ppp->ifindex > 0, -EUNATCH);
761         assert_return(ppp->ifname, -EUNATCH);
762         assert_return(ppp->event, -EUNATCH);
763         assert_return(ppp->cb, -EUNATCH);
764
765         s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
766         if (s < 0)
767                 return -errno;
768
769         link.ll.sll_ifindex = ppp->ifindex;
770
771         r = bind(s, &link.sa, sizeof(link.ll));
772         if (r < 0)
773                 return r;
774
775         r = sd_event_add_io(ppp->event, &io,
776                             s, EPOLLIN, pppoe_receive_message,
777                             ppp);
778         if (r < 0)
779                 return r;
780
781         r = sd_event_source_set_priority(io, ppp->event_priority);
782         if (r < 0)
783                 return r;
784
785         ppp->fd = s;
786         s = -1;
787         ppp->io = io;
788         io = NULL;
789
790         r = pppoe_send_initiation(ppp);
791         if (r < 0)
792                 return r;
793
794         ppp->state = PPPOE_STATE_INITIALIZING;
795
796         return 0;
797 }
798
799 int sd_pppoe_stop(sd_pppoe *ppp) {
800         assert_return(ppp, -EINVAL);
801
802         if (ppp->state == PPPOE_STATE_RUNNING)
803                 pppoe_send_terminate(ppp);
804
805         ppp->io = sd_event_source_unref(ppp->io);
806         ppp->timeout = sd_event_source_unref(ppp->timeout);
807         ppp->fd = asynchronous_close(ppp->fd);
808         ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);
809
810         return 0;
811 }