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"
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 be16toh((tag)->tag_len)
107 #define PPPOE_TAG_TYPE(tag) \
110 #define PPPOE_TAG_NEXT(tag) \
111 (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
113 #define PPPOE_TAGS_FOREACH(tag, header) \
114 for (tag = (header)->tag; \
115 ((uint8_t *)(tag) + sizeof(struct pppoe_tag) < (uint8_t*)PPPOE_PACKET_TAIL(header)) && \
116 (PPPOE_TAG_NEXT(tag) <= PPPOE_PACKET_TAIL(header)) && \
117 (tag >= (header)->tag) && \
118 (PPPOE_TAG_TYPE(tag) != PTT_EOL); \
119 tag = PPPOE_TAG_NEXT(tag))
121 static void pppoe_tags_clear(PPPoETags *tags) {
122 free(tags->service_name);
124 free(tags->host_uniq);
130 int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
131 assert_return(ppp, -EINVAL);
132 assert_return(ifindex > 0, -EINVAL);
134 ppp->ifindex = ifindex;
139 int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
142 assert_return(ppp, -EINVAL);
143 assert_return(ifname, -EINVAL);
145 if (strlen(ifname) > IFNAMSIZ)
148 name = strdup(ifname);
158 int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
159 _cleanup_free_ char *name = NULL;
161 assert_return(ppp, -EINVAL);
164 name = strdup(service_name);
169 free(ppp->service_name);
170 ppp->service_name = name;
176 int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
179 assert_return(ppp, -EINVAL);
180 assert_return(!ppp->event, -EBUSY);
183 ppp->event = sd_event_ref(event);
185 r = sd_event_default(&ppp->event);
190 ppp->event_priority = priority;
195 int sd_pppoe_detach_event(sd_pppoe *ppp) {
196 assert_return(ppp, -EINVAL);
198 ppp->event = sd_event_unref(ppp->event);
203 sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
205 assert_se(REFCNT_INC(ppp->n_ref) >= 2);
210 sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
211 if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
212 pppoe_tags_clear(&ppp->tags);
214 free(ppp->service_name);
216 sd_pppoe_detach_event(ppp);
224 int sd_pppoe_new (sd_pppoe **ret) {
227 assert_return(ret, -EINVAL);
229 ppp = new0(sd_pppoe, 1);
233 ppp->n_ref = REFCNT_INIT;
234 ppp->state = _PPPOE_STATE_INVALID;
238 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
245 int sd_pppoe_get_channel(sd_pppoe *ppp, int *channel) {
246 assert_return(ppp, -EINVAL);
247 assert_return(channel, -EINVAL);
248 assert_return(ppp->pppoe_fd != -1, -EUNATCH);
249 assert_return(ppp->state == PPPOE_STATE_RUNNING, -EUNATCH);
251 *channel = ppp->channel;
256 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
257 assert_return(ppp, -EINVAL);
260 ppp->userdata = userdata;
265 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) {
266 struct pppoe_tag *tag;
269 assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
270 assert(!(!tag_data ^ !tag_len));
272 tag = PPPOE_PACKET_TAIL(packet);
274 tag->tag_len = htobe16(tag_len);
275 tag->tag_type = tag_type;
277 memcpy(tag->tag_data, tag_data, tag_len);
279 packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
282 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
283 union sockaddr_union link = {
285 .sll_family = AF_PACKET,
286 .sll_protocol = htons(ETH_P_PPP_DISC),
287 .sll_halen = ETH_ALEN,
290 _cleanup_free_ struct pppoe_hdr *packet = NULL;
294 assert(ppp->fd != -1);
295 assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
297 link.ll.sll_ifindex = ppp->ifindex;
298 if (code == PADI_CODE)
299 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
301 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
303 packet = malloc0(PPPOE_MAX_PACKET_SIZE);
310 if (code == PADT_CODE)
311 packet->sid = ppp->session_id;
314 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
315 ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
318 if (code == PADR_CODE && ppp->tags.cookie)
319 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE,
320 ppp->tags.cookie, ppp->tags.cookie_len);
323 if (code != PADT_CODE) {
324 ppp->host_uniq = random_u64();
326 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
327 &ppp->host_uniq, sizeof(ppp->host_uniq));
330 r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
331 0, &link.sa, sizeof(link.ll));
338 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
340 static int pppoe_arm_timeout(sd_pppoe *ppp) {
341 _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
347 r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
349 next_timeout = now(clock_boottime_or_monotonic());
353 next_timeout += 500 * USEC_PER_MSEC;
355 r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
356 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
360 r = sd_event_source_set_priority(timeout, ppp->event_priority);
364 sd_event_source_unref(ppp->timeout);
365 ppp->timeout = timeout;
371 static int pppoe_send_initiation(sd_pppoe *ppp) {
374 r = pppoe_send(ppp, PADI_CODE);
378 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
379 ppp->service_name ? : "");
381 pppoe_arm_timeout(ppp);
386 static int pppoe_send_request(sd_pppoe *ppp) {
389 r = pppoe_send(ppp, PADR_CODE);
393 log_debug("PPPoE: sent REQUEST");
395 ppp->padr_resend_count --;
397 pppoe_arm_timeout(ppp);
402 static int pppoe_send_terminate(sd_pppoe *ppp) {
405 r = pppoe_send(ppp, PADT_CODE);
409 log_debug("PPPoE: sent TERMINATE");
414 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
415 sd_pppoe *ppp = userdata;
420 switch (ppp->state) {
421 case PPPOE_STATE_INITIALIZING:
422 r = pppoe_send_initiation(ppp);
424 log_warning_errno(r, "PPPoE: sending PADI failed: %m");
427 case PPPOE_STATE_REQUESTING:
428 if (ppp->padr_resend_count <= 0) {
429 log_debug("PPPoE: PADR timed out, restarting PADI");
431 r = pppoe_send_initiation(ppp);
433 log_warning_errno(r, "PPPoE: sending PADI failed: %m");
435 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
436 ppp->state = PPPOE_STATE_INITIALIZING;
438 r = pppoe_send_request(ppp);
440 log_warning_errno(r, "PPPoE: sending PADR failed: %m");
445 assert_not_reached("timeout in invalid state");
451 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
457 data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
463 *length = PPPOE_TAG_LENGTH(tag);
468 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
473 string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
483 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
484 struct pppoe_tag *tag;
489 pppoe_tags_clear(tags);
491 PPPOE_TAGS_FOREACH(tag, header) {
492 switch (PPPOE_TAG_TYPE(tag)) {
494 r = pppoe_tag_parse_string(tag, &tags->service_name);
500 r = pppoe_tag_parse_string(tag, &tags->ac_name);
506 r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
512 r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
521 _cleanup_free_ char *error = NULL;
523 /* TODO: do something more sensible with the error messages */
524 r = pppoe_tag_parse_string(tag, &error);
528 if (strlen(error) > 0 && utf8_is_valid(error))
529 log_debug("PPPoE: error - '%s'", error);
531 log_debug("PPPoE: error");
536 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
543 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
547 assert(ppp->pppoe_fd == -1);
549 s = socket(AF_PPPOX, SOCK_STREAM, 0);
558 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
559 union sockaddr_union_pppox link = {
561 .sa_family = AF_PPPOX,
562 .sa_protocol = PX_PROTO_OE,
568 assert(ppp->pppoe_fd != -1);
569 assert(ppp->session_id);
572 link.pppox.sa_addr.pppoe.sid = ppp->session_id;
573 memcpy(link.pppox.sa_addr.pppoe.dev, ppp->ifname, strlen(ppp->ifname));
574 memcpy(link.pppox.sa_addr.pppoe.remote, &ppp->peer_mac, ETH_ALEN);
576 r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
580 r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
584 ppp->channel = channel;
589 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
594 if (packet->ver != 0x1 || packet->type != 0x1)
597 r = pppoe_payload_parse(&ppp->tags, packet);
601 switch (ppp->state) {
602 case PPPOE_STATE_INITIALIZING:
603 if (packet->code != PADO_CODE)
606 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
607 memcmp(ppp->tags.host_uniq, &ppp->host_uniq, sizeof(ppp->host_uniq)) != 0)
610 log_debug("PPPoE: got OFFER (Peer: "
611 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
612 "Service-Name: '%s'; AC-Name: '%s')",
613 mac->ether_addr_octet[0],
614 mac->ether_addr_octet[1],
615 mac->ether_addr_octet[2],
616 mac->ether_addr_octet[3],
617 mac->ether_addr_octet[4],
618 mac->ether_addr_octet[5],
619 ppp->tags.service_name ? : "",
620 ppp->tags.ac_name ? : "");
622 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
624 r = pppoe_open_pppoe_socket(ppp);
626 log_warning("PPPoE: could not open socket");
630 r = pppoe_send_request(ppp);
634 ppp->state = PPPOE_STATE_REQUESTING;
637 case PPPOE_STATE_REQUESTING:
638 if (packet->code != PADS_CODE)
641 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
642 memcmp(ppp->tags.host_uniq, &ppp->host_uniq,
643 sizeof(ppp->host_uniq)) != 0)
646 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
649 ppp->session_id = packet->sid;
651 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
652 be16toh(ppp->session_id));
654 r = pppoe_connect_pppoe_socket(ppp);
656 log_warning("PPPoE: could not connect socket");
660 ppp->state = PPPOE_STATE_RUNNING;
662 ppp->timeout = sd_event_source_unref(ppp->timeout);
664 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
667 case PPPOE_STATE_RUNNING:
668 if (packet->code != PADT_CODE)
671 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
674 if (ppp->session_id != packet->sid)
677 log_debug("PPPoE: got TERMINATE");
679 ppp->state = PPPOE_STATE_STOPPED;
682 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
685 case PPPOE_STATE_STOPPED:
688 assert_not_reached("PPPoE: invalid state when receiving message");
694 static int pppoe_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
695 sd_pppoe *ppp = userdata;
696 _cleanup_free_ struct pppoe_hdr *packet = NULL;
697 union sockaddr_union link = {};
698 socklen_t addrlen = sizeof(link);
699 int buflen = 0, len, r;
704 r = ioctl(fd, FIONREAD, &buflen);
709 /* this can't be right */
712 packet = malloc0(buflen);
716 len = recvfrom(fd, packet, buflen, 0, &link.sa, &addrlen);
718 log_warning_errno(r, "PPPoE: could not receive message from raw socket: %m");
720 } else if ((size_t)len < sizeof(struct pppoe_hdr))
722 else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
725 if (link.ll.sll_halen != ETH_ALEN)
729 r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
736 int sd_pppoe_start(sd_pppoe *ppp) {
737 union sockaddr_union link = {
739 .sll_family = AF_PACKET,
740 .sll_protocol = htons(ETH_P_PPP_DISC),
743 _cleanup_close_ int s = -1;
744 _cleanup_event_source_unref_ sd_event_source *io = NULL;
747 assert_return(ppp, -EINVAL);
748 assert_return(ppp->fd == -1, -EBUSY);
749 assert_return(!ppp->io, -EBUSY);
750 assert_return(ppp->ifindex > 0, -EUNATCH);
751 assert_return(ppp->ifname, -EUNATCH);
752 assert_return(ppp->event, -EUNATCH);
753 assert_return(ppp->cb, -EUNATCH);
755 s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
759 link.ll.sll_ifindex = ppp->ifindex;
761 r = bind(s, &link.sa, sizeof(link.ll));
765 r = sd_event_add_io(ppp->event, &io,
766 s, EPOLLIN, pppoe_receive_message,
771 r = sd_event_source_set_priority(io, ppp->event_priority);
780 r = pppoe_send_initiation(ppp);
784 ppp->state = PPPOE_STATE_INITIALIZING;
789 int sd_pppoe_stop(sd_pppoe *ppp) {
790 assert_return(ppp, -EINVAL);
792 if (ppp->state == PPPOE_STATE_RUNNING)
793 pppoe_send_terminate(ppp);
795 ppp->io = sd_event_source_unref(ppp->io);
796 ppp->timeout = sd_event_source_unref(ppp->timeout);
797 ppp->fd = asynchronous_close(ppp->fd);
798 ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);