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 unaligned_read_be16(&(tag)->tag_len)
108 #define PPPOE_TAG_TYPE(tag) \
109 htobe16(unaligned_read_be16(&(tag)->tag_type))
111 #define PPPOE_TAG_SET_LENGTH(tag, len) \
112 unaligned_write_be16(&(tag)->tag_len, len)
114 #define PPPOE_TAG_SET_TYPE(tag, len) \
115 unaligned_write_be16(&(tag)->tag_type, be16toh(len))
117 #define PPPOE_TAG_NEXT(tag) \
118 (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
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))
128 static void pppoe_tags_clear(PPPoETags *tags) {
129 free(tags->service_name);
131 free(tags->host_uniq);
137 int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
138 assert_return(ppp, -EINVAL);
139 assert_return(ifindex > 0, -EINVAL);
141 ppp->ifindex = ifindex;
146 int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
149 assert_return(ppp, -EINVAL);
150 assert_return(ifname, -EINVAL);
152 if (strlen(ifname) > IFNAMSIZ)
155 name = strdup(ifname);
165 int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
166 _cleanup_free_ char *name = NULL;
168 assert_return(ppp, -EINVAL);
171 name = strdup(service_name);
176 free(ppp->service_name);
177 ppp->service_name = name;
183 int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
186 assert_return(ppp, -EINVAL);
187 assert_return(!ppp->event, -EBUSY);
190 ppp->event = sd_event_ref(event);
192 r = sd_event_default(&ppp->event);
197 ppp->event_priority = priority;
202 int sd_pppoe_detach_event(sd_pppoe *ppp) {
203 assert_return(ppp, -EINVAL);
205 ppp->event = sd_event_unref(ppp->event);
210 sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
212 assert_se(REFCNT_INC(ppp->n_ref) >= 2);
217 sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
218 if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
219 pppoe_tags_clear(&ppp->tags);
221 free(ppp->service_name);
223 sd_pppoe_detach_event(ppp);
231 int sd_pppoe_new (sd_pppoe **ret) {
234 assert_return(ret, -EINVAL);
236 ppp = new0(sd_pppoe, 1);
240 ppp->n_ref = REFCNT_INIT;
241 ppp->state = _PPPOE_STATE_INVALID;
245 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
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);
258 *channel = ppp->channel;
263 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
264 assert_return(ppp, -EINVAL);
267 ppp->userdata = userdata;
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;
276 assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
277 assert(!(!tag_data ^ !tag_len));
279 tag = PPPOE_PACKET_TAIL(packet);
281 PPPOE_TAG_SET_LENGTH(tag, tag_len);
282 PPPOE_TAG_SET_TYPE(tag, tag_type);
284 memcpy(tag->tag_data, tag_data, tag_len);
286 packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
289 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
290 union sockaddr_union link = {
292 .sll_family = AF_PACKET,
293 .sll_protocol = htons(ETH_P_PPP_DISC),
294 .sll_halen = ETH_ALEN,
297 _cleanup_free_ struct pppoe_hdr *packet = NULL;
301 assert(ppp->fd != -1);
302 assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
304 link.ll.sll_ifindex = ppp->ifindex;
305 if (code == PADI_CODE)
306 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
308 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
310 packet = malloc0(PPPOE_MAX_PACKET_SIZE);
317 if (code == PADT_CODE)
318 packet->sid = ppp->session_id;
321 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
322 ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
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);
330 if (code != PADT_CODE) {
331 ppp->host_uniq = random_u64();
333 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
334 &ppp->host_uniq, sizeof(ppp->host_uniq));
337 r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
338 0, &link.sa, sizeof(link.ll));
345 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
347 static int pppoe_arm_timeout(sd_pppoe *ppp) {
348 _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
354 r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
356 next_timeout = now(clock_boottime_or_monotonic());
360 next_timeout += 500 * USEC_PER_MSEC;
362 r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
363 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
367 r = sd_event_source_set_priority(timeout, ppp->event_priority);
371 sd_event_source_unref(ppp->timeout);
372 ppp->timeout = timeout;
378 static int pppoe_send_initiation(sd_pppoe *ppp) {
381 r = pppoe_send(ppp, PADI_CODE);
385 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
386 ppp->service_name ? : "");
388 pppoe_arm_timeout(ppp);
393 static int pppoe_send_request(sd_pppoe *ppp) {
396 r = pppoe_send(ppp, PADR_CODE);
400 log_debug("PPPoE: sent REQUEST");
402 ppp->padr_resend_count --;
404 pppoe_arm_timeout(ppp);
409 static int pppoe_send_terminate(sd_pppoe *ppp) {
412 r = pppoe_send(ppp, PADT_CODE);
416 log_debug("PPPoE: sent TERMINATE");
421 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
422 sd_pppoe *ppp = userdata;
427 switch (ppp->state) {
428 case PPPOE_STATE_INITIALIZING:
429 r = pppoe_send_initiation(ppp);
431 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
434 case PPPOE_STATE_REQUESTING:
435 if (ppp->padr_resend_count <= 0) {
436 log_debug("PPPoE: PADR timed out, restarting PADI");
438 r = pppoe_send_initiation(ppp);
440 log_warning("PPPoE: sending PADI failed: %s", strerror(-r));
442 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
443 ppp->state = PPPOE_STATE_INITIALIZING;
445 r = pppoe_send_request(ppp);
447 log_warning("PPPoE: sending PADR failed: %s", strerror(-r));
452 assert_not_reached("timeout in invalid state");
458 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
464 data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
470 *length = PPPOE_TAG_LENGTH(tag);
475 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
480 string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
490 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
491 struct pppoe_tag *tag;
496 pppoe_tags_clear(tags);
498 PPPOE_TAGS_FOREACH(tag, header) {
499 switch (PPPOE_TAG_TYPE(tag)) {
501 r = pppoe_tag_parse_string(tag, &tags->service_name);
507 r = pppoe_tag_parse_string(tag, &tags->ac_name);
513 r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
519 r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
528 _cleanup_free_ char *error = NULL;
530 /* TODO: do something more sensible with the error messages */
531 r = pppoe_tag_parse_string(tag, &error);
535 if (strlen(error) > 0 && utf8_is_valid(error))
536 log_debug("PPPoE: error - '%s'", error);
538 log_debug("PPPoE: error");
543 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
550 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
554 assert(ppp->pppoe_fd == -1);
556 s = socket(AF_PPPOX, SOCK_STREAM, 0);
565 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
566 union sockaddr_union_pppox link = {
568 .sa_family = AF_PPPOX,
569 .sa_protocol = PX_PROTO_OE,
575 assert(ppp->pppoe_fd != -1);
576 assert(ppp->session_id);
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);
583 r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
587 r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
591 ppp->channel = channel;
596 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
601 if (packet->ver != 0x1 || packet->type != 0x1)
604 r = pppoe_payload_parse(&ppp->tags, packet);
608 switch (ppp->state) {
609 case PPPOE_STATE_INITIALIZING:
610 if (packet->code != PADO_CODE)
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)
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 ? : "");
629 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
631 r = pppoe_open_pppoe_socket(ppp);
633 log_warning("PPPoE: could not open socket");
637 r = pppoe_send_request(ppp);
641 ppp->state = PPPOE_STATE_REQUESTING;
644 case PPPOE_STATE_REQUESTING:
645 if (packet->code != PADS_CODE)
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)
653 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
656 ppp->session_id = packet->sid;
658 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
659 be16toh(ppp->session_id));
661 r = pppoe_connect_pppoe_socket(ppp);
663 log_warning("PPPoE: could not connect socket");
667 ppp->state = PPPOE_STATE_RUNNING;
669 ppp->timeout = sd_event_source_unref(ppp->timeout);
671 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
674 case PPPOE_STATE_RUNNING:
675 if (packet->code != PADT_CODE)
678 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
681 if (ppp->session_id != packet->sid)
684 log_debug("PPPoE: got TERMINATE");
686 ppp->state = PPPOE_STATE_STOPPED;
689 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
692 case PPPOE_STATE_STOPPED:
695 assert_not_reached("PPPoE: invalid state when receiving message");
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;
712 r = ioctl(fd, FIONREAD, &buflen);
717 /* this can't be right */
720 packet = malloc0(buflen);
724 len = recvfrom(fd, packet, buflen, 0,
727 log_warning("PPPoE: colud not receive message from raw socket: %s",
730 } else if ((size_t)len < sizeof(struct pppoe_hdr))
732 else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
735 if (link.ll.sll_halen != ETH_ALEN)
739 r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
746 int sd_pppoe_start(sd_pppoe *ppp) {
747 union sockaddr_union link = {
749 .sll_family = AF_PACKET,
750 .sll_protocol = htons(ETH_P_PPP_DISC),
753 _cleanup_close_ int s = -1;
754 _cleanup_event_source_unref_ sd_event_source *io = NULL;
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);
765 s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
769 link.ll.sll_ifindex = ppp->ifindex;
771 r = bind(s, &link.sa, sizeof(link.ll));
775 r = sd_event_add_io(ppp->event, &io,
776 s, EPOLLIN, pppoe_receive_message,
781 r = sd_event_source_set_priority(io, ppp->event_priority);
790 r = pppoe_send_initiation(ppp);
794 ppp->state = PPPOE_STATE_INITIALIZING;
799 int sd_pppoe_stop(sd_pppoe *ppp) {
800 assert_return(ppp, -EINVAL);
802 if (ppp->state == PPPOE_STATE_RUNNING)
803 pppoe_send_terminate(ppp);
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);