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"
40 #define PPPOE_MAX_PACKET_SIZE 1484
41 #define PPPOE_MAX_PADR_RESEND 16
43 /* TODO: move this to socket-util.h without getting into
44 * a mess with the includes */
45 union sockaddr_union_pppox {
47 struct sockaddr_pppox pppox;
50 typedef enum PPPoEState {
51 PPPOE_STATE_INITIALIZING,
52 PPPOE_STATE_REQUESTING,
56 _PPPOE_STATE_INVALID = -1,
59 typedef struct PPPoETags {
81 sd_event_source *timeout;
82 int padr_resend_count;
85 struct ether_addr peer_mac;
97 #define PPPOE_PACKET_LENGTH(header) \
98 be16toh((header)->length)
100 #define PPPOE_PACKET_TAIL(packet) \
101 (struct pppoe_tag*)((uint8_t*)(packet) + sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
103 #define PPPOE_TAG_LENGTH(tag) \
104 be16toh((tag)->tag_len)
106 #define PPPOE_TAG_TYPE(tag) \
109 #define PPPOE_TAG_NEXT(tag) \
110 (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
112 #define PPPOE_TAGS_FOREACH(tag, header) \
113 for (tag = (header)->tag; \
114 ((uint8_t *)(tag) + sizeof(struct pppoe_tag) < (uint8_t*)PPPOE_PACKET_TAIL(header)) && \
115 (PPPOE_TAG_NEXT(tag) <= PPPOE_PACKET_TAIL(header)) && \
116 (tag >= (header)->tag) && \
117 (PPPOE_TAG_TYPE(tag) != PTT_EOL); \
118 tag = PPPOE_TAG_NEXT(tag))
120 static void pppoe_tags_clear(PPPoETags *tags) {
121 free(tags->service_name);
123 free(tags->host_uniq);
129 int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
130 assert_return(ppp, -EINVAL);
131 assert_return(ifindex > 0, -EINVAL);
133 ppp->ifindex = ifindex;
138 int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
141 assert_return(ppp, -EINVAL);
142 assert_return(ifname, -EINVAL);
144 if (strlen(ifname) > IFNAMSIZ)
147 name = strdup(ifname);
157 int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
158 _cleanup_free_ char *name = NULL;
160 assert_return(ppp, -EINVAL);
163 name = strdup(service_name);
168 free(ppp->service_name);
169 ppp->service_name = name;
175 int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
178 assert_return(ppp, -EINVAL);
179 assert_return(!ppp->event, -EBUSY);
182 ppp->event = sd_event_ref(event);
184 r = sd_event_default(&ppp->event);
189 ppp->event_priority = priority;
194 int sd_pppoe_detach_event(sd_pppoe *ppp) {
195 assert_return(ppp, -EINVAL);
197 ppp->event = sd_event_unref(ppp->event);
202 sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
204 assert_se(REFCNT_INC(ppp->n_ref) >= 2);
209 sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
210 if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
211 pppoe_tags_clear(&ppp->tags);
213 free(ppp->service_name);
215 sd_pppoe_detach_event(ppp);
223 int sd_pppoe_new (sd_pppoe **ret) {
226 assert_return(ret, -EINVAL);
228 ppp = new0(sd_pppoe, 1);
232 ppp->n_ref = REFCNT_INIT;
233 ppp->state = _PPPOE_STATE_INVALID;
237 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
244 int sd_pppoe_get_channel(sd_pppoe *ppp, int *channel) {
245 assert_return(ppp, -EINVAL);
246 assert_return(channel, -EINVAL);
247 assert_return(ppp->pppoe_fd != -1, -EUNATCH);
248 assert_return(ppp->state == PPPOE_STATE_RUNNING, -EUNATCH);
250 *channel = ppp->channel;
255 int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
256 assert_return(ppp, -EINVAL);
259 ppp->userdata = userdata;
264 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) {
265 struct pppoe_tag *tag;
268 assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
269 assert(!(!tag_data ^ !tag_len));
271 tag = PPPOE_PACKET_TAIL(packet);
273 tag->tag_len = htobe16(tag_len);
274 tag->tag_type = tag_type;
276 memcpy(tag->tag_data, tag_data, tag_len);
278 packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
281 static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
282 union sockaddr_union link = {
284 .sll_family = AF_PACKET,
285 .sll_protocol = htons(ETH_P_PPP_DISC),
286 .sll_halen = ETH_ALEN,
289 _cleanup_free_ struct pppoe_hdr *packet = NULL;
293 assert(ppp->fd != -1);
294 assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
296 link.ll.sll_ifindex = ppp->ifindex;
297 if (code == PADI_CODE)
298 memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
300 memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
302 packet = malloc0(PPPOE_MAX_PACKET_SIZE);
309 if (code == PADT_CODE)
310 packet->sid = ppp->session_id;
313 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
314 ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
317 if (code == PADR_CODE && ppp->tags.cookie)
318 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE,
319 ppp->tags.cookie, ppp->tags.cookie_len);
322 if (code != PADT_CODE) {
323 ppp->host_uniq = random_u64();
325 pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
326 &ppp->host_uniq, sizeof(ppp->host_uniq));
329 r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
330 0, &link.sa, sizeof(link.ll));
337 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
339 static int pppoe_arm_timeout(sd_pppoe *ppp) {
340 _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
346 r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
348 next_timeout = now(clock_boottime_or_monotonic());
352 next_timeout += 500 * USEC_PER_MSEC;
354 r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
355 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
359 r = sd_event_source_set_priority(timeout, ppp->event_priority);
363 sd_event_source_unref(ppp->timeout);
364 ppp->timeout = timeout;
370 static int pppoe_send_initiation(sd_pppoe *ppp) {
373 r = pppoe_send(ppp, PADI_CODE);
377 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
378 ppp->service_name ? : "");
380 pppoe_arm_timeout(ppp);
385 static int pppoe_send_request(sd_pppoe *ppp) {
388 r = pppoe_send(ppp, PADR_CODE);
392 log_debug("PPPoE: sent REQUEST");
394 ppp->padr_resend_count --;
396 pppoe_arm_timeout(ppp);
401 static int pppoe_send_terminate(sd_pppoe *ppp) {
404 r = pppoe_send(ppp, PADT_CODE);
408 log_debug("PPPoE: sent TERMINATE");
413 static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
414 sd_pppoe *ppp = userdata;
419 switch (ppp->state) {
420 case PPPOE_STATE_INITIALIZING:
421 r = pppoe_send_initiation(ppp);
423 log_warning_errno(r, "PPPoE: sending PADI failed: %m");
426 case PPPOE_STATE_REQUESTING:
427 if (ppp->padr_resend_count <= 0) {
428 log_debug("PPPoE: PADR timed out, restarting PADI");
430 r = pppoe_send_initiation(ppp);
432 log_warning_errno(r, "PPPoE: sending PADI failed: %m");
434 ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
435 ppp->state = PPPOE_STATE_INITIALIZING;
437 r = pppoe_send_request(ppp);
439 log_warning_errno(r, "PPPoE: sending PADR failed: %m");
444 assert_not_reached("timeout in invalid state");
450 static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
456 data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
462 *length = PPPOE_TAG_LENGTH(tag);
467 static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
472 string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
482 static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
483 struct pppoe_tag *tag;
488 pppoe_tags_clear(tags);
490 PPPOE_TAGS_FOREACH(tag, header) {
491 switch (PPPOE_TAG_TYPE(tag)) {
493 r = pppoe_tag_parse_string(tag, &tags->service_name);
499 r = pppoe_tag_parse_string(tag, &tags->ac_name);
505 r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
511 r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
520 _cleanup_free_ char *error = NULL;
522 /* TODO: do something more sensible with the error messages */
523 r = pppoe_tag_parse_string(tag, &error);
527 if (strlen(error) > 0 && utf8_is_valid(error))
528 log_debug("PPPoE: error - '%s'", error);
530 log_debug("PPPoE: error");
535 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
542 static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
546 assert(ppp->pppoe_fd == -1);
548 s = socket(AF_PPPOX, SOCK_STREAM, 0);
557 static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
558 union sockaddr_union_pppox link = {
560 .sa_family = AF_PPPOX,
561 .sa_protocol = PX_PROTO_OE,
567 assert(ppp->pppoe_fd != -1);
568 assert(ppp->session_id);
571 link.pppox.sa_addr.pppoe.sid = ppp->session_id;
572 memcpy(link.pppox.sa_addr.pppoe.dev, ppp->ifname, strlen(ppp->ifname));
573 memcpy(link.pppox.sa_addr.pppoe.remote, &ppp->peer_mac, ETH_ALEN);
575 r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
579 r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
583 ppp->channel = channel;
588 static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
593 if (packet->ver != 0x1 || packet->type != 0x1)
596 r = pppoe_payload_parse(&ppp->tags, packet);
600 switch (ppp->state) {
601 case PPPOE_STATE_INITIALIZING:
602 if (packet->code != PADO_CODE)
605 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
606 memcmp(ppp->tags.host_uniq, &ppp->host_uniq, sizeof(ppp->host_uniq)) != 0)
609 log_debug("PPPoE: got OFFER (Peer: "
610 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
611 "Service-Name: '%s'; AC-Name: '%s')",
612 mac->ether_addr_octet[0],
613 mac->ether_addr_octet[1],
614 mac->ether_addr_octet[2],
615 mac->ether_addr_octet[3],
616 mac->ether_addr_octet[4],
617 mac->ether_addr_octet[5],
618 ppp->tags.service_name ? : "",
619 ppp->tags.ac_name ? : "");
621 memcpy(&ppp->peer_mac, mac, ETH_ALEN);
623 r = pppoe_open_pppoe_socket(ppp);
625 log_warning("PPPoE: could not open socket");
629 r = pppoe_send_request(ppp);
633 ppp->state = PPPOE_STATE_REQUESTING;
636 case PPPOE_STATE_REQUESTING:
637 if (packet->code != PADS_CODE)
640 if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
641 memcmp(ppp->tags.host_uniq, &ppp->host_uniq,
642 sizeof(ppp->host_uniq)) != 0)
645 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
648 ppp->session_id = packet->sid;
650 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
651 be16toh(ppp->session_id));
653 r = pppoe_connect_pppoe_socket(ppp);
655 log_warning("PPPoE: could not connect socket");
659 ppp->state = PPPOE_STATE_RUNNING;
661 ppp->timeout = sd_event_source_unref(ppp->timeout);
663 ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
666 case PPPOE_STATE_RUNNING:
667 if (packet->code != PADT_CODE)
670 if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
673 if (ppp->session_id != packet->sid)
676 log_debug("PPPoE: got TERMINATE");
678 ppp->state = PPPOE_STATE_STOPPED;
681 ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
684 case PPPOE_STATE_STOPPED:
687 assert_not_reached("PPPoE: invalid state when receiving message");
693 static int pppoe_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
694 sd_pppoe *ppp = userdata;
695 _cleanup_free_ struct pppoe_hdr *packet = NULL;
696 union sockaddr_union link = {};
697 socklen_t addrlen = sizeof(link);
698 int buflen = 0, len, r;
703 r = ioctl(fd, FIONREAD, &buflen);
708 /* this can't be right */
711 packet = malloc0(buflen);
715 len = recvfrom(fd, packet, buflen, 0, &link.sa, &addrlen);
717 log_warning_errno(r, "PPPoE: could not receive message from raw socket: %m");
719 } else if ((size_t)len < sizeof(struct pppoe_hdr))
721 else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
724 if (link.ll.sll_halen != ETH_ALEN)
728 r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
735 int sd_pppoe_start(sd_pppoe *ppp) {
736 union sockaddr_union link = {
738 .sll_family = AF_PACKET,
739 .sll_protocol = htons(ETH_P_PPP_DISC),
742 _cleanup_close_ int s = -1;
743 _cleanup_event_source_unref_ sd_event_source *io = NULL;
746 assert_return(ppp, -EINVAL);
747 assert_return(ppp->fd == -1, -EBUSY);
748 assert_return(!ppp->io, -EBUSY);
749 assert_return(ppp->ifindex > 0, -EUNATCH);
750 assert_return(ppp->ifname, -EUNATCH);
751 assert_return(ppp->event, -EUNATCH);
752 assert_return(ppp->cb, -EUNATCH);
754 s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
758 link.ll.sll_ifindex = ppp->ifindex;
760 r = bind(s, &link.sa, sizeof(link.ll));
764 r = sd_event_add_io(ppp->event, &io,
765 s, EPOLLIN, pppoe_receive_message,
770 r = sd_event_source_set_priority(io, ppp->event_priority);
779 r = pppoe_send_initiation(ppp);
783 ppp->state = PPPOE_STATE_INITIALIZING;
788 int sd_pppoe_stop(sd_pppoe *ppp) {
789 assert_return(ppp, -EINVAL);
791 if (ppp->state == PPPOE_STATE_RUNNING)
792 pppoe_send_terminate(ppp);
794 ppp->io = sd_event_source_unref(ppp->io);
795 ppp->timeout = sd_event_source_unref(ppp->timeout);
796 ppp->fd = asynchronous_close(ppp->fd);
797 ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);