3 * Add functionality "server pppoe" to l2tpns.
4 * inspiration pppoe.c of accel-ppp
17 #include <sys/socket.h>
18 #include <sys/ioctl.h>
20 #include <net/ethernet.h>
21 #include <netpacket/packet.h>
22 #include <arpa/inet.h>
23 #include <linux/if_pppox.h>
24 #include <linux/rtnetlink.h>
28 #include "constants.h"
35 static uint8_t bc_addr
[ETH_ALEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
38 #define CODE_PADI 0x09
39 #define CODE_PADO 0x07
40 #define CODE_PADR 0x19
41 #define CODE_PADS 0x65
42 #define CODE_PADT 0xA7
43 #define CODE_SESS 0x00
46 #define TAG_END_OF_LIST 0x0000
47 #define TAG_SERVICE_NAME 0x0101
48 #define TAG_AC_NAME 0x0102
49 #define TAG_HOST_UNIQ 0x0103
50 #define TAG_AC_COOKIE 0x0104
51 #define TAG_VENDOR_SPECIFIC 0x0105
52 #define TAG_RELAY_SESSION_ID 0x0110
53 #define TAG_SERVICE_NAME_ERROR 0x0201
54 #define TAG_AC_SYSTEM_ERROR 0x0202
55 #define TAG_GENERIC_ERROR 0x0203
57 static char *code_pad
[] = {
77 // set up pppoe discovery socket
78 static void init_pppoe_disc(void)
82 struct sockaddr_ll sa
;
84 memset(&ifr
, 0, sizeof(ifr
));
85 memset(&sa
, 0, sizeof(sa
));
87 pppoediscfd
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_PPP_DISC
));
90 LOG(0, 0, 0, "Error pppoe: socket: %s\n", strerror(errno
));
94 fcntl(pppoediscfd
, F_SETFD
, fcntl(pppoediscfd
, F_GETFD
) | FD_CLOEXEC
);
96 if (setsockopt(pppoediscfd
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof(on
)))
98 LOG(0, 0, 0, "Error pppoe: setsockopt(SO_BROADCAST): %s\n", strerror(errno
));
102 assert(strlen(ifr
.ifr_name
) < sizeof(config
->pppoe_if_to_bind
) - 1);
103 if (*config
->pppoe_if_to_bind
)
104 strncpy(ifr
.ifr_name
, config
->pppoe_if_to_bind
, IFNAMSIZ
);
106 if (ioctl(pppoediscfd
, SIOCGIFHWADDR
, &ifr
))
108 LOG(0, 0, 0, "Error pppoe: ioctl(SIOCGIFHWADDR): %s\n", strerror(errno
));
112 if ((ifr
.ifr_hwaddr
.sa_data
[0] & 1) != 0)
114 LOG(0, 0, 0, "Error pppoe: interface %s has not unicast address\n", config
->pppoe_if_to_bind
);
118 memcpy(config
->pppoe_hwaddr
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
120 if (ioctl(pppoediscfd
, SIOCGIFMTU
, &ifr
))
122 LOG(0, 0, 0, "Error pppoe: ioctl(SIOCGIFMTU): %s\n", strerror(errno
));
126 if (ifr
.ifr_mtu
< ETH_DATA_LEN
)
127 LOG(0, 0, 0, "Error pppoe: interface %s has MTU of %i, should be %i\n", config
->pppoe_if_to_bind
, ifr
.ifr_mtu
, ETH_DATA_LEN
);
129 if (ioctl(pppoediscfd
, SIOCGIFINDEX
, &ifr
))
131 LOG(0, 0, 0, "Error pppoe: ioctl(SIOCGIFINDEX): %s\n", strerror(errno
));
135 memset(&sa
, 0, sizeof(sa
));
136 sa
.sll_family
= AF_PACKET
;
137 sa
.sll_protocol
= htons(ETH_P_PPP_DISC
);
138 sa
.sll_ifindex
= ifr
.ifr_ifindex
;
140 if (bind(pppoediscfd
, (struct sockaddr
*)&sa
, sizeof(sa
)))
142 LOG(0, 0, 0, "Error pppoe: bind: %s\n", strerror(errno
));
146 if (fcntl(pppoediscfd
, F_SETFL
, O_NONBLOCK
))
148 LOG(0, 0, 0, "Error pppoe: failed to set nonblocking mode: %s\n", strerror(errno
));
154 // set up pppoe session socket
155 static void init_pppoe_sess(void)
159 struct sockaddr_ll sa
;
161 memset(&ifr
, 0, sizeof(ifr
));
162 memset(&sa
, 0, sizeof(sa
));
164 pppoesessfd
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_PPP_SES
));
167 LOG(0, 0, 0, "Error pppoe: socket: %s\n", strerror(errno
));
171 fcntl(pppoesessfd
, F_SETFD
, fcntl(pppoesessfd
, F_GETFD
) | FD_CLOEXEC
);
173 if (setsockopt(pppoesessfd
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof(on
)))
175 LOG(0, 0, 0, "Error pppoe: setsockopt(SO_BROADCAST): %s\n", strerror(errno
));
179 assert(strlen(ifr
.ifr_name
) < sizeof(config
->pppoe_if_to_bind
) - 1);
180 if (*config
->pppoe_if_to_bind
)
181 strncpy(ifr
.ifr_name
, config
->pppoe_if_to_bind
, IFNAMSIZ
);
183 if (ioctl(pppoesessfd
, SIOCGIFHWADDR
, &ifr
))
185 LOG(0, 0, 0, "Error pppoe: ioctl(SIOCGIFHWADDR): %s\n", strerror(errno
));
189 if ((ifr
.ifr_hwaddr
.sa_data
[0] & 1) != 0)
191 LOG(0, 0, 0, "Error pppoe: interface %s has not unicast address\n", config
->pppoe_if_to_bind
);
195 memcpy(config
->pppoe_hwaddr
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
197 if (ioctl(pppoesessfd
, SIOCGIFMTU
, &ifr
))
199 LOG(0, 0, 0, "Error pppoe: ioctl(SIOCGIFMTU): %s\n", strerror(errno
));
203 if (ifr
.ifr_mtu
< ETH_DATA_LEN
)
204 LOG(0, 0, 0, "Error pppoe: interface %s has MTU of %i, should be %i\n", config
->pppoe_if_to_bind
, ifr
.ifr_mtu
, ETH_DATA_LEN
);
206 if (ioctl(pppoesessfd
, SIOCGIFINDEX
, &ifr
))
208 LOG(0, 0, 0, "Error pppoe: ioctl(SIOCGIFINDEX): %s\n", strerror(errno
));
212 memset(&sa
, 0, sizeof(sa
));
213 sa
.sll_family
= AF_PACKET
;
214 sa
.sll_protocol
= htons(ETH_P_PPP_SES
);
215 sa
.sll_ifindex
= ifr
.ifr_ifindex
;
217 if (bind(pppoesessfd
, (struct sockaddr
*)&sa
, sizeof(sa
)))
219 LOG(0, 0, 0, "Error pppoe: bind: %s\n", strerror(errno
));
223 if (fcntl(pppoesessfd
, F_SETFL
, O_NONBLOCK
))
225 LOG(0, 0, 0, "Error pppoe: failed to set nonblocking mode: %s\n", strerror(errno
));
230 // set up pppoe discovery/session socket
231 void init_pppoe(void)
233 tunnelidt t
= TUNNEL_ID_PPPOE
;
238 // Reserve the a pseudo tunnel for pppoe server
239 if (t
> config
->cluster_highest_tunnelid
)
240 config
->cluster_highest_tunnelid
= t
;
242 memset(&tunnel
[t
], 0, sizeof(tunnel
[t
]));
243 tunnel
[t
].state
= TUNNELOPEN
;
244 STAT(tunnel_created
);
247 char * get_string_codepad(uint8_t codepad
)
253 ptrch
= code_pad
[INDEX_PADI
];
257 ptrch
= code_pad
[INDEX_PADO
];
261 ptrch
= code_pad
[INDEX_PADR
];
265 ptrch
= code_pad
[INDEX_PADS
];
269 ptrch
= code_pad
[INDEX_PADT
];
273 ptrch
= code_pad
[INDEX_SESS
];
280 static uint8_t * setup_header(uint8_t *pack
, const uint8_t *src
, const uint8_t *dst
, int code
, uint16_t sid
, uint16_t h_proto
)
284 // 14 bytes ethernet Header + 6 bytes header pppoe
285 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
286 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
288 memcpy(ethhdr
->h_source
, src
, ETH_ALEN
);
289 memcpy(ethhdr
->h_dest
, dst
, ETH_ALEN
);
290 ethhdr
->h_proto
= htons(h_proto
);
295 hdr
->sid
= htons(sid
);
298 p
= (uint8_t *)(pack
+ ETH_HLEN
+ sizeof(*hdr
));
303 static void add_tag(uint8_t *pack
, int type
, const uint8_t *data
, int len
)
305 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
306 struct pppoe_tag
*tag
= (struct pppoe_tag
*)(pack
+ ETH_HLEN
+ sizeof(*hdr
) + ntohs(hdr
->length
));
308 tag
->tag_type
= htons(type
);
309 tag
->tag_len
= htons(len
);
310 memcpy(tag
->tag_data
, data
, len
);
312 hdr
->length
= htons(ntohs(hdr
->length
) + sizeof(*tag
) + len
);
315 static void add_tag2(uint8_t *pack
, const struct pppoe_tag
*t
)
317 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
318 struct pppoe_tag
*tag
= (struct pppoe_tag
*)(pack
+ ETH_HLEN
+ sizeof(*hdr
) + ntohs(hdr
->length
));
320 memcpy(tag
, t
, sizeof(*t
) + ntohs(t
->tag_len
));
322 hdr
->length
= htons(ntohs(hdr
->length
) + sizeof(*tag
) + ntohs(t
->tag_len
));
325 static void pppoe_disc_send(const uint8_t *pack
)
327 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
328 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
331 s
= ETH_HLEN
+ sizeof(*hdr
) + ntohs(hdr
->length
);
333 LOG(3, 0, 0, "SENT pppoe_disc: Code %s to %s\n", get_string_codepad(hdr
->code
), fmtMacAddr(ethhdr
->h_dest
));
334 LOG_HEX(5, "pppoe_disc_send", pack
, s
);
336 n
= write(pppoediscfd
, pack
, s
);
338 LOG(0, 0, 0, "pppoe: write: %s\n", strerror(errno
));
340 LOG(0, 0, 0, "pppoe: short write %i/%i\n", n
,s
);
344 void pppoe_sess_send(const uint8_t *pack
, uint16_t l
, tunnelidt t
)
346 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
351 if (t
!= TUNNEL_ID_PPPOE
)
353 LOG(3, 0, t
, "ERROR pppoe_sess_send: Tunnel %d is not a tunnel pppoe\n", t
);
358 if (session
[s
].tunnel
!= t
)
360 LOG(3, s
, t
, "ERROR pppoe_sess_send: Session is not a session pppoe\n");
364 if (l
< (ETH_HLEN
+ sizeof(*hdr
) + 3))
366 LOG(0, s
, t
, "ERROR pppoe_sess_send: packet too small for pppoe sent (size=%d)\n", l
);
370 // recalculate the ppp frame length
371 sizeppp
= l
- (ETH_HLEN
+ sizeof(*hdr
));
372 hdr
->length
= htons(sizeppp
);
374 LOG_HEX(5, "pppoe_sess_send", pack
, l
);
376 n
= write(pppoesessfd
, pack
, l
);
378 LOG(0, s
, t
, "pppoe_sess_send: write: %s\n", strerror(errno
));
380 LOG(0, s
, t
, "pppoe_sess_send: short write %i/%i\n", n
,l
);
383 static void pppoe_send_err(const uint8_t *addr
, const struct pppoe_tag
*host_uniq
, const struct pppoe_tag
*relay_sid
, int code
, int tag_type
)
385 uint8_t pack
[ETHER_MAX_LEN
];
387 setup_header(pack
, config
->pppoe_hwaddr
, addr
, code
, 0, ETH_P_PPP_DISC
);
389 add_tag(pack
, TAG_AC_NAME
, (uint8_t *)config
->pppoe_ac_name
, strlen(config
->pppoe_ac_name
));
390 add_tag(pack
, tag_type
, NULL
, 0);
393 add_tag2(pack
, host_uniq
);
396 add_tag2(pack
, relay_sid
);
398 pppoe_disc_send(pack
);
402 static void pppoe_gen_cookie(const uint8_t *serv_hwaddr
, const uint8_t *client_hwaddr
, uint8_t *out
)
407 MD5_Update(&ctx
, config
->l2tp_secret
, strlen(config
->l2tp_secret
));
408 MD5_Update(&ctx
, (void *) serv_hwaddr
, ETH_ALEN
);
409 MD5_Update(&ctx
, (void *) client_hwaddr
, ETH_ALEN
);
410 MD5_Final(out
, &ctx
);
414 static int pppoe_check_cookie(const uint8_t *serv_hwaddr
, const uint8_t *client_hwaddr
, uint8_t *cookie
)
418 pppoe_gen_cookie(serv_hwaddr
, client_hwaddr
, hash
);
420 return memcmp(hash
, cookie
, 16);
423 static void pppoe_send_PADO(const uint8_t *addr
, const struct pppoe_tag
*host_uniq
, const struct pppoe_tag
*relay_sid
, const struct pppoe_tag
*service_name
)
425 uint8_t pack
[ETHER_MAX_LEN
];
428 setup_header(pack
, config
->pppoe_hwaddr
, addr
, CODE_PADO
, 0, ETH_P_PPP_DISC
);
430 add_tag(pack
, TAG_AC_NAME
, (uint8_t *)config
->pppoe_ac_name
, strlen(config
->pppoe_ac_name
));
433 add_tag2(pack
, service_name
);
435 pppoe_gen_cookie(config
->pppoe_hwaddr
, addr
, hash
);
436 add_tag(pack
, TAG_AC_COOKIE
, hash
, 16);
439 add_tag2(pack
, host_uniq
);
442 add_tag2(pack
, relay_sid
);
444 pppoe_disc_send(pack
);
447 static void pppoe_send_PADS(uint16_t sid
, const uint8_t *addr
, const struct pppoe_tag
*host_uniq
, const struct pppoe_tag
*relay_sid
, const struct pppoe_tag
*service_name
)
449 uint8_t pack
[ETHER_MAX_LEN
];
451 setup_header(pack
, config
->pppoe_hwaddr
, addr
, CODE_PADS
, sid
, ETH_P_PPP_DISC
);
453 add_tag(pack
, TAG_AC_NAME
, (uint8_t *)config
->pppoe_ac_name
, strlen(config
->pppoe_ac_name
));
455 add_tag2(pack
, service_name
);
458 add_tag2(pack
, host_uniq
);
461 add_tag2(pack
, relay_sid
);
463 pppoe_disc_send(pack
);
466 static void pppoe_send_PADT(uint16_t sid
)
468 uint8_t pack
[ETHER_MAX_LEN
];
470 setup_header(pack
, config
->pppoe_hwaddr
, session
[sid
].src_hwaddr
, CODE_PADT
, sid
, ETH_P_PPP_DISC
);
472 add_tag(pack
, TAG_AC_NAME
, (uint8_t *)config
->pppoe_ac_name
, strlen(config
->pppoe_ac_name
));
474 LOG(3, sid
, session
[sid
].tunnel
, "pppoe: Sent PADT\n");
476 pppoe_disc_send(pack
);
479 void pppoe_shutdown_session(sessionidt s
)
482 if (session
[s
].tunnel
!= TUNNEL_ID_PPPOE
)
484 LOG(3, s
, session
[s
].tunnel
, "ERROR pppoe_shutdown_session: Session is not a session pppoe\n");
491 static void pppoe_recv_PADI(uint8_t *pack
, int size
)
493 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
494 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
495 struct pppoe_tag
*tag
;
496 struct pppoe_tag
*host_uniq_tag
= NULL
;
497 struct pppoe_tag
*relay_sid_tag
= NULL
;
498 struct pppoe_tag
*service_name_tag
= NULL
;
499 int n
, service_match
= 0;
505 len
= ntohs(hdr
->length
);
506 for (n
= 0; n
< len
; n
+= sizeof(*tag
) + ntohs(tag
->tag_len
))
508 tag
= (struct pppoe_tag
*)(pack
+ ETH_HLEN
+ sizeof(*hdr
) + n
);
509 if (n
+ sizeof(*tag
) + ntohs(tag
->tag_len
) > len
)
511 switch (ntohs(tag
->tag_type
))
513 case TAG_END_OF_LIST
:
515 case TAG_SERVICE_NAME
:
516 if (config
->pppoe_only_equal_svc_name
&& *config
->pppoe_service_name
&& !tag
->tag_len
)
520 else if (*config
->pppoe_service_name
&& tag
->tag_len
)
522 if (ntohs(tag
->tag_len
) != strlen(config
->pppoe_service_name
))
524 if (memcmp(tag
->tag_data
, config
->pppoe_service_name
, ntohs(tag
->tag_len
)))
526 service_name_tag
= tag
;
531 service_name_tag
= tag
;
538 case TAG_RELAY_SESSION_ID
:
546 LOG(3, 0, 0, "pppoe: discarding PADI packet (Service-Name mismatch)\n");
550 pppoe_send_PADO(ethhdr
->h_source
, host_uniq_tag
, relay_sid_tag
, service_name_tag
);
553 static void pppoe_recv_PADR(uint8_t *pack
, int size
)
555 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
556 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
557 struct pppoe_tag
*tag
;
558 struct pppoe_tag
*host_uniq_tag
= NULL
;
559 struct pppoe_tag
*relay_sid_tag
= NULL
;
560 struct pppoe_tag
*ac_cookie_tag
= NULL
;
561 struct pppoe_tag
*service_name_tag
= NULL
;
562 int n
, service_match
= 0;
565 if (!memcmp(ethhdr
->h_dest
, bc_addr
, ETH_ALEN
))
567 LOG(1, 0, 0, "Rcv pppoe: discard PADR (destination address is broadcast)\n");
573 LOG(1, 0, 0, "Rcv pppoe: discarding PADR packet (sid is not zero)\n");
577 for (n
= 0; n
< ntohs(hdr
->length
); n
+= sizeof(*tag
) + ntohs(tag
->tag_len
))
579 tag
= (struct pppoe_tag
*)(pack
+ ETH_HLEN
+ sizeof(*hdr
) + n
);
580 switch (ntohs(tag
->tag_type
))
582 case TAG_END_OF_LIST
:
584 case TAG_SERVICE_NAME
:
585 service_name_tag
= tag
;
586 if (tag
->tag_len
== 0)
588 else if (*config
->pppoe_service_name
)
590 if (ntohs(tag
->tag_len
) != strlen(config
->pppoe_service_name
))
592 if (memcmp(tag
->tag_data
, config
->pppoe_service_name
, ntohs(tag
->tag_len
)))
607 case TAG_RELAY_SESSION_ID
:
615 LOG(3, 0, 0, "pppoe: Service-Name mismatch\n");
616 pppoe_send_err(ethhdr
->h_source
, host_uniq_tag
, relay_sid_tag
, CODE_PADS
, TAG_SERVICE_NAME_ERROR
);
622 LOG(3, 0, 0, "pppoe: discard PADR packet (no AC-Cookie tag present)\n");
626 if (ntohs(ac_cookie_tag
->tag_len
) != 16)
628 LOG(3, 0, 0, "pppoe: discard PADR packet (incorrect AC-Cookie tag length)\n");
632 if (pppoe_check_cookie(ethhdr
->h_dest
, ethhdr
->h_source
, (uint8_t *) ac_cookie_tag
->tag_data
))
634 LOG(3, 0, 0, "pppoe: discard PADR packet (incorrect AC-Cookie)\n");
639 sessionfree
= session
[sid
].next
;
640 memset(&session
[sid
], 0, sizeof(session
[0]));
642 if (sid
> config
->cluster_highest_sessionid
)
643 config
->cluster_highest_sessionid
= sid
;
645 session
[sid
].opened
= time_now
;
646 session
[sid
].tunnel
= TUNNEL_ID_PPPOE
;
647 session
[sid
].last_packet
= session
[sid
].last_data
= time_now
;
649 //strncpy(session[sid].called, called, sizeof(session[sid].called) - 1);
650 //strncpy(session[sid].calling, calling, sizeof(session[sid].calling) - 1);
652 session
[sid
].ppp
.phase
= Establish
;
653 session
[sid
].ppp
.lcp
= Starting
;
655 session
[sid
].magic
= time_now
; // set magic number
656 session
[sid
].mru
= PPPoE_MRU
; // default
659 sess_local
[sid
].lcp_authtype
= config
->radius_authprefer
;
660 sess_local
[sid
].ppp_mru
= MRU
;
662 // Set multilink options before sending initial LCP packet
663 sess_local
[sid
].mp_mrru
= 1614;
664 sess_local
[sid
].mp_epdis
= ntohl(config
->iftun_address
? config
->iftun_address
: my_address
);
666 memcpy(session
[sid
].src_hwaddr
, ethhdr
->h_source
, ETH_ALEN
);
667 pppoe_send_PADS(sid
, ethhdr
->h_source
, host_uniq_tag
, relay_sid_tag
, service_name_tag
);
669 sendlcp(sid
, session
[sid
].tunnel
);
670 change_state(sid
, lcp
, RequestSent
);
674 static void pppoe_recv_PADT(uint8_t *pack
)
676 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
677 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
679 if (!memcmp(ethhdr
->h_dest
, bc_addr
, ETH_ALEN
))
681 LOG(3, 0, 0, "pppoe: discard PADT (destination address is broadcast)\n");
687 if ((hdr
->sid
< MAXSESSION
) && (session
[hdr
->sid
].tunnel
== TUNNEL_ID_PPPOE
))
688 sessionshutdown(hdr
->sid
, "Client shutdown", CDN_ADMIN_DISC
, 0);
692 // fill in a PPPOE message with a PPP frame,
693 // returns start of PPP frame
694 uint8_t *pppoe_makeppp(uint8_t *b
, int size
, uint8_t *p
, int l
, sessionidt s
, tunnelidt t
,
695 uint16_t mtype
, uint8_t prio
, bundleidt bid
, uint8_t mp_bits
)
697 uint16_t type
= mtype
;
699 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(b
+ ETH_HLEN
);
701 if (t
!= TUNNEL_ID_PPPOE
)
704 if (size
< 28) // Need more space than this!!
706 LOG(0, s
, t
, "pppoe_makeppp buffer too small for pppoe header (size=%d)\n", size
);
710 // 14 bytes ethernet Header + 6 bytes header pppoe
711 b
= setup_header(b
, config
->pppoe_hwaddr
, session
[s
].src_hwaddr
, CODE_SESS
, s
, ETH_P_PPP_SES
);
713 // Check whether this session is part of multilink
716 if (bundle
[bid
].num_of_links
> 1)
717 type
= PPPMP
; // Change PPP message type to the PPPMP
722 *(uint16_t *) b
= htons(type
);
728 // Set the sequence number and (B)egin (E)nd flags
731 // Set the multilink bits
732 uint16_t bits_send
= mp_bits
;
733 *(uint16_t *) b
= htons((bundle
[bid
].seq_num_t
& 0x0FFF)|bits_send
);
739 *(uint32_t *) b
= htonl(bundle
[bid
].seq_num_t
);
740 // Set the multilink bits
746 bundle
[bid
].seq_num_t
++;
748 // Add the message type if this fragment has the begin bit set
749 if (mp_bits
& MP_BEGIN
)
751 //*b++ = mtype; // The next two lines are instead of this
752 *(uint16_t *) b
= htons(mtype
); // Message type
758 if ((b
- start
) + l
> size
)
760 LOG(0, s
, t
, "pppoe_makeppp would overflow buffer (size=%d, header+payload=%td)\n", size
, (b
- start
) + l
);
774 // fill in a PPPOE message with a PPP frame,
775 // returns start of PPP frame
776 //(note: THIS ROUTINE WRITES TO p[-28]).
777 uint8_t *opt_pppoe_makeppp(uint8_t *p
, int l
, sessionidt s
, tunnelidt t
, uint16_t mtype
, uint8_t prio
, bundleidt bid
, uint8_t mp_bits
)
779 uint16_t type
= mtype
;
782 struct pppoe_hdr
*hdr
;
784 if (t
!= TUNNEL_ID_PPPOE
)
787 // Check whether this session is part of multilink
790 if (bundle
[bid
].num_of_links
> 1)
791 type
= PPPMP
; // Change PPP message type to the PPPMP
798 // Add the message type if this fragment has the begin bit set
799 if (mp_bits
& MP_BEGIN
)
802 *(uint16_t *) b
= htons(mtype
); // Message type
805 // Set the sequence number and (B)egin (E)nd flags
808 // Set the multilink bits
809 uint16_t bits_send
= mp_bits
;
811 *(uint16_t *) b
= htons((bundle
[bid
].seq_num_t
& 0x0FFF)|bits_send
);
816 *(uint32_t *) b
= htonl(bundle
[bid
].seq_num_t
);
817 // Set the multilink bits
821 bundle
[bid
].seq_num_t
++;
825 *(uint16_t *) b
= htons(type
);
830 // 14 bytes ethernet Header + 6 bytes header pppoe
831 b
-= (ETH_HLEN
+ sizeof(*hdr
));
832 setup_header(b
, config
->pppoe_hwaddr
, session
[s
].src_hwaddr
, CODE_SESS
, s
, ETH_P_PPP_SES
);
833 hdr
= (struct pppoe_hdr
*)(b
+ ETH_HLEN
);
834 // Store length on header pppoe
835 hdr
->length
= hdrlen
;
840 // pppoe discovery recv data
841 void process_pppoe_disc(uint8_t *pack
, int size
)
843 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
844 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
846 LOG(3, 0, 0, "RCV pppoe_disc: Code %s from %s\n", get_string_codepad(hdr
->code
), fmtMacAddr(ethhdr
->h_source
));
847 LOG_HEX(5, "PPPOE Disc", pack
, size
);
849 if (!config
->cluster_iam_master
)
851 if (hdr
->code
== CODE_PADI
)
852 return; // Discard because the PADI is received by all (PADI is a broadcast diffusion)
854 master_forward_pppoe_packet(pack
, size
, hdr
->code
);
858 if (size
< (ETH_HLEN
+ sizeof(*hdr
)))
860 LOG(1, 0, 0, "Error pppoe_disc: short packet received (%i)\n", size
);
864 if (memcmp(ethhdr
->h_dest
, bc_addr
, ETH_ALEN
) && memcmp(ethhdr
->h_dest
, config
->pppoe_hwaddr
, ETH_ALEN
))
866 LOG(1, 0, 0, "Error pppoe_disc: h_dest != bc_addr and h_dest != config->pppoe_hwaddr\n");
870 if (!memcmp(ethhdr
->h_source
, bc_addr
, ETH_ALEN
))
872 LOG(1, 0, 0, "Error pppoe_disc: discarding packet (source address is broadcast)\n");
876 if ((ethhdr
->h_source
[0] & 1) != 0)
878 LOG(1, 0, 0, "Error pppoe_disc: discarding packet (host address is not unicast)\n");
882 if (size
< ETH_HLEN
+ sizeof(*hdr
) + ntohs(hdr
->length
))
884 LOG(1, 0, 0, "Error pppoe_disc: short packet received\n");
890 LOG(1, 0, 0, "Error pppoe_disc: discarding packet (unsupported version %i)\n", hdr
->ver
);
896 LOG(1, 0, 0, "Error pppoe_disc: discarding packet (unsupported type %i)\n", hdr
->type
);
902 pppoe_recv_PADI(pack
, size
);
905 pppoe_recv_PADR(pack
, size
);
908 pppoe_recv_PADT(pack
);
913 // Forward from pppoe to l2tp remote LNS
914 static void pppoe_forwardto_session_rmlns(uint8_t *pack
, int size
, sessionidt sess
, uint16_t proto
)
916 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
917 uint16_t lppp
= ntohs(hdr
->length
);
918 uint16_t ll2tp
= lppp
+ 6;
919 uint8_t *pppdata
= (uint8_t *) hdr
->tag
;
920 uint8_t *pl2tp
= pppdata
- 6;
922 uint16_t t
= 0, s
= 0;
924 s
= session
[sess
].forwardtosession
;
925 if (session
[s
].forwardtosession
!= sess
)
927 LOG(3, sess
, session
[sess
].tunnel
, "pppoe: Link Session (%u) broken\n", s
);
931 t
= session
[s
].tunnel
;
934 LOG(1, s
, t
, "pppoe: Session with invalid tunnel ID\n");
938 if (!tunnel
[t
].isremotelns
)
940 LOG(3, sess
, session
[sess
].tunnel
, "pppoe: Link Tunnel/Session (%u/%u) broken\n", s
, t
);
944 // First word L2TP options (with no options)
945 *(uint16_t *) p
= htons(0x0002);
947 *(uint16_t *) p
= htons(tunnel
[t
].far
); // tunnel
949 *(uint16_t *) p
= htons(session
[s
].far
); // session
952 if ((proto
== PPPIP
) || (proto
== PPPMP
) ||(proto
== PPPIPV6
&& config
->ipv6_prefix
.s6_addr
[0]))
954 session
[sess
].last_packet
= session
[sess
].last_data
= time_now
;
956 increment_counter(&session
[sess
].cin
, &session
[sess
].cin_wrap
, ll2tp
);
957 session
[sess
].cin_delta
+= ll2tp
;
959 sess_local
[sess
].cin
+= ll2tp
;
960 sess_local
[sess
].pin
++;
962 session
[s
].last_data
= time_now
;
964 increment_counter(&session
[s
].cout
, &session
[s
].cout_wrap
, ll2tp
); // byte count
965 session
[s
].cout_delta
+= ll2tp
;
967 sess_local
[s
].cout
+= ll2tp
;
968 sess_local
[s
].pout
++;
971 session
[sess
].last_packet
= time_now
;
973 tunnelsend(pl2tp
, ll2tp
, t
); // send it...
976 // Forward from l2tp to pppoe
977 // (note: THIS ROUTINE WRITES TO pack[-20]).
978 void pppoe_forwardto_session_pppoe(uint8_t *pack
, int size
, sessionidt sess
, uint16_t proto
)
980 uint16_t t
= 0, s
= 0;
981 uint16_t lpppoe
= size
- 2;
982 uint8_t *p
= pack
+ 2; // First word L2TP options
984 LOG(5, sess
, session
[sess
].tunnel
, "Forwarding data session to pppoe session %u\n", session
[sess
].forwardtosession
);
986 s
= session
[sess
].forwardtosession
;
987 t
= session
[s
].tunnel
;
995 *(uint16_t *) p
= htons(tunnel
[t
].far
); // tunnel
997 *(uint16_t *) p
= htons(session
[s
].far
); // session
1003 *(uint16_t *) p
= htons(tunnel
[t
].ns
); // sequence
1005 *(uint16_t *) p
= htons(tunnel
[t
].nr
); // sequence
1010 if (lpppoe
> 2 && p
[0] == 0xFF && p
[1] == 0x03)
1012 // HDLC address header, discard in pppoe
1017 lpppoe
+= (ETH_HLEN
+ sizeof(struct pppoe_hdr
));
1018 p
-= (ETH_HLEN
+ sizeof(struct pppoe_hdr
));
1020 // 14 bytes ethernet Header + 6 bytes header pppoe
1021 setup_header(p
, config
->pppoe_hwaddr
, session
[s
].src_hwaddr
, CODE_SESS
, s
, ETH_P_PPP_SES
);
1023 if ((proto
== PPPIP
) || (proto
== PPPMP
) ||(proto
== PPPIPV6
&& config
->ipv6_prefix
.s6_addr
[0]))
1025 session
[sess
].last_packet
= session
[sess
].last_data
= time_now
;
1027 increment_counter(&session
[sess
].cin
, &session
[sess
].cin_wrap
, lpppoe
);
1028 session
[sess
].cin_delta
+= lpppoe
;
1029 session
[sess
].pin
++;
1030 sess_local
[sess
].cin
+= lpppoe
;
1031 sess_local
[sess
].pin
++;
1033 session
[s
].last_data
= time_now
;
1035 increment_counter(&session
[s
].cout
, &session
[s
].cout_wrap
, lpppoe
); // byte count
1036 session
[s
].cout_delta
+= lpppoe
;
1038 sess_local
[s
].cout
+= lpppoe
;
1039 sess_local
[s
].pout
++;
1042 session
[sess
].last_packet
= time_now
;
1044 tunnelsend(p
, lpppoe
, t
); // send it....
1047 void process_pppoe_sess(uint8_t *pack
, int size
)
1049 //struct ethhdr *ethhdr = (struct ethhdr *)pack;
1050 struct pppoe_hdr
*hdr
= (struct pppoe_hdr
*)(pack
+ ETH_HLEN
);
1051 uint16_t lppp
= ntohs(hdr
->length
);
1052 uint8_t *pppdata
= (uint8_t *) hdr
->tag
;
1053 uint16_t proto
, sid
, t
;
1055 sid
= ntohs(hdr
->sid
);
1056 t
= TUNNEL_ID_PPPOE
;
1058 LOG_HEX(5, "RCV PPPOE Sess", pack
, size
);
1060 if (sid
>= MAXSESSION
)
1062 LOG(0, sid
, t
, "Received pppoe packet with invalid session ID\n");
1063 STAT(tunnel_rx_errors
);
1067 if (session
[sid
].tunnel
!= t
)
1069 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1071 LOG(1, sid
, t
, "ERROR process_pppoe_sess: Session is not a session pppoe\n");
1077 LOG(3, sid
, t
, "Error process_pppoe_sess: discarding packet (unsupported version %i)\n", hdr
->ver
);
1083 LOG(3, sid
, t
, "Error process_pppoe_sess: discarding packet (unsupported type %i)\n", hdr
->type
);
1087 if (lppp
> 2 && pppdata
[0] == 0xFF && pppdata
[1] == 0x03)
1088 { // HDLC address header, discard
1089 LOG(5, sid
, t
, "pppoe_sess: HDLC address header, discard\n");
1095 LOG(3, sid
, t
, "Error process_pppoe_sess: Short ppp length %d\n", lppp
);
1105 proto
= ntohs(*(uint16_t *) pppdata
);
1110 if (session
[sid
].forwardtosession
)
1111 { // Must be forwaded to a remote lns tunnel l2tp
1112 pppoe_forwardto_session_rmlns(pack
, size
, sid
, proto
);
1116 if (proto
== PPPPAP
)
1118 session
[sid
].last_packet
= time_now
;
1119 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1120 processpap(sid
, t
, pppdata
, lppp
);
1122 else if (proto
== PPPCHAP
)
1124 session
[sid
].last_packet
= time_now
;
1125 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1126 processchap(sid
, t
, pppdata
, lppp
);
1128 else if (proto
== PPPLCP
)
1130 session
[sid
].last_packet
= time_now
;
1131 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1132 processlcp(sid
, t
, pppdata
, lppp
);
1134 else if (proto
== PPPIPCP
)
1136 session
[sid
].last_packet
= time_now
;
1137 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1138 processipcp(sid
, t
, pppdata
, lppp
);
1140 else if (proto
== PPPIPV6CP
&& config
->ipv6_prefix
.s6_addr
[0])
1142 session
[sid
].last_packet
= time_now
;
1143 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1144 processipv6cp(sid
, t
, pppdata
, lppp
);
1146 else if (proto
== PPPCCP
)
1148 session
[sid
].last_packet
= time_now
;
1149 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1150 processccp(sid
, t
, pppdata
, lppp
);
1152 else if (proto
== PPPIP
)
1154 session
[sid
].last_packet
= session
[sid
].last_data
= time_now
;
1155 if (session
[sid
].walled_garden
&& !config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1156 processipin(sid
, t
, pppdata
, lppp
);
1158 else if (proto
== PPPMP
)
1160 session
[sid
].last_packet
= session
[sid
].last_data
= time_now
;
1161 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1162 processmpin(sid
, t
, pppdata
, lppp
);
1164 else if (proto
== PPPIPV6
&& config
->ipv6_prefix
.s6_addr
[0])
1166 session
[sid
].last_packet
= session
[sid
].last_data
= time_now
;
1167 if (session
[sid
].walled_garden
&& !config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1168 processipv6in(sid
, t
, pppdata
, lppp
);
1170 else if (session
[sid
].ppp
.lcp
== Opened
)
1172 session
[sid
].last_packet
= time_now
;
1173 if (!config
->cluster_iam_master
) { master_forward_pppoe_packet(pack
, size
, hdr
->code
); return; }
1174 protoreject(sid
, t
, pppdata
, lppp
, proto
);
1178 LOG(3, sid
, t
, "process_pppoe_sess: Unknown PPP protocol 0x%04X received in LCP %s state\n",
1179 proto
, ppp_state(session
[sid
].ppp
.lcp
));
1183 void pppoe_send_garp()
1189 if (!*config
->pppoe_if_to_bind
)
1192 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
1195 LOG(0, 0, 0, "Error creating socket for GARP: %s\n", strerror(errno
));
1198 memset(&ifr
, 0, sizeof(ifr
));
1199 strncpy(ifr
.ifr_name
, config
->pppoe_if_to_bind
, sizeof(ifr
.ifr_name
) - 1);
1200 if (ioctl(s
, SIOCGIFHWADDR
, &ifr
) < 0)
1202 LOG(0, 0, 0, "Error getting eth0 hardware address for GARP: %s\n", strerror(errno
));
1206 memcpy(mac
, &ifr
.ifr_hwaddr
.sa_data
, 6*sizeof(char));
1207 if (ioctl(s
, SIOCGIFINDEX
, &ifr
) < 0)
1209 LOG(0, 0, 0, "Error getting eth0 interface index for GARP: %s\n", strerror(errno
));
1215 sendarp(ifr
.ifr_ifindex
, mac
, config
->iftun_address
);
1218 // rcv pppoe data from slave
1219 void pppoe_process_forward(uint8_t *pack
, int size
, in_addr_t addr
)
1221 struct ethhdr
*ethhdr
= (struct ethhdr
*)pack
;
1223 if (ethhdr
->h_proto
== htons(ETH_P_PPP_DISC
))
1224 process_pppoe_disc(pack
, size
);
1225 else if (ethhdr
->h_proto
== htons(ETH_P_PPP_SES
))
1226 process_pppoe_sess(pack
, size
);
1228 LOG(0, 0, 0, "pppoe_process_forward: I got a C_PPPOE_FORWARD from %s, but not a PPPOE data?\n", fmtaddr(addr
, 0));