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 free(ppp->service_name);
222 sd_pppoe_detach_event(ppp);
230 int sd_pppoe_new (sd_pppoe **ret) {
233 assert_return(ret, -EINVAL);
235 ppp = new0(sd_pppoe, 1);
239 ppp->n_ref = REFCNT_INIT;
240 ppp->state = _PPPOE_STATE_INVALID;
244 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
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);
257 *channel = ppp->channel;
262 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
263 assert_return(ppp, -EINVAL);
266 ppp->userdata = userdata;
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;
275 assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
276 assert(!(!tag_data ^ !tag_len));
278 tag = PPPOE_PACKET_TAIL(packet);
280 PPPOE_TAG_SET_LENGTH(tag, tag_len);
281 PPPOE_TAG_SET_TYPE(tag, tag_type);
283 memcpy(tag->tag_data, tag_data, tag_len);
285 packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
288 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
289 union sockaddr_union link = {
291 .sll_family = AF_PACKET,
292 .sll_protocol = htons(ETH_P_PPP_DISC),
293 .sll_halen = ETH_ALEN,
296 _cleanup_free_ struct pppoe_hdr *packet = NULL;
300 assert(ppp->fd != -1);
301 assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
303 link.ll.sll_ifindex = ppp->ifindex;
304 if (code == PADI_CODE)
305 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
307 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
309 packet = malloc0(PPPOE_MAX_PACKET_SIZE);
316 if (code == PADT_CODE)
317 packet->sid = ppp->session_id;
320 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
321 ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
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);
329 if (code != PADT_CODE) {
330 ppp->host_uniq = random_u64();
332 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
333 &ppp->host_uniq, sizeof(ppp->host_uniq));
336 r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
337 0, &link.sa, sizeof(link.ll));
344 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
346 static int pppoe_arm_timeout(sd_pppoe *ppp) {
347 _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
353 r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
355 next_timeout = now(clock_boottime_or_monotonic());
359 next_timeout += 500 * USEC_PER_MSEC;
361 r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
362 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
366 r = sd_event_source_set_priority(timeout, ppp->event_priority);
370 sd_event_source_unref(ppp->timeout);
371 ppp->timeout = timeout;
377 static int pppoe_send_initiation(sd_pppoe *ppp) {
380 r = pppoe_send(ppp, PADI_CODE);
384 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
385 ppp->service_name ? : "");
387 pppoe_arm_timeout(ppp);
392 static int pppoe_send_request(sd_pppoe *ppp) {
395 r = pppoe_send(ppp, PADR_CODE);
399 log_debug("PPPoE: sent REQUEST");
401 ppp->padr_resend_count --;
403 pppoe_arm_timeout(ppp);
408 static int pppoe_send_terminate(sd_pppoe *ppp) {
411 r = pppoe_send(ppp, PADT_CODE);
415 log_debug("PPPoE: sent TERMINATE");
420 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
421 sd_pppoe *ppp = userdata;
426 switch (ppp->state) {
427 case PPPOE_STATE_INITIALIZING:
428 r = pppoe_send_initiation(ppp);
430 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
433 case PPPOE_STATE_REQUESTING:
434 if (ppp->padr_resend_count <= 0) {
435 log_debug("PPPoE: PADR timed out, restarting PADI");
437 r = pppoe_send_initiation(ppp);
439 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
441 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
442 ppp->state = PPPOE_STATE_INITIALIZING;
444 r = pppoe_send_request(ppp);
446 log_warning("PPPoE: sending PADR failed: %s", strerror(-r));
451 assert_not_reached("timeout in invalid state");
457 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
463 data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
469 *length = PPPOE_TAG_LENGTH(tag);
474 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
479 string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
489 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
490 struct pppoe_tag *tag;
495 pppoe_tags_clear(tags);
497 PPPOE_TAGS_FOREACH(tag, header) {
498 switch (PPPOE_TAG_TYPE(tag)) {
500 r = pppoe_tag_parse_string(tag, &tags->service_name);
506 r = pppoe_tag_parse_string(tag, &tags->ac_name);
512 r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
518 r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
527 _cleanup_free_ char *error = NULL;
529 /* TODO: do something more sensible with the error messages */
530 r = pppoe_tag_parse_string(tag, &error);
534 if (strlen(error) > 0 && utf8_is_valid(error))
535 log_debug("PPPoE: error - '%s'", error);
537 log_debug("PPPoE: error");
542 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
549 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
553 assert(ppp->pppoe_fd == -1);
555 s = socket(AF_PPPOX, SOCK_STREAM, 0);
564 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
565 union sockaddr_union_pppox link = {
567 .sa_family = AF_PPPOX,
568 .sa_protocol = PX_PROTO_OE,
574 assert(ppp->pppoe_fd != -1);
575 assert(ppp->session_id);
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);
582 r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
586 r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
590 ppp->channel = channel;
595 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
600 if (packet->ver != 0x1 || packet->type != 0x1)
603 r = pppoe_payload_parse(&ppp->tags, packet);
607 switch (ppp->state) {
608 case PPPOE_STATE_INITIALIZING:
609 if (packet->code != PADO_CODE)
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)
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 ? : "");
628 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
630 r = pppoe_open_pppoe_socket(ppp);
632 log_warning("PPPoE: could not open socket");
636 r = pppoe_send_request(ppp);
640 ppp->state = PPPOE_STATE_REQUESTING;
643 case PPPOE_STATE_REQUESTING:
644 if (packet->code != PADS_CODE)
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)
652 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
655 ppp->session_id = packet->sid;
657 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
658 be16toh(ppp->session_id));
660 r = pppoe_connect_pppoe_socket(ppp);
662 log_warning("PPPoE: could not connect socket");
666 ppp->state = PPPOE_STATE_RUNNING;
668 ppp->timeout = sd_event_source_unref(ppp->timeout);
670 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
673 case PPPOE_STATE_RUNNING:
674 if (packet->code != PADT_CODE)
677 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
680 if (ppp->session_id != packet->sid)
683 log_debug("PPPoE: got TERMINATE");
685 ppp->state = PPPOE_STATE_STOPPED;
688 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
691 case PPPOE_STATE_STOPPED:
694 assert_not_reached("PPPoE: invalid state when receiving message");
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;
711 r = ioctl(fd, FIONREAD, &buflen);
716 /* this can't be right */
719 packet = malloc0(buflen);
723 len = recvfrom(fd, packet, buflen, 0,
726 log_warning("PPPoE: colud not receive message from raw socket: %s",
729 } else if ((size_t)len < sizeof(struct pppoe_hdr))
731 else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
734 if (link.ll.sll_halen != ETH_ALEN)
738 r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
745 int sd_pppoe_start(sd_pppoe *ppp) {
746 union sockaddr_union link = {
748 .sll_family = AF_PACKET,
749 .sll_protocol = htons(ETH_P_PPP_DISC),
752 _cleanup_close_ int s = -1;
753 _cleanup_event_source_unref_ sd_event_source *io = NULL;
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);
764 s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
768 link.ll.sll_ifindex = ppp->ifindex;
770 r = bind(s, &link.sa, sizeof(link.ll));
774 r = sd_event_add_io(ppp->event, &io,
775 s, EPOLLIN, pppoe_receive_message,
780 r = sd_event_source_set_priority(io, ppp->event_priority);
789 r = pppoe_send_initiation(ppp);
793 ppp->state = PPPOE_STATE_INITIALIZING;
798 int sd_pppoe_stop(sd_pppoe *ppp) {
799 assert_return(ppp, -EINVAL);
801 if (ppp->state == PPPOE_STATE_RUNNING)
802 pppoe_send_terminate(ppp);
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);