1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2014 Tom Gundersen
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.
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.
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/>.
24 #include <sys/ioctl.h>
25 #include <linux/ppp-ioctl.h>
27 #include <netinet/in.h>
28 #include <linux/if_pppox.h>
32 #include "event-util.h"
35 #include "socket-util.h"
38 #include "unaligned.h"
41 #define PPPOE_MAX_PACKET_SIZE 1484
42 #define PPPOE_MAX_PADR_RESEND 16
44 /* TODO: move this to socket-util.h without getting into
45 * a mess with the includes */
46 union sockaddr_union_pppox {
48 struct sockaddr_pppox pppox;
51 typedef enum PPPoEState {
52 PPPOE_STATE_INITIALIZING,
53 PPPOE_STATE_REQUESTING,
57 _PPPOE_STATE_INVALID = -1,
60 typedef struct PPPoETags {
82 sd_event_source *timeout;
83 int padr_resend_count;
86 struct ether_addr peer_mac;
98 #define PPPOE_PACKET_LENGTH(header) \
99 be16toh((header)->length)
101 #define PPPOE_PACKET_TAIL(packet) \
102 (struct pppoe_tag *)((uint8_t*)(packet) + sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
104 #define PPPOE_TAG_LENGTH(tag) \
105 unaligned_read_be16(&(tag)->tag_len)
107 #define PPPOE_TAG_TYPE(tag) \
108 htobe16(unaligned_read_be16(&(tag)->tag_type))
110 #define PPPOE_TAG_SET_LENGTH(tag, len) \
111 unaligned_write_be16(&(tag)->tag_len, len)
113 #define PPPOE_TAG_SET_TYPE(tag, len) \
114 unaligned_write_be16(&(tag)->tag_type, be16toh(len))
116 #define PPPOE_TAG_NEXT(tag) \
117 (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
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))
127 static void pppoe_tags_clear(PPPoETags *tags) {
128 free(tags->service_name);
130 free(tags->host_uniq);
136 int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
137 assert_return(ppp, -EINVAL);
138 assert_return(ifindex > 0, -EINVAL);
140 ppp->ifindex = ifindex;
145 int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
148 assert_return(ppp, -EINVAL);
149 assert_return(ifname, -EINVAL);
151 if (strlen(ifname) > IFNAMSIZ)
154 name = strdup(ifname);
164 int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
165 _cleanup_free_ char *name = NULL;
167 assert_return(ppp, -EINVAL);
170 name = strdup(service_name);
175 free(ppp->service_name);
176 ppp->service_name = name;
182 int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
185 assert_return(ppp, -EINVAL);
186 assert_return(!ppp->event, -EBUSY);
189 ppp->event = sd_event_ref(event);
191 r = sd_event_default(&ppp->event);
196 ppp->event_priority = priority;
201 int sd_pppoe_detach_event(sd_pppoe *ppp) {
202 assert_return(ppp, -EINVAL);
204 ppp->event = sd_event_unref(ppp->event);
209 sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
211 assert_se(REFCNT_INC(ppp->n_ref) >= 2);
216 sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
217 if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
218 pppoe_tags_clear(&ppp->tags);
220 sd_pppoe_detach_event(ppp);
228 int sd_pppoe_new (sd_pppoe **ret) {
231 assert_return(ret, -EINVAL);
233 ppp = new0(sd_pppoe, 1);
237 ppp->n_ref = REFCNT_INIT;
238 ppp->state = _PPPOE_STATE_INVALID;
242 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
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);
255 *channel = ppp->channel;
260 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
261 assert_return(ppp, -EINVAL);
264 ppp->userdata = userdata;
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;
273 assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
274 assert(!(!tag_data ^ !tag_len));
276 tag = PPPOE_PACKET_TAIL(packet);
278 PPPOE_TAG_SET_LENGTH(tag, tag_len);
279 PPPOE_TAG_SET_TYPE(tag, tag_type);
281 memcpy(tag->tag_data, tag_data, tag_len);
283 packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
286 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
287 union sockaddr_union link = {
289 .sll_family = AF_PACKET,
290 .sll_protocol = htons(ETH_P_PPP_DISC),
291 .sll_halen = ETH_ALEN,
294 _cleanup_free_ struct pppoe_hdr *packet = NULL;
298 assert(ppp->fd != -1);
299 assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
301 link.ll.sll_ifindex = ppp->ifindex;
302 if (code == PADI_CODE)
303 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
305 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
307 packet = malloc0(PPPOE_MAX_PACKET_SIZE);
314 if (code == PADT_CODE)
315 packet->sid = ppp->session_id;
318 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
319 ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
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);
327 if (code != PADT_CODE) {
328 ppp->host_uniq = random_u64();
330 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
331 &ppp->host_uniq, sizeof(ppp->host_uniq));
334 r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
335 0, &link.sa, sizeof(link.ll));
342 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
344 static int pppoe_arm_timeout(sd_pppoe *ppp) {
345 _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
351 r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
353 next_timeout = now(clock_boottime_or_monotonic());
357 next_timeout += 500 * USEC_PER_MSEC;
359 r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
360 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
364 r = sd_event_source_set_priority(timeout, ppp->event_priority);
368 sd_event_source_unref(ppp->timeout);
369 ppp->timeout = timeout;
375 static int pppoe_send_initiation(sd_pppoe *ppp) {
378 r = pppoe_send(ppp, PADI_CODE);
382 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
383 ppp->service_name ? : "");
385 pppoe_arm_timeout(ppp);
390 static int pppoe_send_request(sd_pppoe *ppp) {
393 r = pppoe_send(ppp, PADR_CODE);
397 log_debug("PPPoE: sent REQUEST");
399 ppp->padr_resend_count --;
401 pppoe_arm_timeout(ppp);
406 static int pppoe_send_terminate(sd_pppoe *ppp) {
409 r = pppoe_send(ppp, PADT_CODE);
413 log_debug("PPPoE: sent TERMINATE");
418 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
419 sd_pppoe *ppp = userdata;
424 switch (ppp->state) {
425 case PPPOE_STATE_INITIALIZING:
426 r = pppoe_send_initiation(ppp);
428 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
431 case PPPOE_STATE_REQUESTING:
432 if (ppp->padr_resend_count <= 0) {
433 log_debug("PPPoE: PADR timed out, restarting PADI");
435 r = pppoe_send_initiation(ppp);
437 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
439 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
440 ppp->state = PPPOE_STATE_INITIALIZING;
442 r = pppoe_send_request(ppp);
444 log_warning("PPPoE: sending PADR failed: %s", strerror(-r));
449 assert_not_reached("timeout in invalid state");
455 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
461 data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
467 *length = PPPOE_TAG_LENGTH(tag);
472 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
477 string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
487 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
488 struct pppoe_tag *tag;
493 pppoe_tags_clear(tags);
495 PPPOE_TAGS_FOREACH(tag, header) {
496 switch (PPPOE_TAG_TYPE(tag)) {
498 r = pppoe_tag_parse_string(tag, &tags->service_name);
504 r = pppoe_tag_parse_string(tag, &tags->ac_name);
510 r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
516 r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
525 _cleanup_free_ char *error = NULL;
527 /* TODO: do something more sensible with the error messages */
528 r = pppoe_tag_parse_string(tag, &error);
532 if (strlen(error) > 0 && utf8_is_valid(error))
533 log_debug("PPPoE: error - '%s'", error);
535 log_debug("PPPoE: error");
540 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
547 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
551 assert(ppp->pppoe_fd == -1);
553 s = socket(AF_PPPOX, SOCK_STREAM, 0);
562 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
563 union sockaddr_union_pppox link = {
565 .sa_family = AF_PPPOX,
566 .sa_protocol = PX_PROTO_OE,
572 assert(ppp->pppoe_fd != -1);
573 assert(ppp->session_id);
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);
580 r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
584 r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
588 ppp->channel = channel;
593 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
598 if (packet->ver != 0x1 || packet->type != 0x1)
601 r = pppoe_payload_parse(&ppp->tags, packet);
605 switch (ppp->state) {
606 case PPPOE_STATE_INITIALIZING:
607 if (packet->code != PADO_CODE)
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)
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 ? : "");
626 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
628 r = pppoe_open_pppoe_socket(ppp);
630 log_warning("PPPoE: could not open socket");
634 r = pppoe_send_request(ppp);
638 ppp->state = PPPOE_STATE_REQUESTING;
641 case PPPOE_STATE_REQUESTING:
642 if (packet->code != PADS_CODE)
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)
650 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
653 ppp->session_id = packet->sid;
655 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
656 be16toh(ppp->session_id));
658 r = pppoe_connect_pppoe_socket(ppp);
660 log_warning("PPPoE: could not connect socket");
664 ppp->state = PPPOE_STATE_RUNNING;
666 ppp->timeout = sd_event_source_unref(ppp->timeout);
668 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
671 case PPPOE_STATE_RUNNING:
672 if (packet->code != PADT_CODE)
675 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
678 if (ppp->session_id != packet->sid)
681 log_debug("PPPoE: got TERMINATE");
683 ppp->state = PPPOE_STATE_STOPPED;
686 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
689 case PPPOE_STATE_STOPPED:
692 assert_not_reached("PPPoE: invalid state when receiving message");
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;
709 r = ioctl(fd, FIONREAD, &buflen);
714 /* this can't be right */
717 packet = malloc0(buflen);
721 len = recvfrom(fd, packet, buflen, 0,
724 log_warning("PPPoE: colud not receive message from raw socket: %s",
727 } else if ((size_t)len < sizeof(struct pppoe_hdr))
729 else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
732 if (link.ll.sll_halen != ETH_ALEN)
736 r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
743 int sd_pppoe_start(sd_pppoe *ppp) {
744 union sockaddr_union link = {
746 .sll_family = AF_PACKET,
747 .sll_protocol = htons(ETH_P_PPP_DISC),
750 _cleanup_close_ int s = -1;
751 _cleanup_event_source_unref_ sd_event_source *io = NULL;
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);
762 s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
766 link.ll.sll_ifindex = ppp->ifindex;
768 r = bind(s, &link.sa, sizeof(link.ll));
772 r = sd_event_add_io(ppp->event, &io,
773 s, EPOLLIN, pppoe_receive_message,
778 r = sd_event_source_set_priority(io, ppp->event_priority);
787 r = pppoe_send_initiation(ppp);
791 ppp->state = PPPOE_STATE_INITIALIZING;
796 int sd_pppoe_stop(sd_pppoe *ppp) {
797 assert_return(ppp, -EINVAL);
799 if (ppp->state == PPPOE_STATE_RUNNING)
800 pppoe_send_terminate(ppp);
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);