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_defs.h>
26 #include <linux/ppp-ioctl.h>
28 #include <netinet/in.h>
29 #include <linux/if_pppox.h>
33 #include "event-util.h"
36 #include "socket-util.h"
39 #include "unaligned.h"
42 #define PPPOE_MAX_PACKET_SIZE 1484
43 #define PPPOE_MAX_PADR_RESEND 16
45 /* TODO: move this to socket-util.h without getting into
46 * a mess with the includes */
47 union sockaddr_union_pppox {
49 struct sockaddr_pppox pppox;
52 typedef enum PPPoEState {
53 PPPOE_STATE_INITIALIZING,
54 PPPOE_STATE_REQUESTING,
58 _PPPOE_STATE_INVALID = -1,
61 typedef struct PPPoETags {
83 sd_event_source *timeout;
84 int padr_resend_count;
87 struct ether_addr peer_mac;
99 #define PPPOE_PACKET_LENGTH(header) \
100 be16toh((header)->length)
102 #define PPPOE_PACKET_TAIL(packet) \
103 (struct pppoe_tag*)((uint8_t*)(packet) + sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
105 #define PPPOE_TAG_LENGTH(tag) \
106 be16toh((tag)->tag_len)
108 #define PPPOE_TAG_TYPE(tag) \
111 #define PPPOE_TAG_NEXT(tag) \
112 (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
114 #define PPPOE_TAGS_FOREACH(tag, header) \
115 for (tag = (header)->tag; \
116 ((uint8_t *)(tag) + sizeof(struct pppoe_tag) < (uint8_t*)PPPOE_PACKET_TAIL(header)) && \
117 (PPPOE_TAG_NEXT(tag) <= PPPOE_PACKET_TAIL(header)) && \
118 (tag >= (header)->tag) && \
119 (PPPOE_TAG_TYPE(tag) != PTT_EOL); \
120 tag = PPPOE_TAG_NEXT(tag))
122 static void pppoe_tags_clear(PPPoETags *tags) {
123 free(tags->service_name);
125 free(tags->host_uniq);
131 int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
132 assert_return(ppp, -EINVAL);
133 assert_return(ifindex > 0, -EINVAL);
135 ppp->ifindex = ifindex;
140 int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
143 assert_return(ppp, -EINVAL);
144 assert_return(ifname, -EINVAL);
146 if (strlen(ifname) > IFNAMSIZ)
149 name = strdup(ifname);
159 int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
160 _cleanup_free_ char *name = NULL;
162 assert_return(ppp, -EINVAL);
165 name = strdup(service_name);
170 free(ppp->service_name);
171 ppp->service_name = name;
177 int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
180 assert_return(ppp, -EINVAL);
181 assert_return(!ppp->event, -EBUSY);
184 ppp->event = sd_event_ref(event);
186 r = sd_event_default(&ppp->event);
191 ppp->event_priority = priority;
196 int sd_pppoe_detach_event(sd_pppoe *ppp) {
197 assert_return(ppp, -EINVAL);
199 ppp->event = sd_event_unref(ppp->event);
204 sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
206 assert_se(REFCNT_INC(ppp->n_ref) >= 2);
211 sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
212 if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
213 pppoe_tags_clear(&ppp->tags);
215 free(ppp->service_name);
217 sd_pppoe_detach_event(ppp);
225 int sd_pppoe_new (sd_pppoe **ret) {
228 assert_return(ret, -EINVAL);
230 ppp = new0(sd_pppoe, 1);
234 ppp->n_ref = REFCNT_INIT;
235 ppp->state = _PPPOE_STATE_INVALID;
239 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
246 int sd_pppoe_get_channel(sd_pppoe *ppp, int *channel) {
247 assert_return(ppp, -EINVAL);
248 assert_return(channel, -EINVAL);
249 assert_return(ppp->pppoe_fd != -1, -EUNATCH);
250 assert_return(ppp->state == PPPOE_STATE_RUNNING, -EUNATCH);
252 *channel = ppp->channel;
257 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
258 assert_return(ppp, -EINVAL);
261 ppp->userdata = userdata;
266 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) {
267 struct pppoe_tag *tag;
270 assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
271 assert(!(!tag_data ^ !tag_len));
273 tag = PPPOE_PACKET_TAIL(packet);
275 tag->tag_len = htobe16(tag_len);
276 tag->tag_type = tag_type;
278 memcpy(tag->tag_data, tag_data, tag_len);
280 packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
283 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
284 union sockaddr_union link = {
286 .sll_family = AF_PACKET,
287 .sll_protocol = htons(ETH_P_PPP_DISC),
288 .sll_halen = ETH_ALEN,
291 _cleanup_free_ struct pppoe_hdr *packet = NULL;
295 assert(ppp->fd != -1);
296 assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
298 link.ll.sll_ifindex = ppp->ifindex;
299 if (code == PADI_CODE)
300 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
302 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
304 packet = malloc0(PPPOE_MAX_PACKET_SIZE);
311 if (code == PADT_CODE)
312 packet->sid = ppp->session_id;
315 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
316 ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
319 if (code == PADR_CODE && ppp->tags.cookie)
320 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE,
321 ppp->tags.cookie, ppp->tags.cookie_len);
324 if (code != PADT_CODE) {
325 ppp->host_uniq = random_u64();
327 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
328 &ppp->host_uniq, sizeof(ppp->host_uniq));
331 r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
332 0, &link.sa, sizeof(link.ll));
339 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
341 static int pppoe_arm_timeout(sd_pppoe *ppp) {
342 _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
348 r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
350 next_timeout = now(clock_boottime_or_monotonic());
354 next_timeout += 500 * USEC_PER_MSEC;
356 r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
357 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
361 r = sd_event_source_set_priority(timeout, ppp->event_priority);
365 sd_event_source_unref(ppp->timeout);
366 ppp->timeout = timeout;
372 static int pppoe_send_initiation(sd_pppoe *ppp) {
375 r = pppoe_send(ppp, PADI_CODE);
379 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
380 ppp->service_name ? : "");
382 pppoe_arm_timeout(ppp);
387 static int pppoe_send_request(sd_pppoe *ppp) {
390 r = pppoe_send(ppp, PADR_CODE);
394 log_debug("PPPoE: sent REQUEST");
396 ppp->padr_resend_count --;
398 pppoe_arm_timeout(ppp);
403 static int pppoe_send_terminate(sd_pppoe *ppp) {
406 r = pppoe_send(ppp, PADT_CODE);
410 log_debug("PPPoE: sent TERMINATE");
415 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
416 sd_pppoe *ppp = userdata;
421 switch (ppp->state) {
422 case PPPOE_STATE_INITIALIZING:
423 r = pppoe_send_initiation(ppp);
425 log_warning_errno(r, "PPPoE: sending PADI failed: %m");
428 case PPPOE_STATE_REQUESTING:
429 if (ppp->padr_resend_count <= 0) {
430 log_debug("PPPoE: PADR timed out, restarting PADI");
432 r = pppoe_send_initiation(ppp);
434 log_warning_errno(r, "PPPoE: sending PADI failed: %m");
436 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
437 ppp->state = PPPOE_STATE_INITIALIZING;
439 r = pppoe_send_request(ppp);
441 log_warning_errno(r, "PPPoE: sending PADR failed: %m");
446 assert_not_reached("timeout in invalid state");
452 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
458 data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
464 *length = PPPOE_TAG_LENGTH(tag);
469 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
474 string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
484 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
485 struct pppoe_tag *tag;
490 pppoe_tags_clear(tags);
492 PPPOE_TAGS_FOREACH(tag, header) {
493 switch (PPPOE_TAG_TYPE(tag)) {
495 r = pppoe_tag_parse_string(tag, &tags->service_name);
501 r = pppoe_tag_parse_string(tag, &tags->ac_name);
507 r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
513 r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
522 _cleanup_free_ char *error = NULL;
524 /* TODO: do something more sensible with the error messages */
525 r = pppoe_tag_parse_string(tag, &error);
529 if (strlen(error) > 0 && utf8_is_valid(error))
530 log_debug("PPPoE: error - '%s'", error);
532 log_debug("PPPoE: error");
537 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
544 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
548 assert(ppp->pppoe_fd == -1);
550 s = socket(AF_PPPOX, SOCK_STREAM, 0);
559 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
560 union sockaddr_union_pppox link = {
562 .sa_family = AF_PPPOX,
563 .sa_protocol = PX_PROTO_OE,
569 assert(ppp->pppoe_fd != -1);
570 assert(ppp->session_id);
573 link.pppox.sa_addr.pppoe.sid = ppp->session_id;
574 memcpy(link.pppox.sa_addr.pppoe.dev, ppp->ifname, strlen(ppp->ifname));
575 memcpy(link.pppox.sa_addr.pppoe.remote, &ppp->peer_mac, ETH_ALEN);
577 r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
581 r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
585 ppp->channel = channel;
590 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
595 if (packet->ver != 0x1 || packet->type != 0x1)
598 r = pppoe_payload_parse(&ppp->tags, packet);
602 switch (ppp->state) {
603 case PPPOE_STATE_INITIALIZING:
604 if (packet->code != PADO_CODE)
607 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
608 memcmp(ppp->tags.host_uniq, &ppp->host_uniq, sizeof(ppp->host_uniq)) != 0)
611 log_debug("PPPoE: got OFFER (Peer: "
612 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
613 "Service-Name: '%s'; AC-Name: '%s')",
614 mac->ether_addr_octet[0],
615 mac->ether_addr_octet[1],
616 mac->ether_addr_octet[2],
617 mac->ether_addr_octet[3],
618 mac->ether_addr_octet[4],
619 mac->ether_addr_octet[5],
620 ppp->tags.service_name ? : "",
621 ppp->tags.ac_name ? : "");
623 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
625 r = pppoe_open_pppoe_socket(ppp);
627 log_warning("PPPoE: could not open socket");
631 r = pppoe_send_request(ppp);
635 ppp->state = PPPOE_STATE_REQUESTING;
638 case PPPOE_STATE_REQUESTING:
639 if (packet->code != PADS_CODE)
642 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
643 memcmp(ppp->tags.host_uniq, &ppp->host_uniq,
644 sizeof(ppp->host_uniq)) != 0)
647 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
650 ppp->session_id = packet->sid;
652 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
653 be16toh(ppp->session_id));
655 r = pppoe_connect_pppoe_socket(ppp);
657 log_warning("PPPoE: could not connect socket");
661 ppp->state = PPPOE_STATE_RUNNING;
663 ppp->timeout = sd_event_source_unref(ppp->timeout);
665 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
668 case PPPOE_STATE_RUNNING:
669 if (packet->code != PADT_CODE)
672 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
675 if (ppp->session_id != packet->sid)
678 log_debug("PPPoE: got TERMINATE");
680 ppp->state = PPPOE_STATE_STOPPED;
683 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
686 case PPPOE_STATE_STOPPED:
689 assert_not_reached("PPPoE: invalid state when receiving message");
695 static int pppoe_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
696 sd_pppoe *ppp = userdata;
697 _cleanup_free_ struct pppoe_hdr *packet = NULL;
698 union sockaddr_union link = {};
699 socklen_t addrlen = sizeof(link);
700 int buflen = 0, len, r;
705 r = ioctl(fd, FIONREAD, &buflen);
710 /* this can't be right */
713 packet = malloc0(buflen);
717 len = recvfrom(fd, packet, buflen, 0, &link.sa, &addrlen);
719 log_warning_errno(r, "PPPoE: could not receive message from raw socket: %m");
721 } else if ((size_t)len < sizeof(struct pppoe_hdr))
723 else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
726 if (link.ll.sll_halen != ETH_ALEN)
730 r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
737 int sd_pppoe_start(sd_pppoe *ppp) {
738 union sockaddr_union link = {
740 .sll_family = AF_PACKET,
741 .sll_protocol = htons(ETH_P_PPP_DISC),
744 _cleanup_close_ int s = -1;
745 _cleanup_event_source_unref_ sd_event_source *io = NULL;
748 assert_return(ppp, -EINVAL);
749 assert_return(ppp->fd == -1, -EBUSY);
750 assert_return(!ppp->io, -EBUSY);
751 assert_return(ppp->ifindex > 0, -EUNATCH);
752 assert_return(ppp->ifname, -EUNATCH);
753 assert_return(ppp->event, -EUNATCH);
754 assert_return(ppp->cb, -EUNATCH);
756 s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
760 link.ll.sll_ifindex = ppp->ifindex;
762 r = bind(s, &link.sa, sizeof(link.ll));
766 r = sd_event_add_io(ppp->event, &io,
767 s, EPOLLIN, pppoe_receive_message,
772 r = sd_event_source_set_priority(io, ppp->event_priority);
781 r = pppoe_send_initiation(ppp);
785 ppp->state = PPPOE_STATE_INITIALIZING;
790 int sd_pppoe_stop(sd_pppoe *ppp) {
791 assert_return(ppp, -EINVAL);
793 if (ppp->state == PPPOE_STATE_RUNNING)
794 pppoe_send_terminate(ppp);
796 ppp->io = sd_event_source_unref(ppp->io);
797 ppp->timeout = sd_event_source_unref(ppp->timeout);
798 ppp->fd = asynchronous_close(ppp->fd);
799 ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);