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/>.
25 #include <netinet/in.h>
26 #include <sys/ioctl.h>
27 #include <linux/if_pppox.h>
28 #include <linux/ppp-ioctl.h>
29 #include <linux/ppp_defs.h>
34 #include "event-util.h"
35 #include "random-util.h"
36 #include "socket-util.h"
37 #include "string-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
) {
208 assert(ppp
->n_ref
> 0);
214 sd_pppoe
*sd_pppoe_unref(sd_pppoe
*ppp
) {
219 assert(ppp
->n_ref
> 0);
225 pppoe_tags_clear(&ppp
->tags
);
227 free(ppp
->service_name
);
229 sd_pppoe_detach_event(ppp
);
235 int sd_pppoe_new (sd_pppoe
**ret
) {
238 assert_return(ret
, -EINVAL
);
240 ppp
= new0(sd_pppoe
, 1);
245 ppp
->state
= _PPPOE_STATE_INVALID
;
249 ppp
->padr_resend_count
= PPPOE_MAX_PADR_RESEND
;
256 int sd_pppoe_get_channel(sd_pppoe
*ppp
, int *channel
) {
257 assert_return(ppp
, -EINVAL
);
258 assert_return(channel
, -EINVAL
);
259 assert_return(ppp
->pppoe_fd
!= -1, -EUNATCH
);
260 assert_return(ppp
->state
== PPPOE_STATE_RUNNING
, -EUNATCH
);
262 *channel
= ppp
->channel
;
267 int sd_pppoe_set_callback(sd_pppoe
*ppp
, sd_pppoe_cb_t cb
, void *userdata
) {
268 assert_return(ppp
, -EINVAL
);
271 ppp
->userdata
= userdata
;
276 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
) {
277 struct pppoe_tag
*tag
;
280 assert(sizeof(struct pppoe_hdr
) + PPPOE_PACKET_LENGTH(packet
) + sizeof(struct pppoe_tag
) + tag_len
<= packet_size
);
281 assert(!(!tag_data
^ !tag_len
));
283 tag
= PPPOE_PACKET_TAIL(packet
);
285 tag
->tag_len
= htobe16(tag_len
);
286 tag
->tag_type
= tag_type
;
288 memcpy(tag
->tag_data
, tag_data
, tag_len
);
290 packet
->length
= htobe16(PPPOE_PACKET_LENGTH(packet
) + sizeof(struct pppoe_tag
) + tag_len
);
293 static int pppoe_send(sd_pppoe
*ppp
, uint8_t code
) {
294 union sockaddr_union link
= {
296 .sll_family
= AF_PACKET
,
297 .sll_protocol
= htons(ETH_P_PPP_DISC
),
298 .sll_halen
= ETH_ALEN
,
301 _cleanup_free_
struct pppoe_hdr
*packet
= NULL
;
305 assert(ppp
->fd
!= -1);
306 assert(IN_SET(code
, PADI_CODE
, PADR_CODE
, PADT_CODE
));
308 link
.ll
.sll_ifindex
= ppp
->ifindex
;
309 if (code
== PADI_CODE
)
310 memset(&link
.ll
.sll_addr
, 0xff, ETH_ALEN
);
312 memcpy(&link
.ll
.sll_addr
, &ppp
->peer_mac
, ETH_ALEN
);
314 packet
= malloc0(PPPOE_MAX_PACKET_SIZE
);
321 if (code
== PADT_CODE
)
322 packet
->sid
= ppp
->session_id
;
325 pppoe_tag_append(packet
, PPPOE_MAX_PACKET_SIZE
, PTT_SRV_NAME
,
326 ppp
->service_name
, ppp
->service_name
? strlen(ppp
->service_name
) : 0);
329 if (code
== PADR_CODE
&& ppp
->tags
.cookie
)
330 pppoe_tag_append(packet
, PPPOE_MAX_PACKET_SIZE
, PTT_AC_COOKIE
,
331 ppp
->tags
.cookie
, ppp
->tags
.cookie_len
);
334 if (code
!= PADT_CODE
) {
335 ppp
->host_uniq
= random_u64();
337 pppoe_tag_append(packet
, PPPOE_MAX_PACKET_SIZE
, PTT_HOST_UNIQ
,
338 &ppp
->host_uniq
, sizeof(ppp
->host_uniq
));
341 r
= sendto(ppp
->fd
, packet
, sizeof(struct pppoe_hdr
) + PPPOE_PACKET_LENGTH(packet
),
342 0, &link
.sa
, sizeof(link
.ll
));
349 static int pppoe_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
);
351 static int pppoe_arm_timeout(sd_pppoe
*ppp
) {
352 _cleanup_event_source_unref_ sd_event_source
*timeout
= NULL
;
353 usec_t next_timeout
= 0;
358 r
= sd_event_now(ppp
->event
, clock_boottime_or_monotonic(), &next_timeout
);
362 next_timeout
+= 500 * USEC_PER_MSEC
;
364 r
= sd_event_add_time(ppp
->event
, &timeout
, clock_boottime_or_monotonic(), next_timeout
,
365 10 * USEC_PER_MSEC
, pppoe_timeout
, ppp
);
369 r
= sd_event_source_set_priority(timeout
, ppp
->event_priority
);
373 sd_event_source_unref(ppp
->timeout
);
374 ppp
->timeout
= timeout
;
380 static int pppoe_send_initiation(sd_pppoe
*ppp
) {
383 r
= pppoe_send(ppp
, PADI_CODE
);
387 log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
388 strna(ppp
->service_name
));
390 pppoe_arm_timeout(ppp
);
395 static int pppoe_send_request(sd_pppoe
*ppp
) {
398 r
= pppoe_send(ppp
, PADR_CODE
);
402 log_debug("PPPoE: sent REQUEST");
404 ppp
->padr_resend_count
--;
406 pppoe_arm_timeout(ppp
);
411 static int pppoe_send_terminate(sd_pppoe
*ppp
) {
414 r
= pppoe_send(ppp
, PADT_CODE
);
418 log_debug("PPPoE: sent TERMINATE");
423 static int pppoe_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
424 sd_pppoe
*ppp
= userdata
;
429 switch (ppp
->state
) {
430 case PPPOE_STATE_INITIALIZING
:
431 r
= pppoe_send_initiation(ppp
);
433 log_warning_errno(r
, "PPPoE: sending PADI failed: %m");
436 case PPPOE_STATE_REQUESTING
:
437 if (ppp
->padr_resend_count
<= 0) {
438 log_debug("PPPoE: PADR timed out, restarting PADI");
440 r
= pppoe_send_initiation(ppp
);
442 log_warning_errno(r
, "PPPoE: sending PADI failed: %m");
444 ppp
->padr_resend_count
= PPPOE_MAX_PADR_RESEND
;
445 ppp
->state
= PPPOE_STATE_INITIALIZING
;
447 r
= pppoe_send_request(ppp
);
449 log_warning_errno(r
, "PPPoE: sending PADR failed: %m");
454 assert_not_reached("timeout in invalid state");
460 static int pppoe_tag_parse_binary(struct pppoe_tag
*tag
, uint8_t **ret
, size_t *length
) {
466 data
= memdup(tag
->tag_data
, PPPOE_TAG_LENGTH(tag
));
472 *length
= PPPOE_TAG_LENGTH(tag
);
477 static int pppoe_tag_parse_string(struct pppoe_tag
*tag
, char **ret
) {
482 string
= strndup(tag
->tag_data
, PPPOE_TAG_LENGTH(tag
));
492 static int pppoe_payload_parse(PPPoETags
*tags
, struct pppoe_hdr
*header
) {
493 struct pppoe_tag
*tag
;
498 pppoe_tags_clear(tags
);
500 PPPOE_TAGS_FOREACH(tag
, header
) {
501 switch (PPPOE_TAG_TYPE(tag
)) {
503 r
= pppoe_tag_parse_string(tag
, &tags
->service_name
);
509 r
= pppoe_tag_parse_string(tag
, &tags
->ac_name
);
515 r
= pppoe_tag_parse_binary(tag
, &tags
->host_uniq
, &tags
->host_uniq_len
);
521 r
= pppoe_tag_parse_binary(tag
, &tags
->cookie
, &tags
->cookie_len
);
530 _cleanup_free_
char *error
= NULL
;
532 /* TODO: do something more sensible with the error messages */
533 r
= pppoe_tag_parse_string(tag
, &error
);
537 if (strlen(error
) > 0 && utf8_is_valid(error
))
538 log_debug("PPPoE: error - '%s'", error
);
540 log_debug("PPPoE: error");
545 log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag
));
552 static int pppoe_open_pppoe_socket(sd_pppoe
*ppp
) {
556 assert(ppp
->pppoe_fd
== -1);
558 s
= socket(AF_PPPOX
, SOCK_STREAM
, 0);
567 static int pppoe_connect_pppoe_socket(sd_pppoe
*ppp
) {
568 union sockaddr_union_pppox link
= {
570 .sa_family
= AF_PPPOX
,
571 .sa_protocol
= PX_PROTO_OE
,
577 assert(ppp
->pppoe_fd
!= -1);
578 assert(ppp
->session_id
);
581 link
.pppox
.sa_addr
.pppoe
.sid
= ppp
->session_id
;
582 memcpy(link
.pppox
.sa_addr
.pppoe
.dev
, ppp
->ifname
, strlen(ppp
->ifname
));
583 memcpy(link
.pppox
.sa_addr
.pppoe
.remote
, &ppp
->peer_mac
, ETH_ALEN
);
585 r
= connect(ppp
->pppoe_fd
, &link
.sa
, sizeof(link
.pppox
));
589 r
= ioctl(ppp
->pppoe_fd
, PPPIOCGCHAN
, &channel
);
593 ppp
->channel
= channel
;
598 static int pppoe_handle_message(sd_pppoe
*ppp
, struct pppoe_hdr
*packet
, struct ether_addr
*mac
) {
603 if (packet
->ver
!= 0x1 || packet
->type
!= 0x1)
606 r
= pppoe_payload_parse(&ppp
->tags
, packet
);
610 switch (ppp
->state
) {
611 case PPPOE_STATE_INITIALIZING
:
612 if (packet
->code
!= PADO_CODE
)
615 if (ppp
->tags
.host_uniq_len
!= sizeof(ppp
->host_uniq
) ||
616 memcmp(ppp
->tags
.host_uniq
, &ppp
->host_uniq
, sizeof(ppp
->host_uniq
)) != 0)
619 log_debug("PPPoE: got OFFER (Peer: "
620 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
621 "Service-Name: '%s'; AC-Name: '%s')",
622 mac
->ether_addr_octet
[0],
623 mac
->ether_addr_octet
[1],
624 mac
->ether_addr_octet
[2],
625 mac
->ether_addr_octet
[3],
626 mac
->ether_addr_octet
[4],
627 mac
->ether_addr_octet
[5],
628 strempty(ppp
->tags
.service_name
),
629 strempty(ppp
->tags
.ac_name
));
631 memcpy(&ppp
->peer_mac
, mac
, ETH_ALEN
);
633 r
= pppoe_open_pppoe_socket(ppp
);
635 log_warning("PPPoE: could not open socket");
639 r
= pppoe_send_request(ppp
);
643 ppp
->state
= PPPOE_STATE_REQUESTING
;
646 case PPPOE_STATE_REQUESTING
:
647 if (packet
->code
!= PADS_CODE
)
650 if (ppp
->tags
.host_uniq_len
!= sizeof(ppp
->host_uniq
) ||
651 memcmp(ppp
->tags
.host_uniq
, &ppp
->host_uniq
,
652 sizeof(ppp
->host_uniq
)) != 0)
655 if (memcmp(&ppp
->peer_mac
, mac
, ETH_ALEN
) != 0)
658 ppp
->session_id
= packet
->sid
;
660 log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16
")",
661 be16toh(ppp
->session_id
));
663 r
= pppoe_connect_pppoe_socket(ppp
);
665 log_warning("PPPoE: could not connect socket");
669 ppp
->state
= PPPOE_STATE_RUNNING
;
671 ppp
->timeout
= sd_event_source_unref(ppp
->timeout
);
673 ppp
->cb(ppp
, SD_PPPOE_EVENT_RUNNING
, ppp
->userdata
);
676 case PPPOE_STATE_RUNNING
:
677 if (packet
->code
!= PADT_CODE
)
680 if (memcmp(&ppp
->peer_mac
, mac
, ETH_ALEN
) != 0)
683 if (ppp
->session_id
!= packet
->sid
)
686 log_debug("PPPoE: got TERMINATE");
688 ppp
->state
= PPPOE_STATE_STOPPED
;
691 ppp
->cb(ppp
, SD_PPPOE_EVENT_STOPPED
, ppp
->userdata
);
694 case PPPOE_STATE_STOPPED
:
697 assert_not_reached("PPPoE: invalid state when receiving message");
703 static int pppoe_receive_message(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
704 sd_pppoe
*ppp
= userdata
;
705 _cleanup_free_
struct pppoe_hdr
*packet
= NULL
;
706 union sockaddr_union link
= {};
707 socklen_t addrlen
= sizeof(link
);
708 int buflen
= 0, len
, r
;
713 r
= ioctl(fd
, FIONREAD
, &buflen
);
718 /* this can't be right */
721 packet
= malloc0(buflen
);
725 len
= recvfrom(fd
, packet
, buflen
, 0, &link
.sa
, &addrlen
);
727 log_warning_errno(r
, "PPPoE: could not receive message from raw socket: %m");
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
);