diff options
Diffstat (limited to 'accel-pptpd/ctrl')
24 files changed, 0 insertions, 5711 deletions
diff --git a/accel-pptpd/ctrl/CMakeLists.txt b/accel-pptpd/ctrl/CMakeLists.txt deleted file mode 100644 index 6b37bc4a..00000000 --- a/accel-pptpd/ctrl/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -ADD_SUBDIRECTORY(pptp) -ADD_SUBDIRECTORY(pppoe) -ADD_SUBDIRECTORY(l2tp) diff --git a/accel-pptpd/ctrl/l2tp/CMakeLists.txt b/accel-pptpd/ctrl/l2tp/CMakeLists.txt deleted file mode 100644 index e0edd517..00000000 --- a/accel-pptpd/ctrl/l2tp/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -ADD_DEFINITIONS(-DDICTIONARY="${CMAKE_INSTALL_PREFIX}/share/accel-pptp/l2tp/dictionary") - -ADD_LIBRARY(l2tp SHARED - l2tp.c - dict.c - packet.c - # netlink.c -) -#TARGET_LINK_LIBRARIES(l2tp nl nl-genl) - -INSTALL(TARGETS l2tp LIBRARY DESTINATION lib/accel-pptp) - -FILE(GLOB dict "${CMAKE_CURRENT_SOURCE_DIR}/dict/*") -INSTALL(FILES ${dict} DESTINATION share/accel-pptp/l2tp) - diff --git a/accel-pptpd/ctrl/l2tp/attr_defs.h b/accel-pptpd/ctrl/l2tp/attr_defs.h deleted file mode 100644 index e7991574..00000000 --- a/accel-pptpd/ctrl/l2tp/attr_defs.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef __ATTR_DEFS_H -#define __ATTR_DEFS_H - -#define Message_Type 0 -#define Random_Vector 36 -#define Result_Code 1 -#define Protocol_Version 2 -#define Framing_Capabilities 3 -#define Bearer_Capabilities 4 -#define Tie_Breaker 5 -#define Firmware_Revision 6 -#define Host_Name 7 -#define Vendor_Name 8 -#define Assigned_Tunnel_ID 9 -#define Recv_Window_Size 10 -#define Challenge 11 -#define Challenge_Response 13 -#define Cause_Code 12 -#define Assigned_Session_ID 14 -#define Call_Serial_Number 15 -#define Minimum_BPS 16 -#define Maximum_BPS 17 -#define Bearer_Type 18 -#define Framing_Type 19 -#define Called_Number 21 -#define Calling_Number 22 -#define Sub_Address 23 -#define TX_Speed 24 -#define RX_Speed 38 -#define Physical_Channel_ID 25 -#define Private_Group_ID 37 -#define Sequencing_Required 39 -#define Init_Recv_LCP 26 -#define Last_Sent_LCP 27 -#define Last_Recv_LCP 28 -#define Proxy_Authen_Type 29 -#define Proxy_Authen_Name 30 -#define Proxy_Authen_Challenge 31 -#define Proxy_Authen_ID 32 -#define Proxy_Authen_Response 33 -#define Call_Errors 34 -#define ACCM 35 -#define Message_Type_Start_Ctrl_Conn_Request 1 -#define Message_Type_Start_Ctrl_Conn_Reply 2 -#define Message_Type_Start_Ctrl_Conn_Connected 3 -#define Message_Type_Stop_Ctrl_Conn_Notify 4 -#define Message_Type_Hello 6 -#define Message_Type_Outgoing_Call_Request 7 -#define Message_Type_Outgoing_Call_Reply 8 -#define Message_Type_Outgoing_Call_Connected 9 -#define Message_Type_Incoming_Call_Request 10 -#define Message_Type_Incoming_Call_Reply 11 -#define Message_Type_Incoming_Call_Connected 12 -#define Message_Type_Call_Disconnect_Notify 14 -#define Message_Type_WAN_Error_Notify 15 -#define Message_Type_Set_Link_Info 16 -#define Message_Digest 59 -#define Router_ID 60 -#define Assigned_Connection_ID 61 -#define Pseudowire_Capabilities 62 -#define Prefered_Language 72 -#define Local_Session_ID 63 -#define Remote_Session_ID 64 -#define Assigned_Cookie 65 -#define Remote_End_ID 66 -#define Pseudowire_Type 68 -#define L2_Specific_Sublayer 69 -#define Data_Sequencing 70 -#define TX_Connect_Speeed 74 -#define RX_Connect_Speeed 75 -#define Circuit_Status 71 - -#endif diff --git a/accel-pptpd/ctrl/l2tp/dict.c b/accel-pptpd/ctrl/l2tp/dict.c deleted file mode 100644 index c93ccd48..00000000 --- a/accel-pptpd/ctrl/l2tp/dict.c +++ /dev/null @@ -1,271 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <unistd.h> - -#include "list.h" -#include "l2tp.h" -#include "log.h" -#include "triton.h" - -#include "memdebug.h" - -struct l2tp_dict_t -{ - struct list_head items; -}; - -static struct l2tp_dict_t *dict; - -#define BUF_SIZE 1024 -static char *path, *fname1, *buf; - -struct l2tp_dict_attr_t *l2tp_dict_find_attr_by_name(const char *name) -{ - struct l2tp_dict_attr_t *attr; - - list_for_each_entry(attr, &dict->items, entry) { - if (!strcmp(attr->name, name)) - return attr; - } - - return NULL; -} - -struct l2tp_dict_attr_t *l2tp_dict_find_attr_by_id(int id) -{ - struct l2tp_dict_attr_t *attr; - - list_for_each_entry(attr, &dict->items, entry) { - if (attr->id == id) - return attr; - } - - return NULL; -} - -struct l2tp_dict_value_t *l2tp_dict_find_value(struct l2tp_dict_attr_t *attr, l2tp_value_t val) -{ - struct l2tp_dict_value_t *v; - - list_for_each_entry(v, &attr->values, entry) { - switch (attr->type) { - case ATTR_TYPE_INT16: - if (v->val.int16 == val.int16) - return v; - break; - case ATTR_TYPE_INT32: - if (v->val.int32 == val.int32) - return v; - break; - } - } - - return NULL; -} - -static char *skip_word(char *ptr) -{ - for(; *ptr; ptr++) - if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') - break; - return ptr; -} - -static char *skip_space(char *ptr) -{ - for(; *ptr; ptr++) - if (*ptr != ' ' && *ptr != '\t') - break; - return ptr; -} - -static int split(char *buf, char **ptr) -{ - int i; - - for (i = 0; i < 6; i++) { - buf = skip_word(buf); - if (!*buf) - return i; - - *buf = 0; - - buf = skip_space(buf + 1); - if (!*buf) - return i; - - ptr[i] = buf; - } - - buf = skip_word(buf); - //if (*buf == '\n') - *buf = 0; - //else if (*buf) - // return -1; - - return i; -} - - -static int dict_load(const char *fname) -{ - FILE *f; - char *ptr[6], *endptr; - struct l2tp_dict_attr_t *attr; - struct l2tp_dict_value_t *value; - struct list_head *items; - int i, r, n = 0; - - f = fopen(fname, "r"); - if (!f) { - log_emerg("l2tp: open '%s': %s\n", fname, strerror(errno)); - return -1; - } - - items = &dict->items; - while (fgets(buf, BUF_SIZE, f)) { - n++; - if (buf[0] == '#' || buf[0] == '\n' || buf[0] == 0) - continue; - - r = split(buf, ptr); - - if (!strcmp(buf, "$INCLUDE")) { - if (r != 1) - goto out_syntax; - - for (i = strlen(path) - 1; i; i--) { - if (path[i] == '/') { - path[i + 1] = 0; - break; - } - } - - strcpy(fname1, path); - strcat(fname1, ptr[0]); - - if (dict_load(fname1)) - goto out_err; - } else if (!strcmp(buf, "ATTRIBUTE")) { - if (r < 3) - goto out_syntax; - - attr = malloc(sizeof(*attr)); - memset(attr, 0, sizeof(*attr)); - list_add_tail(&attr->entry, items); - INIT_LIST_HEAD(&attr->values); - - attr->name = strdup(ptr[0]); - attr->id = strtol(ptr[1], &endptr, 10); - if (*endptr != 0) - goto out_syntax; - - if (!strcmp(ptr[2], "none")) - attr->type = ATTR_TYPE_NONE; - else if (!strcmp(ptr[2], "int16")) - attr->type = ATTR_TYPE_INT16; - else if (!strcmp(ptr[2], "int32")) - attr->type = ATTR_TYPE_INT32; - else if (!strcmp(ptr[2], "int64")) - attr->type = ATTR_TYPE_INT64; - else if (!strcmp(ptr[2], "octets")) - attr->type = ATTR_TYPE_OCTETS; - else if (!strcmp(ptr[2], "string")) - attr->type = ATTR_TYPE_STRING; - else - goto out_syntax; - - attr->M = -1; - attr->H = -1; - - for (i = 3; i < r; i++) { - if (!strcmp(ptr[i], "M=0")) - attr->M = 0; - else if (!strcmp(ptr[i], "M=1")) - attr->M = 1; - else if (!strcmp(ptr[i], "H=0")) - attr->H = 0; - else if (!strcmp(ptr[i], "H=1")) - attr->H = 1; - else - goto out_syntax; - } - } else if (!strcmp(buf, "VALUE")) { - if (r != 3) - goto out_syntax; - - attr = l2tp_dict_find_attr_by_name(ptr[0]); - if (!attr) { - log_emerg("l2tp:%s:%i: attribute not found\n", fname, n); - goto out_err; - } - - value = malloc(sizeof(*value)); - memset(value, 0, sizeof(*value)); - list_add_tail(&value->entry, &attr->values); - - value->name = strdup(ptr[1]); - switch (attr->type) { - case ATTR_TYPE_INT16: - case ATTR_TYPE_INT32: - value->val.int16 = strtol(ptr[2], &endptr, 10); - if (*endptr != 0) - goto out_syntax; - break; - case ATTR_TYPE_STRING: - value->val.string = strdup(ptr[2]); - break; - } - } else - goto out_syntax; - } - - fclose(f); - - return 0; - -out_syntax: - log_emerg("l2tp:%s:%i: syntaxis error\n", fname, n); -out_err: - fclose(f); - return -1; -} - -static int l2tp_dict_load(const char *fname) -{ - int r; - - dict = _malloc(sizeof(*dict)); - memset(dict, 0, sizeof(*dict)); - INIT_LIST_HEAD(&dict->items); - - path = _malloc(PATH_MAX); - fname1 = _malloc(PATH_MAX); - buf = _malloc(BUF_SIZE); - - strcpy(path, fname); - - r = dict_load(fname); - - _free(buf); - _free(fname1); - _free(path); - - return r; -} - -static void __init dict_init(void) -{ - char *opt; - - opt = conf_get_opt("l2tp", "dictionary"); - if (!opt) - opt = DICTIONARY; - - if (l2tp_dict_load(opt)) - _exit(EXIT_FAILURE); -} - diff --git a/accel-pptpd/ctrl/l2tp/dict/dictionary b/accel-pptpd/ctrl/l2tp/dict/dictionary deleted file mode 100644 index f5d7c423..00000000 --- a/accel-pptpd/ctrl/l2tp/dict/dictionary +++ /dev/null @@ -1,2 +0,0 @@ -$INCLUDE dictionary.rfc2661 -$INCLUDE dictionary.rfc3931 diff --git a/accel-pptpd/ctrl/l2tp/dict/dictionary.rfc2661 b/accel-pptpd/ctrl/l2tp/dict/dictionary.rfc2661 deleted file mode 100644 index 3fd9614e..00000000 --- a/accel-pptpd/ctrl/l2tp/dict/dictionary.rfc2661 +++ /dev/null @@ -1,55 +0,0 @@ -ATTRIBUTE Message-Type 0 int16 H=0 -ATTRIBUTE Random-Vector 36 octets M=1 H=0 -ATTRIBUTE Result-Code 1 octets M=1 H=0 -ATTRIBUTE Protocol-Version 2 int16 M=1 H=0 -ATTRIBUTE Framing-Capabilities 3 int32 M=1 -ATTRIBUTE Bearer-Capabilities 4 int32 M=1 -ATTRIBUTE Tie-Breaker 5 int64 M=0 -ATTRIBUTE Firmware-Revision 6 int16 M=0 -ATTRIBUTE Host-Name 7 string M=1 -ATTRIBUTE Vendor-Name 8 string M=0 -ATTRIBUTE Assigned-Tunnel-ID 9 int16 M=1 -ATTRIBUTE Recv-Window-Size 10 int16 M=1 -ATTRIBUTE Challenge 11 octets M=1 -ATTRIBUTE Challenge-Response 13 octets M=1 -ATTRIBUTE Cause-Code 12 int32 M=1 H=0 -ATTRIBUTE Assigned-Session-ID 14 int16 M=1 -ATTRIBUTE Call-Serial-Number 15 int32 M=1 -ATTRIBUTE Minimum-BPS 16 int32 M=1 -ATTRIBUTE Maximum-BPS 17 int32 M=1 -ATTRIBUTE Bearer-Type 18 int32 M=1 -ATTRIBUTE Framing-Type 19 int32 M=1 -ATTRIBUTE Called-Number 21 string M=1 -ATTRIBUTE Calling-Number 22 string M=1 -ATTRIBUTE Sub-Address 23 string M=1 -ATTRIBUTE TX-Speed 24 int32 M=1 -ATTRIBUTE RX-Speed 38 int32 M=1 -ATTRIBUTE Physical-Channel-ID 25 int32 M=0 -ATTRIBUTE Private-Group-ID 37 int32 M=0 -ATTRIBUTE Sequencing-Required 39 none M=1 H=0 -ATTRIBUTE Init-Recv-LCP 26 octets M=0 -ATTRIBUTE Last-Sent-LCP 27 octets M=0 -ATTRIBUTE Last-Recv-LCP 28 octets M=0 -ATTRIBUTE Proxy-Authen-Type 29 int16 M=0 -ATTRIBUTE Proxy-Authen-Name 30 string M=0 -ATTRIBUTE Proxy-Authen-Challenge 31 octets M=0 -ATTRIBUTE Proxy-Authen-ID 32 int16 M=0 -ATTRIBUTE Proxy-Authen-Response 33 octets M=0 -ATTRIBUTE Call-Errors 34 octets M=1 -ATTRIBUTE ACCM 35 octets M=1 - -VALUE Message-Type Start-Ctrl-Conn-Request 1 -VALUE Message-Type Start-Ctrl-Conn-Reply 2 -VALUE Message-Type Start-Ctrl-Conn-Connected 3 -VALUE Message-Type Stop-Ctrl-Conn-Notify 4 -VALUE Message-Type Hello 6 -VALUE Message-Type Outgoing-Call-Request 7 -VALUE Message-Type Outgoing-Call-Reply 8 -VALUE Message-Type Outgoing-Call-Connected 9 -VALUE Message-Type Incoming-Call-Request 10 -VALUE Message-Type Incoming-Call-Reply 11 -VALUE Message-Type Incoming-Call-Connected 12 -VALUE Message-Type Call-Disconnect-Notify 14 -VALUE Message-Type WAN-Error-Notify 15 -VALUE Message-Type Set-Link-Info 16 - diff --git a/accel-pptpd/ctrl/l2tp/dict/dictionary.rfc3931 b/accel-pptpd/ctrl/l2tp/dict/dictionary.rfc3931 deleted file mode 100644 index d6ad410b..00000000 --- a/accel-pptpd/ctrl/l2tp/dict/dictionary.rfc3931 +++ /dev/null @@ -1,15 +0,0 @@ -ATTRIBUTE Message-Digest 59 octets M=1 H=0 -ATTRIBUTE Router-ID 60 int32 H=0 -ATTRIBUTE Assigned-Connection-ID 61 int32 -ATTRIBUTE Pseudowire-Capabilities 62 octets -ATTRIBUTE Prefered-Language 72 octets -ATTRIBUTE Local-Session-ID 63 int32 -ATTRIBUTE Remote-Session-ID 64 int32 -ATTRIBUTE Assigned-Cookie 65 octets -ATTRIBUTE Remote-End-ID 66 octets -ATTRIBUTE Pseudowire-Type 68 int16 -ATTRIBUTE L2-Specific-Sublayer 69 int16 -ATTRIBUTE Data-Sequencing 70 int16 -ATTRIBUTE TX-Connect-Speeed 74 int64 -ATTRIBUTE RX-Connect-Speeed 75 int64 -ATTRIBUTE Circuit-Status 71 int16 diff --git a/accel-pptpd/ctrl/l2tp/dict2c.py b/accel-pptpd/ctrl/l2tp/dict2c.py deleted file mode 100644 index ff0961e7..00000000 --- a/accel-pptpd/ctrl/l2tp/dict2c.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys,re - -hdr = file(sys.argv[2],'w') - -def process(fname, hdr): - for line in file(fname): - if line[:-1].strip() == '': - continue - if line[0] == '#': - continue - f = re.compile('[$.a-zA-Z0-9\-]+').findall(line) - if f[0] == 'ATTRIBUTE' or f[0] == 'VENDOR': - hdr.write('#define {0} {1}\n'.format(f[1].replace('-','_').replace('.','_'), f[2])) - elif f[0] == 'VALUE': - hdr.write('#define {0}_{1} {2}\n'.format(f[1].replace('-','_').replace('.','_'), f[2].replace('-','_'),f[3])) - elif f[0] == '$INCLUDE': - process(f[1], hdr) - -if __name__ == '__main__': - process(sys.argv[1], hdr) diff --git a/accel-pptpd/ctrl/l2tp/l2tp.c b/accel-pptpd/ctrl/l2tp/l2tp.c deleted file mode 100644 index ca56051b..00000000 --- a/accel-pptpd/ctrl/l2tp/l2tp.c +++ /dev/null @@ -1,1141 +0,0 @@ -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <pthread.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <linux/socket.h> -#include <linux/if.h> -#include <linux/if_ether.h> -#include <linux/if_pppox.h> - -#include "triton.h" -#include "mempool.h" -#include "log.h" -#include "ppp.h" -#include "events.h" -#include "utils.h" -#include "iprange.h" -#include "cli.h" - -#include "memdebug.h" - -#include "l2tp.h" -#include "attr_defs.h" - -#ifndef SOL_PPPOL2TP -#define SOL_PPPOL2TP 273 -#endif - -#define STATE_WAIT_SCCCN 1 -#define STATE_WAIT_ICRQ 2 -#define STATE_WAIT_ICCN 3 -#define STATE_WAIT_OCRP 4 -#define STATE_WAIT_OCCN 5 -#define STATE_ESTB 6 -#define STATE_PPP 7 -#define STATE_FIN 8 -#define STATE_CLOSE 0 - -int conf_verbose = 0; -int conf_timeout = 60; -int conf_rtimeout = 5; -int conf_retransmit = 5; -int conf_hello_interval = 60; -char *conf_host_name = NULL; - -static unsigned int stat_active; -static unsigned int stat_starting; - -struct l2tp_serv_t -{ - struct triton_context_t ctx; - struct triton_md_handler_t hnd; - struct sockaddr_in addr; -}; - -struct l2tp_conn_t -{ - struct triton_context_t ctx; - struct triton_md_handler_t hnd; - struct triton_timer_t timeout_timer; - struct triton_timer_t rtimeout_timer; - struct triton_timer_t hello_timer; - - int tunnel_fd; - - struct sockaddr_in addr; - uint16_t tid; - uint16_t sid; - uint16_t peer_tid; - uint16_t peer_sid; - uint32_t framing_cap; - - int retransmit; - uint16_t Ns, Nr; - struct list_head send_queue; - - int state; - int state1; - int state2; - - struct ppp_ctrl_t ctrl; - struct ppp_t ppp; -}; - -static pthread_mutex_t l2tp_lock = PTHREAD_MUTEX_INITIALIZER; -static struct l2tp_conn_t **l2tp_conn; -static uint16_t l2tp_tid; - -static mempool_t l2tp_conn_pool; - -static void l2tp_timeout(struct triton_timer_t *t); -static void l2tp_rtimeout(struct triton_timer_t *t); -static void l2tp_send_HELLO(struct triton_timer_t *t); -static void l2tp_send_SCCRP(struct l2tp_conn_t *conn); -static int l2tp_send(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack, int log_debug); -static int l2tp_conn_read(struct triton_md_handler_t *); - -static void l2tp_disconnect(struct l2tp_conn_t *conn) -{ - struct l2tp_packet_t *pack; - - triton_md_unregister_handler(&conn->hnd); - close(conn->hnd.fd); - - if (conn->timeout_timer.tpd) - triton_timer_del(&conn->timeout_timer); - - if (conn->rtimeout_timer.tpd) - triton_timer_del(&conn->rtimeout_timer); - - if (conn->hello_timer.tpd) - triton_timer_del(&conn->hello_timer); - - if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - conn->state = STATE_FIN; - ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } else if (conn->state != STATE_FIN) - __sync_sub_and_fetch(&stat_starting, 1); - - pthread_mutex_lock(&l2tp_lock); - l2tp_conn[conn->tid] = NULL; - pthread_mutex_unlock(&l2tp_lock); - - if (conn->ppp.fd != -1) - close(conn->ppp.fd); - - if (conn->tunnel_fd != -1) - close(conn->tunnel_fd); - - triton_event_fire(EV_CTRL_FINISHED, &conn->ppp); - - log_ppp_info1("disconnected\n"); - - triton_context_unregister(&conn->ctx); - - while (!list_empty(&conn->send_queue)) { - pack = list_entry(conn->send_queue.next, typeof(*pack), entry); - list_del(&pack->entry); - l2tp_packet_free(pack); - } - - if (conn->ppp.chan_name) - _free(conn->ppp.chan_name); - - _free(conn->ctrl.calling_station_id); - _free(conn->ctrl.called_station_id); - - mempool_free(conn); -} - -static int l2tp_terminate(struct l2tp_conn_t *conn, int res, int err) -{ - struct l2tp_packet_t *pack; - struct l2tp_avp_result_code rc = {res, err}; - - log_ppp_debug("l2tp: terminate (%i, %i)\n", res, err); - - pack = l2tp_packet_alloc(2, Message_Type_Stop_Ctrl_Conn_Notify, &conn->addr); - if (!pack) - return -1; - - if (l2tp_packet_add_int16(pack, Assigned_Tunnel_ID, conn->tid, 1)) - goto out_err; - if (l2tp_packet_add_octets(pack, Result_Code, (uint8_t *)&rc, sizeof(rc), 0)) - goto out_err; - - l2tp_send(conn, pack, 0); - - conn->state = STATE_FIN; - - return 0; - -out_err: - l2tp_packet_free(pack); - return -1; -} - -static void l2tp_ppp_started(struct ppp_t *ppp) -{ - struct l2tp_conn_t *conn = container_of(ppp, typeof(*conn), ppp); - - log_ppp_debug("l2tp: ppp started\n"); - - if (conf_hello_interval) - triton_timer_add(&conn->ctx, &conn->hello_timer, 0); -} - -static void l2tp_ppp_finished(struct ppp_t *ppp) -{ - struct l2tp_conn_t *conn = container_of(ppp, typeof(*conn), ppp); - - log_ppp_debug("l2tp: ppp finished\n"); - - if (conn->state != STATE_FIN) { - __sync_sub_and_fetch(&stat_active, 1); - if (l2tp_terminate(conn, 0, 0)) - triton_context_call(&conn->ctx, (triton_event_func)l2tp_disconnect, conn); - } -} - -static void l2tp_conn_close(struct triton_context_t *ctx) -{ - struct l2tp_conn_t *conn = container_of(ctx, typeof(*conn), ctx); - - if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - conn->state = STATE_FIN; - ppp_terminate(&conn->ppp, TERM_ADMIN_RESET, 1); - } - - if (l2tp_terminate(conn, 0, 0)) - l2tp_disconnect(conn); -} - -static int l2tp_tunnel_alloc(struct l2tp_serv_t *serv, struct l2tp_packet_t *pack, struct in_pktinfo *pkt_info, struct l2tp_attr_t *assigned_tid, struct l2tp_attr_t *framing_cap) -{ - struct l2tp_conn_t *conn; - struct sockaddr_in addr; - uint16_t tid; - //char *opt; - int flag = 1; - - conn = mempool_alloc(l2tp_conn_pool); - if (!conn) { - log_emerg("l2tp: out of memory\n"); - return -1; - } - - memset(conn, 0, sizeof(*conn)); - INIT_LIST_HEAD(&conn->send_queue); - - conn->hnd.fd = socket(PF_INET, SOCK_DGRAM, 0); - if (conn->hnd.fd < 0) { - log_error("l2tp: socket: %s\n", strerror(errno)); - mempool_free(conn); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = pkt_info->ipi_addr; - addr.sin_port = htons(L2TP_PORT); - - setsockopt(conn->hnd.fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); - if (bind(conn->hnd.fd, &addr, sizeof(addr))) { - log_error("l2tp: bind: %s\n", strerror(errno)); - goto out_err; - } - - if (connect(conn->hnd.fd, (struct sockaddr *)&pack->addr, sizeof(addr))) { - log_error("l2tp: connect: %s\n", strerror(errno)); - goto out_err; - } - - if (fcntl(conn->hnd.fd, F_SETFL, O_NONBLOCK)) { - log_emerg("l2tp: failed to set nonblocking mode: %s\n", strerror(errno)); - goto out_err; - } - - pthread_mutex_lock(&l2tp_lock); - for (tid = l2tp_tid + 1; tid != l2tp_tid; tid++) { - if (tid == L2TP_MAX_TID) - tid = 1; - if (!l2tp_conn[tid]) { - l2tp_conn[tid] = conn; - conn->tid = tid; - break; - } - } - pthread_mutex_unlock(&l2tp_lock); - - if (!conn->tid) { - if (conf_verbose) - log_warn("l2tp: no free tid available\n"); - mempool_free(conn); - return -1; - } - - conn->sid = 1; - - memcpy(&conn->addr, &pack->addr, sizeof(pack->addr)); - conn->peer_tid = assigned_tid->val.uint16; - conn->framing_cap = framing_cap->val.uint32; - - conn->ctx.before_switch = log_switch; - conn->ctx.close = l2tp_conn_close; - conn->hnd.read = l2tp_conn_read; - conn->timeout_timer.expire = l2tp_timeout; - conn->timeout_timer.period = conf_timeout * 1000; - conn->rtimeout_timer.expire = l2tp_rtimeout; - conn->rtimeout_timer.period = conf_rtimeout * 1000; - conn->hello_timer.expire = l2tp_send_HELLO; - conn->hello_timer.period = conf_hello_interval * 1000; - conn->ctrl.ctx = &conn->ctx; - conn->ctrl.name = "l2tp"; - conn->ctrl.started = l2tp_ppp_started; - conn->ctrl.finished = l2tp_ppp_finished; - conn->ctrl.max_mtu = 1420; - - conn->ctrl.calling_station_id = _malloc(17); - conn->ctrl.called_station_id = _malloc(17); - u_inet_ntoa(conn->addr.sin_addr.s_addr, conn->ctrl.calling_station_id); - u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id); - - ppp_init(&conn->ppp); - conn->ppp.ctrl = &conn->ctrl; - conn->ppp.fd = -1; - conn->tunnel_fd = -1; - - triton_context_register(&conn->ctx, &conn->ppp); - triton_md_register_handler(&conn->ctx, &conn->hnd); - triton_md_enable_handler(&conn->hnd, MD_MODE_READ); - triton_context_wakeup(&conn->ctx); - - if (conf_verbose) { - log_switch(&conn->ctx, &conn->ppp); - log_ppp_info2("recv "); - l2tp_packet_print(pack, log_ppp_info2); - } - - triton_context_call(&conn->ctx, (triton_event_func)l2tp_send_SCCRP, conn); - - __sync_add_and_fetch(&stat_starting, 1); - - return 0; - -out_err: - close(conn->hnd.fd); - mempool_free(conn); - return -1; -} - -static int l2tp_connect(struct l2tp_conn_t *conn) -{ - struct sockaddr_pppol2tp pppox_addr; - int arg = 1; - - memset(&pppox_addr, 0, sizeof(pppox_addr)); - pppox_addr.sa_family = AF_PPPOX; - pppox_addr.sa_protocol = PX_PROTO_OL2TP; - pppox_addr.pppol2tp.fd = conn->hnd.fd; - memcpy(&pppox_addr.pppol2tp.addr, &conn->addr, sizeof(conn->addr)); - pppox_addr.pppol2tp.s_tunnel = conn->tid; - pppox_addr.pppol2tp.d_tunnel = conn->peer_tid; - - conn->tunnel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); - if (!conn->ppp.fd) { - log_ppp_error("l2tp: socket(AF_PPPOX): %s\n", strerror(errno)); - return -1; - } - - conn->ppp.fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); - if (!conn->ppp.fd) { - close(conn->tunnel_fd); - conn->tunnel_fd = -1; - log_ppp_error("l2tp: socket(AF_PPPOX): %s\n", strerror(errno)); - return -1; - } - - if (connect(conn->tunnel_fd, (struct sockaddr *)&pppox_addr, sizeof(pppox_addr)) < 0) { - log_ppp_error("l2tp: connect(tunnel): %s\n", strerror(errno)); - return -1; - } - - pppox_addr.pppol2tp.s_session = conn->sid; - pppox_addr.pppol2tp.d_session = conn->peer_sid; - - if (connect(conn->ppp.fd, (struct sockaddr *)&pppox_addr, sizeof(pppox_addr)) < 0) { - log_ppp_error("l2tp: connect(session): %s\n", strerror(errno)); - return -1; - } - - if (setsockopt(conn->ppp.fd, SOL_PPPOL2TP, PPPOL2TP_SO_LNSMODE, &arg, sizeof(arg))) { - log_ppp_error("l2tp: setsockopt: %s\n", strerror(errno)); - return -1; - } - - conn->ppp.chan_name = _strdup(inet_ntoa(conn->addr.sin_addr)); - - triton_event_fire(EV_CTRL_STARTED, &conn->ppp); - - if (establish_ppp(&conn->ppp)) - return -1; - - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_active, 1); - - conn->state = STATE_PPP; - - return 0; -} - -static void l2tp_rtimeout(struct triton_timer_t *t) -{ - struct l2tp_conn_t *conn = container_of(t, typeof(*conn), rtimeout_timer); - struct l2tp_packet_t *pack; - - if (!list_empty(&conn->send_queue)) { - log_ppp_debug("l2tp: retransmit (%i)\n", conn->retransmit); - if (++conn->retransmit <= conf_retransmit) { - pack = list_entry(conn->send_queue.next, typeof(*pack), entry); - pack->hdr.Nr = htons(conn->Nr + 1); - if (conf_verbose) { - log_ppp_debug("send "); - l2tp_packet_print(pack, log_ppp_debug); - } - if (l2tp_packet_send(conn->hnd.fd, pack) == 0) - return; - } else - l2tp_disconnect(conn); - } -} - -static void l2tp_timeout(struct triton_timer_t *t) -{ - struct l2tp_conn_t *conn = container_of(t, typeof(*conn), timeout_timer); - log_ppp_debug("l2tp: timeout\n"); - l2tp_disconnect(conn); -} - -static int l2tp_send(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack, int log_debug) -{ - conn->retransmit = 0; - - pack->hdr.tid = htons(conn->peer_tid); - //pack->hdr.sid = htons(conn->peer_sid); - pack->hdr.Nr = htons(conn->Nr + 1); - pack->hdr.Ns = htons(conn->Ns); - - if (!list_empty(&pack->attrs)) - conn->Ns++; - - if (conf_verbose) { - if (log_debug) { - log_ppp_debug("send "); - l2tp_packet_print(pack, log_ppp_debug); - } else { - log_ppp_info2("send "); - l2tp_packet_print(pack, log_ppp_info2); - } - } - - if (l2tp_packet_send(conn->hnd.fd, pack)) - goto out_err; - - if (!list_empty(&pack->attrs)) { - list_add_tail(&pack->entry, &conn->send_queue); - if (!conn->rtimeout_timer.tpd) - triton_timer_add(&conn->ctx, &conn->rtimeout_timer, 0); - } else - l2tp_packet_free(pack); - - return 0; - -out_err: - l2tp_packet_free(pack); - return -1; -} - -static int l2tp_send_ZLB(struct l2tp_conn_t *conn) -{ - struct l2tp_packet_t *pack; - - pack = l2tp_packet_alloc(2, 0, &conn->addr); - if (!pack) - return -1; - - if (l2tp_send(conn, pack, 1)) - return -1; - - return 0; -} - -static void l2tp_send_HELLO(struct triton_timer_t *t) -{ - struct l2tp_conn_t *conn = container_of(t, typeof(*conn), hello_timer); - struct l2tp_packet_t *pack; - - pack = l2tp_packet_alloc(2, Message_Type_Hello, &conn->addr); - if (!pack) { - l2tp_disconnect(conn); - return; - } - - if (l2tp_send(conn, pack, 1)) - l2tp_disconnect(conn); -} - -static void l2tp_send_SCCRP(struct l2tp_conn_t *conn) -{ - struct l2tp_packet_t *pack; - - pack = l2tp_packet_alloc(2, Message_Type_Start_Ctrl_Conn_Reply, &conn->addr); - if (!pack) - goto out; - - if (l2tp_packet_add_int16(pack, Protocol_Version, L2TP_V2_PROTOCOL_VERSION, 1)) - goto out_err; - if (conf_host_name && l2tp_packet_add_string(pack, Host_Name, conf_host_name, 1)) - goto out_err; - if (l2tp_packet_add_int32(pack, Framing_Capabilities, conn->framing_cap, 1)) - goto out_err; - if (l2tp_packet_add_int16(pack, Assigned_Tunnel_ID, conn->tid, 1)) - goto out_err; - - if (l2tp_send(conn, pack, 0)) - goto out; - - if (!conn->timeout_timer.tpd) - triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); - else - triton_timer_mod(&conn->timeout_timer, 0); - - conn->state = STATE_WAIT_SCCCN; - - return; - -out_err: - l2tp_packet_free(pack); -out: - l2tp_disconnect(conn); -} - -static int l2tp_send_ICRP(struct l2tp_conn_t *conn) -{ - struct l2tp_packet_t *pack; - - pack = l2tp_packet_alloc(2, Message_Type_Incoming_Call_Reply, &conn->addr); - if (!pack) - return -1; - - pack->hdr.sid = htons(conn->peer_sid); - - if (l2tp_packet_add_int16(pack, Assigned_Session_ID, conn->sid, 1)) - goto out_err; - - l2tp_send(conn, pack, 0); - - if (!conn->timeout_timer.tpd) - triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); - else - triton_timer_mod(&conn->timeout_timer, 0); - - conn->state1 = STATE_WAIT_ICCN; - - return 0; - -out_err: - l2tp_packet_free(pack); - return -1; -} - -static int l2tp_send_OCRQ(struct l2tp_conn_t *conn) -{ - struct l2tp_packet_t *pack; - - pack = l2tp_packet_alloc(2, Message_Type_Outgoing_Call_Request, &conn->addr); - if (!pack) - return -1; - - pack->hdr.sid = htons(conn->peer_sid); - - if (l2tp_packet_add_int16(pack, Assigned_Session_ID, conn->sid, 1)) - goto out_err; - if (l2tp_packet_add_int32(pack, Call_Serial_Number, 0, 1)) - goto out_err; - if (l2tp_packet_add_int32(pack, Minimum_BPS, 100, 1)) - goto out_err; - if (l2tp_packet_add_int32(pack, Maximum_BPS, 100000, 1)) - goto out_err; - if (l2tp_packet_add_int32(pack, Bearer_Type, 3, 1)) - goto out_err; - if (l2tp_packet_add_int32(pack, Framing_Type, 3, 1)) - goto out_err; - if (l2tp_packet_add_string(pack, Called_Number, "", 1)) - goto out_err; - - if (l2tp_send(conn, pack, 0)) - return -1; - - if (!conn->timeout_timer.tpd) - triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); - else - triton_timer_mod(&conn->timeout_timer, 0); - - conn->state2 = STATE_WAIT_OCRP; - - return 0; - -out_err: - l2tp_packet_free(pack); - return -1; -} - - -static int l2tp_recv_SCCRQ(struct l2tp_serv_t *serv, struct l2tp_packet_t *pack, struct in_pktinfo *pkt_info) -{ - struct l2tp_attr_t *attr; - struct l2tp_attr_t *protocol_version = NULL; - struct l2tp_attr_t *assigned_tid = NULL; - struct l2tp_attr_t *assigned_cid = NULL; - struct l2tp_attr_t *framing_cap = NULL; - struct l2tp_attr_t *router_id = NULL; - - if (ppp_shutdown) - return 0; - - list_for_each_entry(attr, &pack->attrs, entry) { - switch (attr->attr->id) { - case Protocol_Version: - protocol_version = attr; - break; - case Framing_Capabilities: - framing_cap = attr; - break; - case Assigned_Tunnel_ID: - assigned_tid = attr; - break; - case Challenge: - if (conf_verbose) - log_warn("l2tp: Challenge in SCCRQ is not supported\n"); - return -1; - case Assigned_Connection_ID: - assigned_cid = attr; - break; - case Router_ID: - router_id = attr; - break; - case Message_Digest: - if (conf_verbose) - log_warn("l2tp: Message-Digest is not supported\n"); - return -1; - } - } - - if (assigned_tid) { - if (!protocol_version) { - if (conf_verbose) - log_warn("l2tp: SCCRQ: no Protocol-Version present in message\n"); - return -1; - } - if (protocol_version->val.uint16 != L2TP_V2_PROTOCOL_VERSION) { - if (conf_verbose) - log_warn("l2tp: protocol version %02x is not supported\n", protocol_version->val.uint16); - return -1; - } - if (!framing_cap) { - if (conf_verbose) - log_warn("l2tp: SCCRQ: no Framing-Capabilities present in message\n"); - return -1; - } - - if (l2tp_tunnel_alloc(serv, pack, pkt_info, assigned_tid, framing_cap)) - return -1; - - } else if (assigned_cid) { - // not yet implemented - return 0; - } else { - if (conf_verbose) - log_warn("l2tp: SCCRQ: no Assigned-Tunnel-ID or Assigned-Connection-ID present in message\n"); - return -1; - } - - return 0; -} - -static int l2tp_recv_SCCCN(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - if (conn->state == STATE_WAIT_SCCCN) { - triton_timer_mod(&conn->timeout_timer, 0); - conn->state = STATE_ESTB; - conn->state1 = STATE_WAIT_ICRQ; - } - else - log_ppp_warn("l2tp: unexpected SCCCN\n"); - - return 0; -} - -static int l2tp_recv_StopCCN(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - l2tp_send_ZLB(conn); - return -1; -} - -static int l2tp_recv_HELLO(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - if (l2tp_send_ZLB(conn)) - return -1; - - return 0; -} - -static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - struct l2tp_attr_t *attr; - struct l2tp_attr_t *assigned_sid = NULL; - - if (conn->state1 != STATE_WAIT_ICRQ) { - log_ppp_warn("l2tp: unexpected ICRQ\n"); - return 0; - } - - list_for_each_entry(attr, &pack->attrs, entry) { - switch(attr->attr->id) { - case Assigned_Session_ID: - assigned_sid = attr; - break; - case Message_Type: - case Call_Serial_Number: - case Bearer_Type: - case Calling_Number: - case Called_Number: - case Sub_Address: - case Physical_Channel_ID: - break; - default: - if (attr->M) { - if (conf_verbose) { - log_ppp_warn("l2tp: ICRQ: unknown attribute %i\n", attr->attr->id); - if (l2tp_terminate(conn, 2, 8)) - return -1; - return 0; - } - } - } - } - - if (!assigned_sid) { - if (conf_verbose) - log_ppp_warn("l2tp: ICRQ: no Assigned-Session-ID attribute present in message\n"); - if (l2tp_terminate(conn, 2, 0)) - return -1; - } - - conn->peer_sid = assigned_sid->val.uint16; - - if (l2tp_send_ICRP(conn)) - return -1; - - if (l2tp_send_OCRQ(conn)) - return -1; - - return 0; -} - -static int l2tp_recv_ICCN(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - if (conn->state1 != STATE_WAIT_ICCN) { - log_ppp_warn("l2tp: unexpected ICCN\n"); - return 0; - } - - conn->state1 = STATE_ESTB; - - if (l2tp_connect(conn)) { - if (l2tp_terminate(conn, 2, 0)) - return -1; - return 0; - } - - if (l2tp_send_ZLB(conn)) - return -1; - - triton_timer_del(&conn->timeout_timer); - - return 0; -} - -static int l2tp_recv_OCRP(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - if (conn->state2 != STATE_WAIT_OCRP) { - log_ppp_warn("l2tp: unexpected OCRP\n"); - return 0; - } - - conn->state2 = STATE_WAIT_OCCN; - - return 0; -} - -static int l2tp_recv_OCCN(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - if (conn->state2 != STATE_WAIT_OCCN) { - log_ppp_warn("l2tp: unexpected OCCN\n"); - return 0; - } - - conn->state2 = STATE_ESTB; - - return 0; -} - -static int l2tp_recv_CDN(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - if (ntohs(pack->hdr.sid) != conn->sid) { - if (conf_verbose) - log_warn("l2tp: sid %i is incorrect\n", ntohs(pack->hdr.sid)); - return 0; - } - - if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - conn->state = STATE_FIN; - ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } - - if (l2tp_terminate(conn, 0, 0)) - return -1; - - return 0; -} - -static int l2tp_recv_SLI(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack) -{ - return 0; -} - -static int l2tp_conn_read(struct triton_md_handler_t *h) -{ - struct l2tp_conn_t *conn = container_of(h, typeof(*conn), hnd); - struct l2tp_packet_t *pack, *p; - struct l2tp_attr_t *msg_type; - - while (1) { - if (l2tp_recv(h->fd, &pack, NULL)) - return 0; - - if (!pack) - continue; - - if (ntohs(pack->hdr.tid) != conn->tid) { - if (conf_verbose) - log_warn("l2tp: incorrect tid %i in tunnel %i\n", ntohs(pack->hdr.tid), conn->tid); - l2tp_packet_free(pack); - continue; - } - - if (ntohs(pack->hdr.Ns) == conn->Nr + 1) { - if (!list_empty(&pack->attrs)) - conn->Nr++; - if (!list_empty(&conn->send_queue)) { - p = list_entry(conn->send_queue.next, typeof(*pack), entry); - list_del(&p->entry); - l2tp_packet_free(p); - conn->retransmit = 0; - } - if (!list_empty(&conn->send_queue)) - triton_timer_mod(&conn->rtimeout_timer, 0); - else { - if (conn->rtimeout_timer.tpd) - triton_timer_del(&conn->rtimeout_timer); - if (conn->state == STATE_FIN) - goto drop; - } - } else { - if (ntohs(pack->hdr.Ns) < conn->Nr + 1 || (ntohs(pack->hdr.Ns > 32767 && conn->Nr + 1 < 32767))) { - log_ppp_debug("duplicate packet\n"); - if (l2tp_send_ZLB(conn)) - goto drop; - } else - log_ppp_debug("reordered packet\n"); - l2tp_packet_free(pack); - continue; - } - - if (list_empty(&pack->attrs)) { - l2tp_packet_free(pack); - continue; - } - - msg_type = list_entry(pack->attrs.next, typeof(*msg_type), entry); - - if (msg_type->attr->id != Message_Type) { - if (conf_verbose) - log_ppp_error("l2tp: first attribute is not Message-Type, dropping connection...\n"); - goto drop; - } - - if (conf_verbose) { - if (msg_type->val.uint16 == Message_Type_Hello) { - log_ppp_debug("recv "); - l2tp_packet_print(pack, log_ppp_debug); - } else { - log_ppp_info2("recv "); - l2tp_packet_print(pack, log_ppp_info2); - } - } - - switch (msg_type->val.uint16) { - case Message_Type_Start_Ctrl_Conn_Connected: - if (l2tp_recv_SCCCN(conn, pack)) - goto drop; - break; - case Message_Type_Stop_Ctrl_Conn_Notify: - if (l2tp_recv_StopCCN(conn, pack)) - goto drop; - break; - case Message_Type_Hello: - if (l2tp_recv_HELLO(conn, pack)) - goto drop; - break; - case Message_Type_Incoming_Call_Request: - if (l2tp_recv_ICRQ(conn, pack)) - goto drop; - break; - case Message_Type_Incoming_Call_Connected: - if (l2tp_recv_ICCN(conn, pack)) - goto drop; - break; - case Message_Type_Outgoing_Call_Reply: - if (l2tp_recv_OCRP(conn, pack)) - goto drop; - break; - case Message_Type_Outgoing_Call_Connected: - if (l2tp_recv_OCCN(conn, pack)) - goto drop; - break; - case Message_Type_Call_Disconnect_Notify: - if (l2tp_recv_CDN(conn, pack)) - goto drop; - break; - case Message_Type_Set_Link_Info: - if (l2tp_recv_SLI(conn, pack)) - goto drop; - break; - case Message_Type_Start_Ctrl_Conn_Request: - case Message_Type_Start_Ctrl_Conn_Reply: - case Message_Type_Outgoing_Call_Request: - case Message_Type_Incoming_Call_Reply: - case Message_Type_WAN_Error_Notify: - if (conf_verbose) - log_warn("l2tp: unexpected Message-Type %i\n", msg_type->val.uint16); - break; - default: - if (conf_verbose) - log_warn("l2tp: unknown Message-Type %i\n", msg_type->val.uint16); - if (msg_type->M) { - if (l2tp_terminate(conn, 2, 8)) - goto drop; - } - } - - l2tp_packet_free(pack); - } - -drop: - l2tp_packet_free(pack); - l2tp_disconnect(conn); - return -1; -} - -static int l2tp_udp_read(struct triton_md_handler_t *h) -{ - struct l2tp_serv_t *serv = container_of(h, typeof(*serv), hnd); - struct l2tp_packet_t *pack; - struct l2tp_attr_t *msg_type; - struct in_pktinfo pkt_info; - - while (1) { - if (l2tp_recv(h->fd, &pack, &pkt_info)) - break; - - if (!pack) - continue; - - if (iprange_client_check(pack->addr.sin_addr.s_addr)) { - log_warn("l2tp: IP is out of client-ip-range, droping connection...\n"); - goto skip; - } - - if (pack->hdr.tid) - goto skip; - - if (list_empty(&pack->attrs)) { - if (conf_verbose) - log_warn("l2tp: to Message-Type attribute present\n"); - goto skip; - } - - msg_type = list_entry(pack->attrs.next, typeof(*msg_type), entry); - if (msg_type->attr->id != Message_Type) { - if (conf_verbose) - log_warn("l2tp: first attribute is not Message-Type\n"); - goto skip; - } - - if (msg_type->val.uint16 == Message_Type_Start_Ctrl_Conn_Request) - l2tp_recv_SCCRQ(serv, pack, &pkt_info); - else { - if (conf_verbose) { - log_warn("recv (unexpected) "); - l2tp_packet_print(pack, log_ppp_warn); - } - } -skip: - l2tp_packet_free(pack); - } - - return 0; -} - -static void l2tp_udp_close(struct triton_context_t *ctx) -{ - struct l2tp_serv_t *serv = container_of(ctx, typeof(*serv), ctx); - triton_md_unregister_handler(&serv->hnd); - close(serv->hnd.fd); - triton_context_unregister(&serv->ctx); -} - -static struct l2tp_serv_t udp_serv = -{ - .hnd.read = l2tp_udp_read, - .ctx.close = l2tp_udp_close, - .ctx.before_switch = log_switch, -}; - -/*static struct l2tp_serv_t ip_serv = -{ - .hnd.read=l2t_ip_read, - .ctx.close=l2tp_ip_close, -};*/ - -static void start_udp_server(void) -{ - struct sockaddr_in addr; - char *opt; - int flag = 1; - - udp_serv.hnd.fd = socket(PF_INET, SOCK_DGRAM, 0); - if (udp_serv.hnd.fd < 0) { - log_emerg("l2tp: socket: %s\n", strerror(errno)); - return; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(L2TP_PORT); - - opt = conf_get_opt("l2tp", "bind"); - if (opt) - addr.sin_addr.s_addr = inet_addr(opt); - else - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - setsockopt(udp_serv.hnd.fd, SOL_SOCKET, SO_REUSEADDR, &udp_serv.hnd.fd, sizeof(udp_serv.hnd.fd)); - setsockopt(udp_serv.hnd.fd, SOL_SOCKET, SO_NO_CHECK, &udp_serv.hnd.fd, sizeof(udp_serv.hnd.fd)); - - if (bind (udp_serv.hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { - log_emerg("l2tp: bind: %s\n", strerror(errno)); - close(udp_serv.hnd.fd); - return; - } - - if (fcntl(udp_serv.hnd.fd, F_SETFL, O_NONBLOCK)) { - log_emerg("l2tp: failed to set nonblocking mode: %s\n", strerror(errno)); - close(udp_serv.hnd.fd); - return; - } - - if (setsockopt(udp_serv.hnd.fd, IPPROTO_IP, IP_PKTINFO, &flag, sizeof(flag))) { - log_emerg("l2tp: setsockopt(IP_PKTINFO): %s\n", strerror(errno)); - close(udp_serv.hnd.fd); - return; - } - - memcpy(&udp_serv.addr, &addr, sizeof(addr)); - - triton_context_register(&udp_serv.ctx, NULL); - triton_md_register_handler(&udp_serv.ctx, &udp_serv.hnd); - triton_md_enable_handler(&udp_serv.hnd, MD_MODE_READ); - triton_context_wakeup(&udp_serv.ctx); -} - -static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) -{ - cli_send(client, "l2tp:\r\n"); - cli_sendv(client, " starting: %u\r\n", stat_starting); - cli_sendv(client, " active: %u\r\n", stat_active); - - return CLI_CMD_OK; -} - -static void load_config(void) -{ - char *opt; - - opt = conf_get_opt("l2tp", "verbose"); - if (opt && atoi(opt) > 0) - conf_verbose = 1; - - opt = conf_get_opt("l2tp", "hello-interval"); - if (opt && atoi(opt) > 0) - conf_hello_interval = atoi(opt); - - opt = conf_get_opt("l2tp", "timeout"); - if (opt && atoi(opt) > 0) - conf_timeout = atoi(opt); - - opt = conf_get_opt("l2tp", "rtimeout"); - if (opt && atoi(opt) > 0) - conf_rtimeout = atoi(opt); - - opt = conf_get_opt("l2tp", "retransmit"); - if (opt && atoi(opt) > 0) - conf_retransmit = atoi(opt); - - if (conf_host_name) - _free(conf_host_name); - opt = conf_get_opt("l2tp", "host-name"); - if (opt) - conf_host_name = _strdup(opt); - else - conf_host_name = NULL; -} - -static void __init l2tp_init(void) -{ - l2tp_conn = malloc(L2TP_MAX_TID * sizeof(void *)); - memset(l2tp_conn, 0, L2TP_MAX_TID * sizeof(void *)); - - l2tp_conn_pool = mempool_create(sizeof(struct l2tp_conn_t)); - - load_config(); - - start_udp_server(); - - cli_register_simple_cmd2(&show_stat_exec, NULL, 2, "show", "stat"); - - triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config); -} - diff --git a/accel-pptpd/ctrl/l2tp/l2tp.h b/accel-pptpd/ctrl/l2tp/l2tp.h deleted file mode 100644 index ac9b8e0b..00000000 --- a/accel-pptpd/ctrl/l2tp/l2tp.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef __L2TP_H -#define __L2TP_H - -#include <netinet/in.h> - -#include "list.h" -#include "l2tp_prot.h" - -#define ATTR_TYPE_NONE 0 -#define ATTR_TYPE_INT16 1 -#define ATTR_TYPE_INT32 2 -#define ATTR_TYPE_INT64 3 -#define ATTR_TYPE_OCTETS 4 -#define ATTR_TYPE_STRING 5 - -#define L2TP_MAX_PACKET_SIZE 65536 -#define L2TP_MAX_TID 65534 - -#define L2TP_V2_PROTOCOL_VERSION ( 1 << 8 | 0 ) - -typedef union -{ - uint32_t uint32; - int32_t int32; - uint16_t uint16; - int16_t int16; - uint64_t uint64; - uint8_t *octets; - char *string; -} l2tp_value_t; - -struct l2tp_dict_attr_t -{ - struct list_head entry; - const char *name; - int id; - int type; - int M; - int H; - struct list_head values; -}; - -struct l2tp_dict_value_t -{ - struct list_head entry; - const char *name; - l2tp_value_t val; -}; - -struct l2tp_attr_t -{ - struct list_head entry; - struct l2tp_dict_attr_t *attr; - int M:1; - int H:1; - int length; - l2tp_value_t val; -}; - -struct l2tp_packet_t -{ - struct list_head entry; - struct sockaddr_in addr; - struct l2tp_hdr_t hdr; - struct list_head attrs; -}; - -extern int conf_verbose; - -struct l2tp_dict_attr_t *l2tp_dict_find_attr_by_name(const char *name); -struct l2tp_dict_attr_t *l2tp_dict_find_attr_by_id(int id); -struct l2tp_dict_value_t *l2tp_dict_find_value(struct l2tp_dict_attr_t *attr, l2tp_value_t val); - -int l2tp_recv(int fd, struct l2tp_packet_t **, struct in_pktinfo *); -void l2tp_packet_free(struct l2tp_packet_t *); -void l2tp_packet_print(struct l2tp_packet_t *, void (*print)(const char *fmt, ...)); -struct l2tp_packet_t *l2tp_packet_alloc(int ver, int msg_type, struct sockaddr_in *addr); -int l2tp_packet_send(int sock, struct l2tp_packet_t *); -int l2tp_packet_add_int16(struct l2tp_packet_t *pack, int id, int16_t val, int M); -int l2tp_packet_add_int32(struct l2tp_packet_t *pack, int id, int32_t val, int M); -int l2tp_packet_add_string(struct l2tp_packet_t *pack, int id, const char *val, int M); -int l2tp_packet_add_octets(struct l2tp_packet_t *pack, int id, const uint8_t *val, int size, int M); - -void l2tp_nl_create_tunnel(int fd, int tid, int peer_tid); -void l2tp_nl_create_session(int tid, int sid, int peer_sid); -void l2tp_nl_delete_tunnel(int tid); - -#endif diff --git a/accel-pptpd/ctrl/l2tp/l2tp_kernel.h b/accel-pptpd/ctrl/l2tp/l2tp_kernel.h deleted file mode 100644 index 4bdb31df..00000000 --- a/accel-pptpd/ctrl/l2tp/l2tp_kernel.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * L2TP-over-IP socket for L2TPv3. - * - * Author: James Chapman <jchapman@katalix.com> - */ - -#ifndef _LINUX_L2TP_H_ -#define _LINUX_L2TP_H_ - -#include <linux/types.h> -#ifdef __KERNEL__ -#include <linux/socket.h> -#include <linux/in.h> -#else -#include <netinet/in.h> -#endif - -#define IPPROTO_L2TP 115 - -/** - * struct sockaddr_l2tpip - the sockaddr structure for L2TP-over-IP sockets - * @l2tp_family: address family number AF_L2TPIP. - * @l2tp_addr: protocol specific address information - * @l2tp_conn_id: connection id of tunnel - */ -#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ -struct sockaddr_l2tpip { - /* The first fields must match struct sockaddr_in */ - sa_family_t l2tp_family; /* AF_INET */ - __be16 l2tp_unused; /* INET port number (unused) */ - struct in_addr l2tp_addr; /* Internet address */ - - __u32 l2tp_conn_id; /* Connection ID of tunnel */ - - /* Pad to size of `struct sockaddr'. */ - unsigned char __pad[sizeof(struct sockaddr) - sizeof(sa_family_t) - - sizeof(__be16) - sizeof(struct in_addr) - - sizeof(__u32)]; -}; - -/***************************************************************************** - * NETLINK_GENERIC netlink family. - *****************************************************************************/ - -/* - * Commands. - * Valid TLVs of each command are:- - * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum, vlanid - * TUNNEL_DELETE - CONN_ID - * TUNNEL_MODIFY - CONN_ID, udpcsum - * TUNNEL_GETSTATS - CONN_ID, (stats) - * TUNNEL_GET - CONN_ID, (...) - * SESSION_CREATE - SESSION_ID, PW_TYPE, offset, data_seq, cookie, peer_cookie, offset, l2spec - * SESSION_DELETE - SESSION_ID - * SESSION_MODIFY - SESSION_ID, data_seq - * SESSION_GET - SESSION_ID, (...) - * SESSION_GETSTATS - SESSION_ID, (stats) - * - */ -enum { - L2TP_CMD_NOOP, - L2TP_CMD_TUNNEL_CREATE, - L2TP_CMD_TUNNEL_DELETE, - L2TP_CMD_TUNNEL_MODIFY, - L2TP_CMD_TUNNEL_GET, - L2TP_CMD_SESSION_CREATE, - L2TP_CMD_SESSION_DELETE, - L2TP_CMD_SESSION_MODIFY, - L2TP_CMD_SESSION_GET, - __L2TP_CMD_MAX, -}; - -#define L2TP_CMD_MAX (__L2TP_CMD_MAX - 1) - -/* - * ATTR types defined for L2TP - */ -enum { - L2TP_ATTR_NONE, /* no data */ - L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */ - L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */ - L2TP_ATTR_OFFSET, /* u16 */ - L2TP_ATTR_DATA_SEQ, /* u16 */ - L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */ - L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */ - L2TP_ATTR_PROTO_VERSION, /* u8 */ - L2TP_ATTR_IFNAME, /* string */ - L2TP_ATTR_CONN_ID, /* u32 */ - L2TP_ATTR_PEER_CONN_ID, /* u32 */ - L2TP_ATTR_SESSION_ID, /* u32 */ - L2TP_ATTR_PEER_SESSION_ID, /* u32 */ - L2TP_ATTR_UDP_CSUM, /* u8 */ - L2TP_ATTR_VLAN_ID, /* u16 */ - L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */ - L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */ - L2TP_ATTR_DEBUG, /* u32 */ - L2TP_ATTR_RECV_SEQ, /* u8 */ - L2TP_ATTR_SEND_SEQ, /* u8 */ - L2TP_ATTR_LNS_MODE, /* u8 */ - L2TP_ATTR_USING_IPSEC, /* u8 */ - L2TP_ATTR_RECV_TIMEOUT, /* msec */ - L2TP_ATTR_FD, /* int */ - L2TP_ATTR_IP_SADDR, /* u32 */ - L2TP_ATTR_IP_DADDR, /* u32 */ - L2TP_ATTR_UDP_SPORT, /* u16 */ - L2TP_ATTR_UDP_DPORT, /* u16 */ - L2TP_ATTR_MTU, /* u16 */ - L2TP_ATTR_MRU, /* u16 */ - L2TP_ATTR_STATS, /* nested */ - __L2TP_ATTR_MAX, -}; - -#define L2TP_ATTR_MAX (__L2TP_ATTR_MAX - 1) - -/* Nested in L2TP_ATTR_STATS */ -enum { - L2TP_ATTR_STATS_NONE, /* no data */ - L2TP_ATTR_TX_PACKETS, /* u64 */ - L2TP_ATTR_TX_BYTES, /* u64 */ - L2TP_ATTR_TX_ERRORS, /* u64 */ - L2TP_ATTR_RX_PACKETS, /* u64 */ - L2TP_ATTR_RX_BYTES, /* u64 */ - L2TP_ATTR_RX_SEQ_DISCARDS, /* u64 */ - L2TP_ATTR_RX_OOS_PACKETS, /* u64 */ - L2TP_ATTR_RX_ERRORS, /* u64 */ - __L2TP_ATTR_STATS_MAX, -}; - -#define L2TP_ATTR_STATS_MAX (__L2TP_ATTR_STATS_MAX - 1) - -enum l2tp_pwtype { - L2TP_PWTYPE_NONE = 0x0000, - L2TP_PWTYPE_ETH_VLAN = 0x0004, - L2TP_PWTYPE_ETH = 0x0005, - L2TP_PWTYPE_PPP = 0x0007, - L2TP_PWTYPE_PPP_AC = 0x0008, - L2TP_PWTYPE_IP = 0x000b, - __L2TP_PWTYPE_MAX -}; - -enum l2tp_l2spec_type { - L2TP_L2SPECTYPE_NONE, - L2TP_L2SPECTYPE_DEFAULT, -}; - -enum l2tp_encap_type { - L2TP_ENCAPTYPE_UDP, - L2TP_ENCAPTYPE_IP, -}; - -enum l2tp_seqmode { - L2TP_SEQ_NONE = 0, - L2TP_SEQ_IP = 1, - L2TP_SEQ_ALL = 2, -}; - -/* - * NETLINK_GENERIC related info - */ -#define L2TP_GENL_NAME "l2tp" -#define L2TP_GENL_VERSION 0x1 - -#endif diff --git a/accel-pptpd/ctrl/l2tp/l2tp_prot.h b/accel-pptpd/ctrl/l2tp/l2tp_prot.h deleted file mode 100644 index 1c1d9dae..00000000 --- a/accel-pptpd/ctrl/l2tp/l2tp_prot.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __L2TP_PROT_H -#define __L2TP_PROT_H - -#include <stdint.h> - -#define L2TP_PORT 1701 - -struct l2tp_hdr_t -{ - uint8_t P:1; - uint8_t O:1; - uint8_t reserved2:1; - uint8_t S:1; - uint8_t reserved1:2; - uint8_t L:1; - uint8_t T:1; - uint8_t ver:4; - uint8_t reserved3:4; - uint16_t length; - union { - struct { - uint16_t tid; - uint16_t sid; - }; - uint32_t cid; - }; - uint16_t Ns; - uint16_t Nr; -} __attribute__((packed)); - -/*#define L2TP_T(hdr) (hdr->flags >> 15) -#define L2TP_L(hdr) ((hdr->flags >> 14) & 1) -#define L2TP_S(hdr) ((hdr->flags >> 10) & 1) -#define L2TP_O(hdr) ((hdr->flags >> 8) & 1) -#define L2TP_VER(hdr) (hdr->flags & 0xf)*/ - -struct l2tp_avp_t -{ - uint16_t length:10; - uint16_t reserved:4; - uint16_t H:1; - uint16_t M:1; - uint16_t vendor; - uint16_t type; - uint8_t val[0]; -} __attribute__((packed)); - -struct l2tp_avp_result_code -{ - uint16_t result_code; - uint16_t error_code; -} __attribute__((packed)); - -#endif - diff --git a/accel-pptpd/ctrl/l2tp/netlink.c b/accel-pptpd/ctrl/l2tp/netlink.c deleted file mode 100644 index 7c8c79a6..00000000 --- a/accel-pptpd/ctrl/l2tp/netlink.c +++ /dev/null @@ -1,94 +0,0 @@ -#include <netlink/netlink.h> -#include <netlink/genl/genl.h> -#include <netlink/genl/ctrl.h> - -#include "l2tp_kernel.h" -#include "triton.h" - -static int family; - -void l2tp_nl_delete_tunnel(int tid) -{ - struct nl_sock *nl_sock; - struct nl_msg *msg; - - nl_sock = nl_socket_alloc(); - msg = nlmsg_alloc(); - - genl_connect(nl_sock); - - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, L2TP_CMD_TUNNEL_DELETE, L2TP_GENL_VERSION); - nla_put_u32(msg, L2TP_ATTR_CONN_ID, tid); - - nl_send_auto_complete(nl_sock, msg); - nl_recvmsgs_default(nl_sock); - - nlmsg_free(msg); - nl_close(nl_sock); - nl_socket_free(nl_sock); -} - -void l2tp_nl_create_tunnel(int fd, int tid, int peer_tid) -{ - struct nl_sock *nl_sock; - struct nl_msg *msg; - - nl_sock = nl_socket_alloc(); - msg = nlmsg_alloc(); - - genl_connect(nl_sock); - - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, L2TP_CMD_TUNNEL_CREATE, L2TP_GENL_VERSION); - nla_put_u16(msg, L2TP_ATTR_ENCAP_TYPE, L2TP_ENCAPTYPE_UDP); - nla_put_u8(msg, L2TP_ATTR_PROTO_VERSION, 2); - nla_put_u32(msg, L2TP_ATTR_CONN_ID, tid); - nla_put_u32(msg, L2TP_ATTR_PEER_CONN_ID, peer_tid); - nla_put_u32(msg, L2TP_ATTR_FD, fd); - //nla_put_u32(msg, L2TP_ATTR_DEBUG, 0xffffffff); - - nl_send_auto_complete(nl_sock, msg); - nl_recvmsgs_default(nl_sock); - - nlmsg_free(msg); - nl_close(nl_sock); - nl_socket_free(nl_sock); -} - -void l2tp_nl_create_session(int tid, int sid, int peer_sid) -{ - struct nl_sock *nl_sock; - struct nl_msg *msg; - - nl_sock = nl_socket_alloc(); - msg = nlmsg_alloc(); - - genl_connect(nl_sock); - - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, L2TP_CMD_SESSION_CREATE, L2TP_GENL_VERSION); - nla_put_u32(msg, L2TP_ATTR_CONN_ID, tid); - nla_put_u32(msg, L2TP_ATTR_SESSION_ID, sid); - nla_put_u32(msg, L2TP_ATTR_PEER_SESSION_ID, peer_sid); - nla_put_u16(msg, L2TP_ATTR_PW_TYPE, L2TP_PWTYPE_PPP); - nla_put_u8(msg, L2TP_ATTR_LNS_MODE, 1); - //nla_put_u32(msg, L2TP_ATTR_DEBUG, 0xffffffff); - - nl_send_auto_complete(nl_sock, msg); - nl_recvmsgs_default(nl_sock); - - nlmsg_free(msg); - nl_close(nl_sock); - nl_socket_free(nl_sock); -} - -static void __init init(void) -{ - struct nl_sock *nl_sock = nl_socket_alloc(); - - genl_connect(nl_sock); - - family = genl_ctrl_resolve(nl_sock, L2TP_GENL_NAME); - - nl_close(nl_sock); - nl_socket_free(nl_sock); -} - diff --git a/accel-pptpd/ctrl/l2tp/packet.c b/accel-pptpd/ctrl/l2tp/packet.c deleted file mode 100644 index e3f68965..00000000 --- a/accel-pptpd/ctrl/l2tp/packet.c +++ /dev/null @@ -1,494 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <arpa/inet.h> - -#include "triton.h" -#include "log.h" -#include "mempool.h" -#include "memdebug.h" - -#include "l2tp.h" -#include "attr_defs.h" - -static mempool_t attr_pool; -static mempool_t pack_pool; -static mempool_t buf_pool; - -void l2tp_packet_print(struct l2tp_packet_t *pack, void (*print)(const char *fmt, ...)) -{ - struct l2tp_attr_t *attr; - struct l2tp_dict_value_t *val; - - if (pack->hdr.ver == 2) { - print("[L2TP tid=%i sid=%i", ntohs(pack->hdr.tid), ntohs(pack->hdr.sid)); - log_ppp_debug(" Ns=%i Nr=%i", ntohs(pack->hdr.Ns), ntohs(pack->hdr.Nr)); - } else { - print("[L2TP cid=%u", pack->hdr.cid); - log_ppp_debug(" Ns=%i Nr=%i", ntohs(pack->hdr.Ns), ntohs(pack->hdr.Nr)); - } - - list_for_each_entry(attr, &pack->attrs, entry) { - print(" <%s", attr->attr->name); - val = l2tp_dict_find_value(attr->attr, attr->val); - if (val) - print(" %s", val->name); - else { - switch (attr->attr->type) { - case ATTR_TYPE_INT16: - print(" %i", attr->val.int16); - break; - case ATTR_TYPE_INT32: - print(" %i", attr->val.int32); - break; - case ATTR_TYPE_STRING: - print(" %s", attr->val.string); - break; - } - } - print(">"); - } - - print("]\n"); -} - -struct l2tp_packet_t *l2tp_packet_alloc(int ver, int msg_type, struct sockaddr_in *addr) -{ - struct l2tp_packet_t *pack = mempool_alloc(pack_pool); - if (!pack) - return NULL; - - memset(pack, 0, sizeof(*pack)); - INIT_LIST_HEAD(&pack->attrs); - pack->hdr.ver = ver; - pack->hdr.T = 1; - pack->hdr.L = 1; - pack->hdr.S = 1; - memcpy(&pack->addr, addr, sizeof(*addr)); - - if (msg_type) { - if (l2tp_packet_add_int16(pack, Message_Type, msg_type, 1)) { - mempool_free(pack); - return NULL; - } - } - - return pack; -} - -void l2tp_packet_free(struct l2tp_packet_t *pack) -{ - struct l2tp_attr_t *attr; - - while (!list_empty(&pack->attrs)) { - attr = list_entry(pack->attrs.next, typeof(*attr), entry); - if (attr->attr->type == ATTR_TYPE_OCTETS || attr->attr->type == ATTR_TYPE_STRING) - _free(attr->val.octets); - list_del(&attr->entry); - mempool_free(attr); - } - - mempool_free(pack); -} - -int l2tp_recv(int fd, struct l2tp_packet_t **p, struct in_pktinfo *pkt_info) -{ - int n, length; - uint8_t *buf; - struct l2tp_hdr_t *hdr; - struct l2tp_avp_t *avp; - struct l2tp_dict_attr_t *da; - struct l2tp_attr_t *attr, *RV = NULL; - uint8_t *ptr; - struct l2tp_packet_t *pack; - struct sockaddr_in addr; - socklen_t len = sizeof(addr); - struct msghdr msg; - char msg_control[128]; - struct cmsghdr *cmsg; - - *p = NULL; - - if (pkt_info) { - memset(&msg, 0, sizeof(msg)); - msg.msg_control = msg_control; - msg.msg_controllen = 128; - - n = recvmsg(fd, &msg, MSG_PEEK); - - if (n < 0) { - if (errno == EAGAIN) - return -1; - log_error("l2tp: recvmsg: %s\n", strerror(errno)); - return 0; - } - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { - memcpy(pkt_info, CMSG_DATA(cmsg), sizeof(*pkt_info)); - break; - } - } - } - - buf = mempool_alloc(buf_pool); - if (!buf) { - log_emerg("l2tp: out of memory\n"); - return 0; - } - hdr = (struct l2tp_hdr_t *)buf; - ptr = (uint8_t *)(hdr + 1); - - n = recvfrom(fd, buf, L2TP_MAX_PACKET_SIZE, 0, &addr, &len); - - if (n < 0) { - mempool_free(buf); - if (errno == EAGAIN) - return -1; - log_error("l2tp: recv: %s\n", strerror(errno)); - return 0; - } - - if (n < sizeof(*hdr)) { - if (conf_verbose) - log_warn("l2tp: short packet received (%i/%i)\n", n, sizeof(*hdr)); - goto out_err_hdr; - } - - if (n < ntohs(hdr->length)) { - if (conf_verbose) - log_warn("l2tp: short packet received (%i/%i)\n", n, ntohs(hdr->length)); - goto out_err_hdr; - } - - if (hdr->T == 0) - goto out_err_hdr; - - if (hdr->ver == 2) { - if (hdr->L == 0) { - if (conf_verbose) - log_warn("l2tp: incorrect message received (L=0)\n"); - goto out_err_hdr; - } - - if (hdr->S == 0) { - if (conf_verbose) - log_warn("l2tp: incorrect message received (S=0)\n"); - goto out_err_hdr; - } - - if (hdr->O == 1) { - if (conf_verbose) - log_warn("l2tp: incorrect message received (O=1)\n"); - goto out_err_hdr; - } - } else if (hdr->ver != 3) { - if (conf_verbose) - log_warn("l2tp: protocol version %i is not supported\n", hdr->ver); - goto out_err_hdr; - } - - pack = mempool_alloc(pack_pool); - if (!pack) { - log_emerg("l2tp: out of memory\n"); - goto out_err_hdr; - } - - memset(pack, 0, sizeof(*pack)); - INIT_LIST_HEAD(&pack->attrs); - - memcpy(&pack->addr, &addr, sizeof(addr)); - memcpy(&pack->hdr, hdr, sizeof(*hdr)); - length = ntohs(hdr->length) - sizeof(*hdr); - - while (length) { - *(uint16_t *)ptr = ntohs(*(uint16_t *)ptr); - avp = (struct l2tp_avp_t *)ptr; - - if (avp->length > length) { - if (conf_verbose) - log_warn("l2tp: incorrect avp received (exceeds message length)\n"); - goto out_err; - } - - if (avp->vendor) - goto skip; - - da = l2tp_dict_find_attr_by_id(ntohs(avp->type)); - if (!da) { - if (conf_verbose) - log_warn("l2tp: unknown avp received (type=%i, M=%u)\n", ntohs(avp->type), avp->M); - if (avp->M) - goto out_err; - } else { - if (da->M != -1 && da->M != avp->M) { - if (conf_verbose) - log_warn("l2tp: incorrect avp received (type=%i, M=%i, must be %i)\n", ntohs(avp->type), avp->M, da->M); - goto out_err; - } - - if (da->H != -1 && da->H != avp->H) { - if (conf_verbose) - log_warn("l2tp: incorrect avp received (type=%i, H=%i, must be %i)\n", ntohs(avp->type), avp->H, da->H); - goto out_err; - } - - if (avp->H) { - if (!RV) { - if (conf_verbose) - log_warn("l2tp: incorrect avp received (type=%i, H=1, but Random-Vector is not received)\n", ntohs(avp->type)); - goto out_err; - } else { - if (conf_verbose) - log_warn("l2tp: hidden avp received (type=%i)\n", ntohs(avp->type)); - } - } - - attr = mempool_alloc(attr_pool); - memset(attr, 0, sizeof(*attr)); - list_add_tail(&attr->entry, &pack->attrs); - - attr->attr = da; - attr->M = avp->M; - attr->H = avp->H; - attr->length = avp->length - sizeof(*avp); - - if (attr->attr->id == Random_Vector) - RV = attr; - - switch (da->type) { - case ATTR_TYPE_INT16: - if (avp->length != sizeof(*avp) + 2) - goto out_err_len; - attr->val.uint16 = ntohs(*(uint16_t *)avp->val); - break; - case ATTR_TYPE_INT32: - if (avp->length != sizeof(*avp) + 4) - goto out_err_len; - attr->val.uint32 = ntohl(*(uint32_t *)avp->val); - break; - case ATTR_TYPE_INT64: - if (avp->length != sizeof(*avp) + 8) - goto out_err_len; - attr->val.uint64 = *(uint64_t *)avp->val; - break; - case ATTR_TYPE_OCTETS: - attr->val.octets = _malloc(attr->length); - if (!attr->val.octets) - goto out_err_mem; - memcpy(attr->val.octets, avp->val, attr->length); - break; - case ATTR_TYPE_STRING: - attr->val.string = _malloc(attr->length + 1); - if (!attr->val.string) - goto out_err_mem; - memcpy(attr->val.string, avp->val, attr->length); - attr->val.string[attr->length] = 0; - break; - } - } -skip: - ptr += avp->length; - length -= avp->length; - } - - *p = pack; - - mempool_free(buf); - - return 0; - -out_err: - l2tp_packet_free(pack); -out_err_hdr: - mempool_free(buf); - return 0; -out_err_len: - if (conf_verbose) - log_warn("l2tp: incorrect avp received (type=%i, incorrect length %i)\n", ntohs(avp->type), avp->length); - goto out_err; -out_err_mem: - log_emerg("l2tp: out of memory\n"); - goto out_err; -} - -int l2tp_packet_send(int sock, struct l2tp_packet_t *pack) -{ - uint8_t *buf = mempool_alloc(buf_pool); - struct l2tp_avp_t *avp; - struct l2tp_attr_t *attr; - uint8_t *ptr; - int n; - int len = sizeof(pack->hdr); - - if (!buf) { - log_emerg("l2tp: out of memory\n"); - return -1; - } - - memset(buf, 0, L2TP_MAX_PACKET_SIZE); - - ptr = buf + sizeof(pack->hdr); - - list_for_each_entry(attr, &pack->attrs, entry) { - if (len + sizeof(*avp) + attr->length >= L2TP_MAX_PACKET_SIZE) { - log_error("l2tp: cann't send packet (exceeds maximum size)\n"); - mempool_free(buf); - return -1; - } - avp = (struct l2tp_avp_t *)ptr; - avp->type = htons(attr->attr->id); - avp->M = attr->M; - avp->H = attr->H; - avp->length = sizeof(*avp) + attr->length; - *(uint16_t *)ptr = htons(*(uint16_t *)ptr); - switch (attr->attr->type) { - case ATTR_TYPE_INT16: - *(int16_t *)avp->val = htons(attr->val.int16); - break; - case ATTR_TYPE_INT32: - *(int32_t *)avp->val = htonl(attr->val.int32); - break; - case ATTR_TYPE_STRING: - case ATTR_TYPE_OCTETS: - memcpy(avp->val, attr->val.string, attr->length); - break; - } - - ptr += sizeof(*avp) + attr->length; - len += sizeof(*avp) + attr->length; - } - - pack->hdr.length = htons(len); - memcpy(buf, &pack->hdr, sizeof(pack->hdr)); - - n = write(sock, buf, ntohs(pack->hdr.length)); - - mempool_free(buf); - - if (n < 0) { - if (errno == EAGAIN) { - if (conf_verbose) - log_warn("l2tp: buffer overflow (packet lost)\n"); - } else { - if (conf_verbose) - log_warn("l2tp: sendto: %s\n", strerror(errno)); - return -1; - } - } - - if (n != ntohs(pack->hdr.length)) { - if (conf_verbose) - log_warn("l2tp: short write (%i/%i)\n", n, ntohs(pack->hdr.length)); - } - - return 0; -} - -static struct l2tp_attr_t *attr_alloc(int id, int M) -{ - struct l2tp_attr_t *attr; - struct l2tp_dict_attr_t *da; - - da = l2tp_dict_find_attr_by_id(id); - if (!da) - return NULL; - - attr = mempool_alloc(attr_pool); - if (!attr) { - log_emerg("l2tp: out of memory\n"); - return NULL; - } - - memset(attr, 0, sizeof(*attr)); - - attr->attr = da; - - if (da->M != -1) - attr->M = da->M; - else - attr->M = M; - - //if (da->H != -1) - //attr->H = da->H; - - return attr; -} - -int l2tp_packet_add_int16(struct l2tp_packet_t *pack, int id, int16_t val, int M) -{ - struct l2tp_attr_t *attr = attr_alloc(id, M); - - if (!attr) - return -1; - - attr->length = 2; - attr->val.int16 = val; - list_add_tail(&attr->entry, &pack->attrs); - - return 0; -} -int l2tp_packet_add_int32(struct l2tp_packet_t *pack, int id, int32_t val, int M) -{ - struct l2tp_attr_t *attr = attr_alloc(id, M); - - if (!attr) - return -1; - - attr->length = 4; - attr->val.int32 = val; - list_add_tail(&attr->entry, &pack->attrs); - - return 0; -} -int l2tp_packet_add_string(struct l2tp_packet_t *pack, int id, const char *val, int M) -{ - struct l2tp_attr_t *attr = attr_alloc(id, M); - - if (!attr) - return -1; - - attr->length = strlen(val); - attr->val.string = _strdup(val); - if (!attr->val.string) { - log_emerg("l2tp: out of memory\n"); - mempool_free(attr); - return -1; - } - memcpy(attr->val.string, val, attr->length); - list_add_tail(&attr->entry, &pack->attrs); - - return 0; -} - -int l2tp_packet_add_octets(struct l2tp_packet_t *pack, int id, const uint8_t *val, int size, int M) -{ - struct l2tp_attr_t *attr = attr_alloc(id, M); - - if (!attr) - return -1; - - attr->length = size; - attr->val.octets = _malloc(size); - if (!attr->val.string) { - log_emerg("l2tp: out of memory\n"); - mempool_free(attr); - return -1; - } - memcpy(attr->val.octets, val, attr->length); - list_add_tail(&attr->entry, &pack->attrs); - - return 0; -} - -static void __init init(void) -{ - attr_pool = mempool_create(sizeof(struct l2tp_attr_t)); - pack_pool = mempool_create(sizeof(struct l2tp_packet_t)); - buf_pool = mempool_create(L2TP_MAX_PACKET_SIZE); -} - diff --git a/accel-pptpd/ctrl/pppoe/CMakeLists.txt b/accel-pptpd/ctrl/pppoe/CMakeLists.txt deleted file mode 100644 index f047936e..00000000 --- a/accel-pptpd/ctrl/pppoe/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -SET(sources - pppoe.c - mac_filter.c - dpado.c - cli.c -) - -IF (RADIUS) -SET(sources ${sources} tr101.c) -ENDIF(RADIUS) - -ADD_LIBRARY(pppoe SHARED ${sources}) -TARGET_LINK_LIBRARIES(pppoe crypto) - -INSTALL(TARGETS pppoe LIBRARY DESTINATION lib/accel-pptp) diff --git a/accel-pptpd/ctrl/pppoe/cli.c b/accel-pptpd/ctrl/pppoe/cli.c deleted file mode 100644 index 9929f669..00000000 --- a/accel-pptpd/ctrl/pppoe/cli.c +++ /dev/null @@ -1,205 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include <netinet/in.h> -#include <net/ethernet.h> - -#include "triton.h" -#include "cli.h" -#include "ppp.h" -#include "memdebug.h" - -#include "pppoe.h" - -static void show_interfaces(void *cli) -{ - struct pppoe_serv_t *serv; - - cli_send(cli, "interface: connections: state:\r\n"); - cli_send(cli, "-----------------------------------\r\n"); - - pthread_rwlock_rdlock(&serv_lock); - list_for_each_entry(serv, &serv_list, entry) { - cli_sendv(cli, "%9s %11u %6s\r\n", serv->ifname, serv->conn_cnt, serv->stopping ? "stop" : "active"); - } - pthread_rwlock_unlock(&serv_lock); -} - -static void intf_help(char * const *fields, int fields_cnt, void *client) -{ - cli_send(client, "pppoe interface add <name> - start pppoe server on specified interface\r\n"); - cli_send(client, "pppoe interface del <name> - stop pppoe server on specified interface and drop his connections\r\n"); - cli_send(client, "pppoe interface show - show interfaces on which pppoe server started\r\n"); -} - -static int intf_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) -{ - if (fields_cnt == 2) - goto help; - - if (fields_cnt == 3) { - if (!strcmp(fields[2], "show")) - show_interfaces(client); - else - goto help; - - return CLI_CMD_OK; - } - - if (fields_cnt != 4) - goto help; - - if (!strcmp(fields[2], "add")) - pppoe_server_start(fields[3], client); - else if (!strcmp(fields[2], "del")) - pppoe_server_stop(fields[3]); - else - goto help; - - return CLI_CMD_OK; -help: - intf_help(fields, fields_cnt, client); - return CLI_CMD_OK; -} - -//=================================== - -static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) -{ - cli_send(client, "pppoe:\r\n"); - cli_sendv(client, " active: %u\r\n", stat_active); - cli_sendv(client, " delayed PADO: %u\r\n", stat_delayed_pado); - cli_sendv(client, " recv PADI: %lu\r\n", stat_PADI_recv); - cli_sendv(client, " sent PADO: %lu\r\n", stat_PADO_sent); - cli_sendv(client, " recv PADR(dup): %lu(%lu)\r\n", stat_PADR_recv, stat_PADR_dup_recv); - cli_sendv(client, " sent PADS: %lu\r\n", stat_PADS_sent); - - return CLI_CMD_OK; -} - -//=================================== - -static void set_verbose_help(char * const *f, int f_cnt, void *cli) -{ - cli_send(cli, "pppoe set verbose <n> - set verbosity of pppoe logging\r\n"); - cli_send(cli, "pppoe set PADO-delay <delay[,delay1:count1[,delay2:count2[,...]]]> - set PADO delays (ms)\r\n"); - cli_send(cli, "pppoe set Service-Name <name> - set Service-Name to respond\r\n"); - cli_send(cli, "pppoe set Service-Name * - respond with client's Service-Name\r\n"); - cli_send(cli, "pppoe set AC-Name <name> - set AC-Name tag value\r\n"); - cli_send(cli, "pppoe show verbose - show current verbose value\r\n"); - cli_send(cli, "pppoe show PADO-delay - show current PADO delay value\r\n"); - cli_send(cli, "pppoe show Service-Name - show current Service-Name value\r\n"); - cli_send(cli, "pppoe show AC-Name - show current AC-Name tag value\r\n"); -} - -static int show_verbose_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 3) - return CLI_CMD_SYNTAX; - - cli_sendv(cli, "%i\r\n", conf_verbose); - - return CLI_CMD_OK; -} - -static int show_pado_delay_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 3) - return CLI_CMD_SYNTAX; - - cli_sendv(cli, "%s\r\n", conf_pado_delay); - - return CLI_CMD_OK; -} - -static int show_service_name_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 3) - return CLI_CMD_SYNTAX; - - if (conf_service_name) - cli_sendv(cli, "%s\r\n", conf_service_name); - else - cli_sendv(cli, "*\r\n", conf_service_name); - - return CLI_CMD_OK; -} - -static int show_ac_name_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 3) - return CLI_CMD_SYNTAX; - - cli_sendv(cli, "%s\r\n", conf_ac_name); - - return CLI_CMD_OK; -} - -static int set_verbose_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 4) - return CLI_CMD_SYNTAX; - - if (!strcmp(f[3], "0")) - conf_verbose = 0; - else if (!strcmp(f[3], "1")) - conf_verbose = 1; - else - return CLI_CMD_INVAL; - - return CLI_CMD_OK; -} - -static int set_pado_delay_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 4) - return CLI_CMD_SYNTAX; - - if (dpado_parse(f[3])) - return CLI_CMD_INVAL; - - return CLI_CMD_OK; -} - -static int set_service_name_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 4) - return CLI_CMD_SYNTAX; - - if (conf_service_name) - _free(conf_service_name); - - if (!strcmp(f[3], "*")) - conf_service_name = NULL; - else - conf_service_name = _strdup(f[3]); - - return CLI_CMD_OK; -} - -static int set_ac_name_exec(const char *cmd, char * const *f, int f_cnt, void *cli) -{ - if (f_cnt != 4) - return CLI_CMD_SYNTAX; - - _free(conf_ac_name); - conf_ac_name = _strdup(f[3]); - - return CLI_CMD_OK; -} -//=================================== - - -static void __init init(void) -{ - cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat"); - cli_register_simple_cmd2(intf_exec, intf_help, 2, "pppoe", "interface"); - cli_register_simple_cmd2(set_verbose_exec, set_verbose_help, 3, "pppoe", "set", "verbose"); - cli_register_simple_cmd2(set_pado_delay_exec, NULL, 3, "pppoe", "set", "PADO-delay"); - cli_register_simple_cmd2(set_service_name_exec, NULL, 3, "pppoe", "set", "Service-Name"); - cli_register_simple_cmd2(set_ac_name_exec, NULL, 3, "pppoe", "set", "AC-Name"); - cli_register_simple_cmd2(show_verbose_exec, NULL, 3, "pppoe", "show", "verbose"); - cli_register_simple_cmd2(show_pado_delay_exec, NULL, 3, "pppoe", "show", "PADO-delay"); - cli_register_simple_cmd2(show_service_name_exec, NULL, 3, "pppoe", "show", "Service-Name"); - cli_register_simple_cmd2(show_ac_name_exec, NULL, 3, "pppoe", "show", "AC-Name"); -} - diff --git a/accel-pptpd/ctrl/pppoe/dpado.c b/accel-pptpd/ctrl/pppoe/dpado.c deleted file mode 100644 index 3f565198..00000000 --- a/accel-pptpd/ctrl/pppoe/dpado.c +++ /dev/null @@ -1,162 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <pthread.h> -#include <errno.h> -#include <limits.h> -#include <netinet/in.h> -#include <net/ethernet.h> - -#include "list.h" -#include "cli.h" -#include "triton.h" -#include "log.h" -#include "memdebug.h" - -#include "pppoe.h" - -struct dpado_range_t -{ - struct list_head entry; - unsigned int conn_cnt; - int pado_delay; -}; - -static pthread_mutex_t dpado_range_lock = PTHREAD_MUTEX_INITIALIZER; -static LIST_HEAD(dpado_range_list); -static struct dpado_range_t *dpado_range_next; -static struct dpado_range_t *dpado_range_prev; -int pado_delay; - -void dpado_check_next(int conn_cnt) -{ - pthread_mutex_lock(&dpado_range_lock); - if (dpado_range_next && conn_cnt == dpado_range_next->conn_cnt) { - pado_delay = dpado_range_next->pado_delay; - dpado_range_prev = dpado_range_next; - if (dpado_range_next->entry.next != &dpado_range_list) - dpado_range_next = list_entry(dpado_range_next->entry.next, typeof(*dpado_range_next), entry); - else - dpado_range_next = NULL; - /*printf("active=%i, prev=%i:%i, next=%i:%i, pado_delay=%i\n", stat_active, - dpado_range_prev?dpado_range_prev->pado_delay:0,dpado_range_prev?dpado_range_prev->conn_cnt:0, - dpado_range_next?dpado_range_next->pado_delay:0,dpado_range_next?dpado_range_next->conn_cnt:0, - pado_delay);*/ - } - pthread_mutex_unlock(&dpado_range_lock); -} - -void dpado_check_prev(int conn_cnt) -{ - pthread_mutex_lock(&dpado_range_lock); - if (dpado_range_prev && conn_cnt == dpado_range_prev->conn_cnt) { - dpado_range_next = dpado_range_prev; - dpado_range_prev = list_entry(dpado_range_prev->entry.prev, typeof(*dpado_range_prev), entry); - pado_delay = dpado_range_prev->pado_delay; - /*printf("active=%i, prev=%i:%i, next=%i:%i, pado_delay=%i\n", stat_active, - dpado_range_prev?dpado_range_prev->pado_delay:0,dpado_range_prev?dpado_range_prev->conn_cnt:0, - dpado_range_next?dpado_range_next->pado_delay:0,dpado_range_next?dpado_range_next->conn_cnt:0, - pado_delay);*/ - } - pthread_mutex_unlock(&dpado_range_lock); -} - -static void strip(char *str) -{ - char *ptr = str; - char *endptr = strchr(str, 0); - while (1) { - ptr = strchr(ptr, ' '); - if (ptr) - memmove(ptr, ptr + 1, endptr - ptr - 1); - else - break; - } -} - -int dpado_parse(const char *str) -{ - char *str1 = _strdup(str); - char *ptr1, *ptr2, *ptr3, *endptr; - LIST_HEAD(range_list); - struct dpado_range_t *r; - - strip(str1); - - ptr1 = str1; - - while (1) { - ptr2 = strchr(ptr1, ','); - if (ptr2) - *ptr2 = 0; - ptr3 = strchr(ptr1, ':'); - if (ptr3) - *ptr3 = 0; - - r = _malloc(sizeof(*r)); - memset(r, 0, sizeof(*r)); - - r->pado_delay = strtol(ptr1, &endptr, 10); - if (*endptr) - goto out_err; - - if (list_empty(&range_list)) - r->conn_cnt = INT_MAX; - else { - if (!ptr3) - goto out_err; - r->conn_cnt = strtol(ptr3 + 1, &endptr, 10); - if (*endptr) - goto out_err; - } - - list_add_tail(&r->entry, &range_list); - //printf("parsed range: %i:%i\n", r->pado_delay, r->conn_cnt); - - if (!ptr2) - break; - - ptr1 = ptr2 + 1; - } - - pthread_mutex_lock(&dpado_range_lock); - while (!list_empty(&dpado_range_list)) { - r = list_entry(dpado_range_list.next, typeof(*r), entry); - list_del(&r->entry); - _free(r); - } - - dpado_range_next = NULL; - dpado_range_prev = NULL; - - while (!list_empty(&range_list)) { - r = list_entry(range_list.next, typeof(*r), entry); - list_del(&r->entry); - list_add_tail(&r->entry, &dpado_range_list); - - if (!dpado_range_prev || stat_active >= r->conn_cnt) - dpado_range_prev = r; - else if (!dpado_range_next) - dpado_range_next = r; - } - - pado_delay = dpado_range_prev->pado_delay; - - if (conf_pado_delay) - _free(conf_pado_delay); - conf_pado_delay = _strdup(str); - /*printf("active=%i, prev=%i:%i, next=%i:%i, pado_delay=%i\n", stat_active, - dpado_range_prev?dpado_range_prev->pado_delay:0,dpado_range_prev?dpado_range_prev->conn_cnt:0, - dpado_range_next?dpado_range_next->pado_delay:0,dpado_range_next?dpado_range_next->conn_cnt:0, - pado_delay);*/ - - pthread_mutex_unlock(&dpado_range_lock); - - _free(str1); - return 0; - -out_err: - _free(str1); - log_emerg("pppoe: pado_delay: invalid format\n"); - return -1; -} - diff --git a/accel-pptpd/ctrl/pppoe/mac_filter.c b/accel-pptpd/ctrl/pppoe/mac_filter.c deleted file mode 100644 index 9b101c67..00000000 --- a/accel-pptpd/ctrl/pppoe/mac_filter.c +++ /dev/null @@ -1,255 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <pthread.h> -#include <errno.h> -#include <netinet/in.h> -#include <net/ethernet.h> - -#include "list.h" -#include "cli.h" -#include "triton.h" -#include "log.h" -#include "ppp.h" -#include "memdebug.h" - -#include "pppoe.h" - -struct mac_t -{ - struct list_head entry; - uint8_t addr[ETH_ALEN]; -}; - -static LIST_HEAD(mac_list); -static int type; // -1 - disabled, 1 - allow, 0 - denied -static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER; -static const char *conf_mac_filter; - -int mac_filter_check(const uint8_t *addr) -{ - struct mac_t *mac; - int res = type; - - if (type == -1) - return 0; - - pthread_rwlock_rdlock(&lock); - list_for_each_entry(mac, &mac_list, entry) { - if (memcmp(mac->addr, addr, ETH_ALEN)) - continue; - res = !type; - break; - } - pthread_rwlock_unlock(&lock); - - return res; -} - -static int mac_filter_load(const char *opt) -{ - struct mac_t *mac; - FILE *f; - char *c; - char *name = _strdup(opt); - char *buf = _malloc(1024); - int n[ETH_ALEN]; - int i, line = 0; - - c = strstr(name, ","); - if (!c) - goto err_inval; - - *c = 0; - - if (!strcmp(c + 1, "allow")) - type = 1; - else if (!strcmp(c + 1, "deny")) - type = 0; - else - goto err_inval; - - f = fopen(name, "r"); - if (!f) { - log_emerg("pppoe: open '%s': %s\n", name, strerror(errno)); - goto err; - } - - conf_mac_filter = opt; - - pthread_rwlock_wrlock(&lock); - while (!list_empty(&mac_list)) { - mac = list_entry(mac_list.next, typeof(*mac), entry); - list_del(&mac->entry); - _free(mac); - } - - while (fgets(buf, 1024, f)) { - line++; - if (buf[0] == '#' || buf[0] == ';' || buf[0] == '\n') - continue; - if (sscanf(buf, "%x:%x:%x:%x:%x:%x", - n + 0, n + 1, n + 2, n + 3, n + 4, n + 5) != 6) { - log_warn("pppoe: mac-filter:%s:%i: address is invalid\n", name, line); - continue; - } - mac = _malloc(sizeof(*mac)); - for (i = 0; i < ETH_ALEN; i++) { - if (n[i] > 255) { - log_warn("pppoe: mac-filter:%s:%i: address is invalid\n", name, line); - _free(mac); - continue; - } - mac->addr[i] = n[i]; - } - list_add_tail(&mac->entry, &mac_list); - } - pthread_rwlock_unlock(&lock); - - fclose(f); - - _free(name); - _free(buf); - - return 0; - -err_inval: - log_emerg("pppoe: mac-filter format is invalid\n"); -err: - _free(name); - _free(buf); - return -1; -} - -static void mac_filter_add(const char *addr, void *client) -{ - int n[ETH_ALEN]; - struct mac_t *mac; - int i; - - if (sscanf(addr, "%x:%x:%x:%x:%x:%x", - n + 0, n + 1, n + 2, n + 3, n + 4, n + 5) != 6) { - cli_send(client, "invalid format\r\n"); - return; - } - - mac = _malloc(sizeof(*mac)); - for (i = 0; i < ETH_ALEN; i++) { - if (n[i] > 255) { - _free(mac); - cli_send(client, "invalid format\r\n"); - return; - } - mac->addr[i] = n[i]; - } - - pthread_rwlock_wrlock(&lock); - list_add_tail(&mac->entry, &mac_list); - pthread_rwlock_unlock(&lock); -} - -static void mac_filter_del(const char *addr, void *client) -{ - int n[ETH_ALEN]; - uint8_t a[ETH_ALEN]; - struct mac_t *mac; - int i; - int found = 0; - - if (sscanf(addr, "%x:%x:%x:%x:%x:%x", - n + 0, n + 1, n + 2, n + 3, n + 4, n + 5) != 6) { - cli_send(client, "invalid format\r\n"); - return; - } - - for (i = 0; i < ETH_ALEN; i++) { - if (n[i] > 255) { - cli_send(client, "invalid format\r\n"); - return; - } - a[i] = n[i]; - } - - pthread_rwlock_wrlock(&lock); - list_for_each_entry(mac, &mac_list, entry) { - if (memcmp(a, mac->addr, ETH_ALEN)) - continue; - list_del(&mac->entry); - _free(mac); - found = 1; - break; - } - pthread_rwlock_unlock(&lock); - - if (!found) - cli_send(client, "not found\r\n"); -} - -static void mac_filter_show(void *client) -{ - struct mac_t *mac; - const char *filter_type; - - if (type == 0) - filter_type = "deny"; - else if (type == 1) - filter_type = "allow"; - else - filter_type = "disabled"; - - cli_sendv(client, "filter type: %s\r\n", filter_type); - - pthread_rwlock_rdlock(&lock); - list_for_each_entry(mac, &mac_list, entry) { - cli_sendv(client, "%02x:%02x:%02x:%02x:%02x:%02x\r\n", - mac->addr[0], mac->addr[1], mac->addr[2], - mac->addr[3], mac->addr[4], mac->addr[5]); - } - pthread_rwlock_unlock(&lock); -} - -static void cmd_help(char * const *fields, int fields_cnt, void *client); -static int cmd_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) -{ - if (fields_cnt == 2) - goto help; - - if (!strcmp(fields[2], "reload")) { - if (!conf_mac_filter) - cli_send(client, "error: mac-filter was not specified in the config\r\n"); - else if (mac_filter_load(conf_mac_filter)) - cli_send(client, "error: check logs\r\n"); - } else if (!strcmp(fields[2], "add")) { - if (fields_cnt != 4) - goto help; - mac_filter_add(fields[3], client); - } else if (!strcmp(fields[2], "del")) { - if (fields_cnt != 4) - goto help; - mac_filter_del(fields[3], client); - } else if (!strcmp(fields[2], "show")) { - mac_filter_show(client); - } - - return CLI_CMD_OK; -help: - cmd_help(fields, fields_cnt, client); - return CLI_CMD_OK; -} - -static void cmd_help(char * const *fields, int fields_cnt, void *client) -{ - cli_send(client, "pppoe mac-filter reload - reload mac-filter file\r\n"); - cli_send(client, "pppoe mac-filter add <address> - add address to mac-filter list\r\n"); - cli_send(client, "pppoe mac-filter del <address> - delete address from mac-filter list\r\n"); - cli_send(client, "pppoe mac-filter show - show current mac-filter list\r\n"); -} - -static void __init init(void) -{ - const char *opt = conf_get_opt("pppoe", "mac-filter"); - if (!opt || mac_filter_load(opt)) - type = -1; - - cli_register_simple_cmd2(cmd_exec, cmd_help, 2, "pppoe", "mac-filter"); -} - diff --git a/accel-pptpd/ctrl/pppoe/pppoe.c b/accel-pptpd/ctrl/pppoe/pppoe.c deleted file mode 100644 index 95ae3944..00000000 --- a/accel-pptpd/ctrl/pppoe/pppoe.c +++ /dev/null @@ -1,1288 +0,0 @@ -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <errno.h> -#include <string.h> -#include <pthread.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/ethernet.h> -#include <netpacket/packet.h> -#include <arpa/inet.h> -#include <printf.h> - -#include <openssl/md5.h> - -#include "events.h" -#include "triton.h" -#include "log.h" -#include "ppp.h" -#include "mempool.h" -#include "cli.h" - -#ifdef RADIUS -#include "radius.h" -#endif - -#include "pppoe.h" - -#include "memdebug.h" - -struct pppoe_conn_t -{ - struct list_head entry; - struct triton_context_t ctx; - struct pppoe_serv_t *serv; - int disc_sock; - uint16_t sid; - uint8_t addr[ETH_ALEN]; - int ppp_started:1; - - struct pppoe_tag *relay_sid; - struct pppoe_tag *host_uniq; - struct pppoe_tag *service_name; - struct pppoe_tag *tr101; - uint8_t cookie[COOKIE_LENGTH]; - - struct ppp_ctrl_t ctrl; - struct ppp_t ppp; -#ifdef RADIUS - struct rad_plugin_t radius; -#endif -}; - -struct delayed_pado_t -{ - struct list_head entry; - struct triton_timer_t timer; - struct pppoe_serv_t *serv; - uint8_t addr[ETH_ALEN]; - struct pppoe_tag *host_uniq; - struct pppoe_tag *relay_sid; - struct pppoe_tag *service_name; -}; - -int conf_verbose; -char *conf_service_name; -char *conf_ac_name; -int conf_ifname_in_sid; -char *conf_pado_delay; - -static mempool_t conn_pool; -static mempool_t pado_pool; - -unsigned int stat_active; -unsigned int stat_delayed_pado; -unsigned long stat_PADI_recv; -unsigned long stat_PADO_sent; -unsigned long stat_PADR_recv; -unsigned long stat_PADR_dup_recv; -unsigned long stat_PADS_sent; - -pthread_rwlock_t serv_lock = PTHREAD_RWLOCK_INITIALIZER; -LIST_HEAD(serv_list); - -static uint8_t bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - -static void pppoe_send_PADT(struct pppoe_conn_t *conn); -static void _server_stop(struct pppoe_serv_t *serv); -void pppoe_server_free(struct pppoe_serv_t *serv); -static int init_secret(struct pppoe_serv_t *serv); - -static void disconnect(struct pppoe_conn_t *conn) -{ - if (conn->ppp_started) { - dpado_check_prev(__sync_fetch_and_sub(&stat_active, 1)); - conn->ppp_started = 0; - ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } - - pppoe_send_PADT(conn); - - close(conn->disc_sock); - - - triton_event_fire(EV_CTRL_FINISHED, &conn->ppp); - - log_ppp_info1("disconnected\n"); - - pthread_mutex_lock(&conn->serv->lock); - conn->serv->conn[conn->sid] = NULL; - list_del(&conn->entry); - conn->serv->conn_cnt--; - if (conn->serv->stopping && conn->serv->conn_cnt == 0) { - pthread_mutex_unlock(&conn->serv->lock); - pppoe_server_free(conn->serv); - } else - pthread_mutex_unlock(&conn->serv->lock); - - _free(conn->ctrl.calling_station_id); - _free(conn->ctrl.called_station_id); - _free(conn->service_name); - if (conn->host_uniq) - _free(conn->host_uniq); - if (conn->relay_sid) - _free(conn->relay_sid); - - triton_context_unregister(&conn->ctx); - - mempool_free(conn); -} - -static void ppp_started(struct ppp_t *ppp) -{ - log_ppp_debug("pppoe: ppp started\n"); -} - -static void ppp_finished(struct ppp_t *ppp) -{ - struct pppoe_conn_t *conn = container_of(ppp, typeof(*conn), ppp); - - log_ppp_debug("pppoe: ppp finished\n"); - - if (conn->ppp_started) { - dpado_check_prev(__sync_fetch_and_sub(&stat_active, 1)); - conn->ppp_started = 0; - triton_context_call(&conn->ctx, (triton_event_func)disconnect, conn); - } -} - -static void pppoe_conn_close(struct triton_context_t *ctx) -{ - struct pppoe_conn_t *conn = container_of(ctx, typeof(*conn), ctx); - - if (conn->ppp_started) - ppp_terminate(&conn->ppp, TERM_ADMIN_RESET, 0); - else - disconnect(conn); -} - -#ifdef RADIUS -static int pppoe_rad_send_access_request(struct rad_plugin_t *rad, struct rad_packet_t *pack) -{ - struct pppoe_conn_t *conn = container_of(rad, typeof(*conn), radius); - - if (conn->tr101) - return tr101_send_access_request(conn->tr101, pack); - - return 0; -} - -static int pppoe_rad_send_accounting_request(struct rad_plugin_t *rad, struct rad_packet_t *pack) -{ - struct pppoe_conn_t *conn = container_of(rad, typeof(*conn), radius); - - if (conn->tr101) - return tr101_send_accounting_request(conn->tr101, pack); - - return 0; -} -#endif - -static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, const struct pppoe_tag *service_name, const struct pppoe_tag *tr101, const uint8_t *cookie) -{ - struct pppoe_conn_t *conn; - int sid; - - conn = mempool_alloc(conn_pool); - if (!conn) { - log_emerg("pppoe: out of memory\n"); - return NULL; - } - - memset(conn, 0, sizeof(*conn)); - - pthread_mutex_lock(&serv->lock); - for (sid = serv->sid + 1; sid != serv->sid; sid++) { - if (sid == MAX_SID) - sid = 1; - if (!serv->conn[sid]) { - conn->sid = sid; - serv->sid = sid; - serv->conn[sid] = conn; - list_add_tail(&conn->entry, &serv->conn_list); - serv->conn_cnt++; - break; - } - } - pthread_mutex_unlock(&serv->lock); - - if (!conn->sid) { - log_warn("pppoe: no free sid available\n"); - mempool_free(conn); - return NULL; - } - - conn->serv = serv; - memcpy(conn->addr, addr, ETH_ALEN); - - if (host_uniq) { - conn->host_uniq = _malloc(sizeof(*host_uniq) + ntohs(host_uniq->tag_len)); - memcpy(conn->host_uniq, host_uniq, sizeof(*host_uniq) + ntohs(host_uniq->tag_len)); - } - - if (relay_sid) { - conn->relay_sid = _malloc(sizeof(*relay_sid) + ntohs(relay_sid->tag_len)); - memcpy(conn->relay_sid, relay_sid, sizeof(*relay_sid) + ntohs(relay_sid->tag_len)); - } - - if (tr101) { - conn->tr101 = _malloc(sizeof(*tr101) + ntohs(tr101->tag_len)); - memcpy(conn->tr101, tr101, sizeof(*tr101) + ntohs(tr101->tag_len)); - } - - conn->service_name = _malloc(sizeof(*service_name) + ntohs(service_name->tag_len)); - memcpy(conn->service_name, service_name, sizeof(*service_name) + ntohs(service_name->tag_len)); - - memcpy(conn->cookie, cookie, COOKIE_LENGTH); - - conn->ctx.before_switch = log_switch; - conn->ctx.close = pppoe_conn_close; - conn->ctrl.ctx = &conn->ctx; - conn->ctrl.started = ppp_started; - conn->ctrl.finished = ppp_finished; - conn->ctrl.max_mtu = MAX_PPPOE_MTU; - conn->ctrl.name = "pppoe"; - - conn->ctrl.calling_station_id = _malloc(IFNAMSIZ + 19); - conn->ctrl.called_station_id = _malloc(IFNAMSIZ + 19); - - if (conf_ifname_in_sid == 1 || conf_ifname_in_sid == 3) - sprintf(conn->ctrl.calling_station_id, "%s:%02x:%02x:%02x:%02x:%02x:%02x", serv->ifname, - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - else - sprintf(conn->ctrl.calling_station_id, "%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - if (conf_ifname_in_sid == 2 || conf_ifname_in_sid == 3) - sprintf(conn->ctrl.called_station_id, "%s:%02x:%02x:%02x:%02x:%02x:%02x", serv->ifname, - serv->hwaddr[0], serv->hwaddr[1], serv->hwaddr[2], serv->hwaddr[3], serv->hwaddr[4], serv->hwaddr[5]); - else - sprintf(conn->ctrl.called_station_id, "%02x:%02x:%02x:%02x:%02x:%02x", - serv->hwaddr[0], serv->hwaddr[1], serv->hwaddr[2], serv->hwaddr[3], serv->hwaddr[4], serv->hwaddr[5]); - - ppp_init(&conn->ppp); - - conn->ppp.ctrl = &conn->ctrl; - conn->ppp.chan_name = conn->ctrl.calling_station_id; - - triton_context_register(&conn->ctx, &conn->ppp); - triton_context_wakeup(&conn->ctx); - - triton_event_fire(EV_CTRL_STARTING, &conn->ppp); - triton_event_fire(EV_CTRL_STARTED, &conn->ppp); - - conn->disc_sock = dup(serv->hnd.fd); - - return conn; -} - -static void connect_channel(struct pppoe_conn_t *conn) -{ - int sock; - struct sockaddr_pppox sp; - - sock = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); - if (!sock) { - log_error("pppoe: socket(PPPOX): %s\n", strerror(errno)); - goto out_err; - } - - memset(&sp, 0, sizeof(sp)); - - sp.sa_family = AF_PPPOX; - sp.sa_protocol = PX_PROTO_OE; - sp.sa_addr.pppoe.sid = htons(conn->sid); - strcpy(sp.sa_addr.pppoe.dev, conn->serv->ifname); - memcpy(sp.sa_addr.pppoe.remote, conn->addr, ETH_ALEN); - - if (connect(sock, (struct sockaddr *)&sp, sizeof(sp))) { - log_error("pppoe: connect: %s\n", strerror(errno)); - goto out_err_close; - } - - conn->ppp.fd = sock; - - if (establish_ppp(&conn->ppp)) - goto out_err_close; - -#ifdef RADIUS - if (conn->tr101) { - conn->radius.send_access_request = pppoe_rad_send_access_request; - conn->radius.send_accounting_request = pppoe_rad_send_accounting_request; - rad_register_plugin(&conn->ppp, &conn->radius); - } -#endif - - conn->ppp_started = 1; - - dpado_check_next(__sync_add_and_fetch(&stat_active, 1)); - - return; - -out_err_close: - close(sock); -out_err: - disconnect(conn); -} - -static struct pppoe_conn_t *find_channel(struct pppoe_serv_t *serv, const uint8_t *cookie) -{ - struct pppoe_conn_t *conn; - - list_for_each_entry(conn, &serv->conn_list, entry) - if (!memcmp(conn->cookie, cookie, COOKIE_LENGTH)) - return conn; - - return NULL; -} - -static void print_tag_string(struct pppoe_tag *tag) -{ - int i; - - for (i = 0; i < ntohs(tag->tag_len); i++) - log_info2("%c", tag->tag_data[i]); -} - -static void print_tag_octets(struct pppoe_tag *tag) -{ - int i; - - for (i = 0; i < ntohs(tag->tag_len); i++) - log_info2("%02x", (uint8_t)tag->tag_data[i]); -} - -static void print_packet(uint8_t *pack) -{ - struct ethhdr *ethhdr = (struct ethhdr *)pack; - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - struct pppoe_tag *tag; - int n; - - log_info2("[PPPoE "); - - switch (hdr->code) { - case CODE_PADI: - log_info2("PADI"); - break; - case CODE_PADO: - log_info2("PADO"); - break; - case CODE_PADR: - log_info2("PADR"); - break; - case CODE_PADS: - log_info2("PADS"); - break; - case CODE_PADT: - log_info2("PADT"); - break; - } - - log_info2(" %02x:%02x:%02x:%02x:%02x:%02x => %02x:%02x:%02x:%02x:%02x:%02x", - ethhdr->h_source[0], ethhdr->h_source[1], ethhdr->h_source[2], ethhdr->h_source[3], ethhdr->h_source[4], ethhdr->h_source[5], - ethhdr->h_dest[0], ethhdr->h_dest[1], ethhdr->h_dest[2], ethhdr->h_dest[3], ethhdr->h_dest[4], ethhdr->h_dest[5]); - - log_info2(" sid=%04x", ntohs(hdr->sid)); - - for (n = 0; n < ntohs(hdr->length); n += sizeof(*tag) + ntohs(tag->tag_len)) { - tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + n); - switch (ntohs(tag->tag_type)) { - case TAG_END_OF_LIST: - log_info2(" <End-Of-List>"); - break; - case TAG_SERVICE_NAME: - log_info2(" <Service-Name "); - print_tag_string(tag); - log_info2(">"); - break; - case TAG_AC_NAME: - log_info2(" <AC-Name "); - print_tag_string(tag); - log_info2(">"); - break; - case TAG_HOST_UNIQ: - log_info2(" <Host-Uniq "); - print_tag_octets(tag); - log_info2(">"); - break; - case TAG_AC_COOKIE: - log_info2(" <AC-Cookie "); - print_tag_octets(tag); - log_info2(">"); - break; - case TAG_VENDOR_SPECIFIC: - if (ntohs(tag->tag_len) < 4) - log_info2(" <Vendor-Specific invalid>"); - else - log_info2(" <Vendor-Specific %x>", ntohl(*(uint32_t *)tag->tag_data)); - break; - case TAG_RELAY_SESSION_ID: - log_info2(" <Relay-Session-Id"); - print_tag_octets(tag); - log_info2(">"); - break; - case TAG_SERVICE_NAME_ERROR: - log_info2(" <Service-Name-Error>"); - break; - case TAG_AC_SYSTEM_ERROR: - log_info2(" <AC-System-Error>"); - break; - case TAG_GENERIC_ERROR: - log_info2(" <Generic-Error>"); - break; - default: - log_info2(" <Unknown (%x)>", ntohs(tag->tag_type)); - break; - } - } - - log_info2("]\n"); -} - -static void generate_cookie(struct pppoe_serv_t *serv, const uint8_t *src, uint8_t *cookie) -{ - MD5_CTX ctx; - DES_cblock key; - DES_key_schedule ks; - int i; - union { - DES_cblock b[3]; - uint8_t raw[24]; - } u1, u2; - - memset(&key, 0, sizeof(key)); - DES_random_key(&key); - DES_set_key(&key, &ks); - - MD5_Init(&ctx); - MD5_Update(&ctx, serv->secret, SECRET_LENGTH); - MD5_Update(&ctx, serv->hwaddr, ETH_ALEN); - MD5_Update(&ctx, src, ETH_ALEN); - MD5_Update(&ctx, &key, 8); - MD5_Final(u1.raw, &ctx); - - for (i = 0; i < 2; i++) - DES_ecb_encrypt(&u1.b[i], &u2.b[i], &ks, DES_ENCRYPT); - memcpy(u2.b[2], &key, 8); - - for (i = 0; i < 3; i++) - DES_ecb_encrypt(&u2.b[i], &u1.b[i], &serv->des_ks, DES_ENCRYPT); - - memcpy(cookie, u1.raw, 24); -} - -static int check_cookie(struct pppoe_serv_t *serv, const uint8_t *src, const uint8_t *cookie) -{ - MD5_CTX ctx; - DES_key_schedule ks; - int i; - union { - DES_cblock b[3]; - uint8_t raw[24]; - } u1, u2; - - memcpy(u1.raw, cookie, 24); - - for (i = 0; i < 3; i++) - DES_ecb_encrypt(&u1.b[i], &u2.b[i], &serv->des_ks, DES_DECRYPT); - - if (DES_set_key_checked(&u2.b[2], &ks)) - return -1; - - for (i = 0; i < 2; i++) - DES_ecb_encrypt(&u2.b[i], &u1.b[i], &ks, DES_DECRYPT); - - MD5_Init(&ctx); - MD5_Update(&ctx, serv->secret, SECRET_LENGTH); - MD5_Update(&ctx, serv->hwaddr, ETH_ALEN); - MD5_Update(&ctx, src, ETH_ALEN); - MD5_Update(&ctx, u2.b[2], 8); - MD5_Final(u2.raw, &ctx); - - return memcmp(u1.raw, u2.raw, 16); -} - -static void setup_header(uint8_t *pack, const uint8_t *src, const uint8_t *dst, int code, uint16_t sid) -{ - struct ethhdr *ethhdr = (struct ethhdr *)pack; - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - - memcpy(ethhdr->h_source, src, ETH_ALEN); - memcpy(ethhdr->h_dest, dst, ETH_ALEN); - ethhdr->h_proto = htons(ETH_P_PPP_DISC); - - hdr->ver = 1; - hdr->type = 1; - hdr->code = code; - hdr->sid = htons(sid); - hdr->length = 0; -} - -static void add_tag(uint8_t *pack, int type, const uint8_t *data, int len) -{ - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - struct pppoe_tag *tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length)); - - tag->tag_type = htons(type); - tag->tag_len = htons(len); - memcpy(tag->tag_data, data, len); - - hdr->length = htons(ntohs(hdr->length) + sizeof(*tag) + len); -} - -static void add_tag2(uint8_t *pack, const struct pppoe_tag *t) -{ - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - struct pppoe_tag *tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length)); - - memcpy(tag, t, sizeof(*t) + ntohs(t->tag_len)); - - hdr->length = htons(ntohs(hdr->length) + sizeof(*tag) + ntohs(t->tag_len)); -} - -static void pppoe_send(int fd, const uint8_t *pack) -{ - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - int n, s; - - s = ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length); - n = write(fd, pack, s); - if (n < 0 ) - log_error("pppoe: write: %s\n", strerror(errno)); - else if (n != s) { - log_warn("pppoe: short write %i/%i\n", n,s); - } -} - -static void pppoe_send_PADO(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, const struct pppoe_tag *service_name) -{ - uint8_t pack[ETHER_MAX_LEN]; - uint8_t cookie[COOKIE_LENGTH]; - - setup_header(pack, serv->hwaddr, addr, CODE_PADO, 0); - - add_tag(pack, TAG_AC_NAME, (uint8_t *)conf_ac_name, strlen(conf_ac_name)); - if (conf_service_name) - add_tag(pack, TAG_SERVICE_NAME, (uint8_t *)conf_service_name, strlen(conf_service_name)); - - if (service_name) - add_tag2(pack, service_name); - - generate_cookie(serv, addr, cookie); - add_tag(pack, TAG_AC_COOKIE, cookie, COOKIE_LENGTH); - - if (host_uniq) - add_tag2(pack, host_uniq); - - if (relay_sid) - add_tag2(pack, relay_sid); - - if (conf_verbose) { - log_info2("send "); - print_packet(pack); - } - - __sync_add_and_fetch(&stat_PADO_sent, 1); - pppoe_send(serv->hnd.fd, pack); -} - -static void pppoe_send_err(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, int code, int tag_type) -{ - uint8_t pack[ETHER_MAX_LEN]; - - setup_header(pack, serv->hwaddr, addr, code, 0); - - add_tag(pack, TAG_AC_NAME, (uint8_t *)conf_ac_name, strlen(conf_ac_name)); - add_tag(pack, tag_type, NULL, 0); - - if (host_uniq) - add_tag2(pack, host_uniq); - - if (relay_sid) - add_tag2(pack, relay_sid); - - if (conf_verbose) { - log_info2("send "); - print_packet(pack); - } - - pppoe_send(serv->hnd.fd, pack); -} - -static void pppoe_send_PADS(struct pppoe_conn_t *conn) -{ - uint8_t pack[ETHER_MAX_LEN]; - - setup_header(pack, conn->serv->hwaddr, conn->addr, CODE_PADS, conn->sid); - - add_tag(pack, TAG_AC_NAME, (uint8_t *)conf_ac_name, strlen(conf_ac_name)); - - add_tag2(pack, conn->service_name); - - if (conn->host_uniq) - add_tag2(pack, conn->host_uniq); - - if (conn->relay_sid) - add_tag2(pack, conn->relay_sid); - - if (conf_verbose) { - log_info2("send "); - print_packet(pack); - } - - __sync_add_and_fetch(&stat_PADS_sent, 1); - pppoe_send(conn->disc_sock, pack); -} - -static void pppoe_send_PADT(struct pppoe_conn_t *conn) -{ - uint8_t pack[ETHER_MAX_LEN]; - - setup_header(pack, conn->serv->hwaddr, conn->addr, CODE_PADT, conn->sid); - - add_tag(pack, TAG_AC_NAME, (uint8_t *)conf_ac_name, strlen(conf_ac_name)); - - add_tag2(pack, conn->service_name); - - if (conn->host_uniq) - add_tag2(pack, conn->host_uniq); - - if (conn->relay_sid) - add_tag2(pack, conn->relay_sid); - - if (conf_verbose) { - log_info2("send "); - print_packet(pack); - } - - pppoe_send(conn->disc_sock, pack); -} - -static void free_delayed_pado(struct delayed_pado_t *pado) -{ - triton_timer_del(&pado->timer); - - __sync_sub_and_fetch(&stat_delayed_pado, 1); - list_del(&pado->entry); - - if (pado->host_uniq) - _free(pado->host_uniq); - if (pado->relay_sid) - _free(pado->relay_sid); - if (pado->service_name) - _free(pado->service_name); - - mempool_free(pado); -} - -static void pado_timer(struct triton_timer_t *t) -{ - struct delayed_pado_t *pado = container_of(t, typeof(*pado), timer); - - if (!ppp_shutdown) - pppoe_send_PADO(pado->serv, pado->addr, pado->host_uniq, pado->relay_sid, pado->service_name); - - free_delayed_pado(pado); -} - -static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size) -{ - struct ethhdr *ethhdr = (struct ethhdr *)pack; - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - struct pppoe_tag *tag; - struct pppoe_tag *host_uniq_tag = NULL; - struct pppoe_tag *relay_sid_tag = NULL; - struct pppoe_tag *service_name_tag = NULL; - int n, service_match = 0; - struct delayed_pado_t *pado; - - __sync_add_and_fetch(&stat_PADI_recv, 1); - - if (ppp_shutdown || pado_delay == -1) - return; - - if (hdr->sid) { - log_warn("pppoe: discarding PADI packet (sid is not zero)\n"); - return; - } - - if (conf_verbose) { - log_info2("recv "); - print_packet(pack); - } - - for (n = 0; n < ntohs(hdr->length); n += sizeof(*tag) + ntohs(tag->tag_len)) { - tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + n); - switch (ntohs(tag->tag_type)) { - case TAG_END_OF_LIST: - break; - case TAG_SERVICE_NAME: - if (conf_service_name && tag->tag_len) { - if (ntohs(tag->tag_len) != strlen(conf_service_name)) - break; - if (memcmp(tag->tag_data, conf_service_name, ntohs(tag->tag_len))) - break; - service_match = 1; - } else { - service_name_tag = tag; - service_match = 1; - } - break; - case TAG_HOST_UNIQ: - host_uniq_tag = tag; - break; - case TAG_RELAY_SESSION_ID: - relay_sid_tag = tag; - break; - } - } - - if (!service_match) { - if (conf_verbose) - log_warn("pppoe: discarding PADI packet (Service-Name mismatch)\n"); - return; - } - - if (pado_delay) { - list_for_each_entry(pado, &serv->pado_list, entry) { - if (memcmp(pado->addr, ethhdr->h_source, ETH_ALEN)) - continue; - if (conf_verbose) - log_warn("pppoe: discarding PADI packet (already queued)\n"); - return; - } - pado = mempool_alloc(pado_pool); - memset(pado, 0, sizeof(*pado)); - pado->serv = serv; - memcpy(pado->addr, ethhdr->h_source, ETH_ALEN); - - if (host_uniq_tag) { - pado->host_uniq = _malloc(sizeof(*host_uniq_tag) + ntohs(host_uniq_tag->tag_len)); - memcpy(pado->host_uniq, host_uniq_tag, sizeof(*host_uniq_tag) + ntohs(host_uniq_tag->tag_len)); - } - - if (relay_sid_tag) { - pado->relay_sid = _malloc(sizeof(*relay_sid_tag) + ntohs(relay_sid_tag->tag_len)); - memcpy(pado->relay_sid, relay_sid_tag, sizeof(*relay_sid_tag) + ntohs(relay_sid_tag->tag_len)); - } - - if (service_name_tag) { - pado->service_name = _malloc(sizeof(*service_name_tag) + ntohs(service_name_tag->tag_len)); - memcpy(pado->service_name, service_name_tag, sizeof(*service_name_tag) + ntohs(service_name_tag->tag_len)); - } - - pado->timer.expire = pado_timer; - pado->timer.period = pado_delay; - - triton_timer_add(&serv->ctx, &pado->timer, 0); - - list_add_tail(&pado->entry, &serv->pado_list); - __sync_add_and_fetch(&stat_delayed_pado, 1); - } else - pppoe_send_PADO(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag); -} - -static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size) -{ - struct ethhdr *ethhdr = (struct ethhdr *)pack; - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - struct pppoe_tag *tag; - struct pppoe_tag *host_uniq_tag = NULL; - struct pppoe_tag *relay_sid_tag = NULL; - struct pppoe_tag *ac_cookie_tag = NULL; - struct pppoe_tag *service_name_tag = NULL; - struct pppoe_tag *tr101_tag = NULL; - int n, service_match = 0; - struct pppoe_conn_t *conn; - int vendor_id; - - __sync_add_and_fetch(&stat_PADR_recv, 1); - - if (ppp_shutdown) - return; - - if (!memcmp(ethhdr->h_dest, bc_addr, ETH_ALEN)) { - if (conf_verbose) - log_warn("pppoe: discard PADR (destination address is broadcast)\n"); - return; - } - - if (hdr->sid) { - if (conf_verbose) - log_warn("pppoe: discarding PADR packet (sid is not zero)\n"); - return; - } - - if (conf_verbose) { - log_info2("recv "); - print_packet(pack); - } - - for (n = 0; n < ntohs(hdr->length); n += sizeof(*tag) + ntohs(tag->tag_len)) { - tag = (struct pppoe_tag *)(pack + ETH_HLEN + sizeof(*hdr) + n); - switch (ntohs(tag->tag_type)) { - case TAG_END_OF_LIST: - break; - case TAG_SERVICE_NAME: - service_name_tag = tag; - if (tag->tag_len == 0) - service_match = 1; - else if (conf_service_name) { - if (ntohs(tag->tag_len) != strlen(conf_service_name)) - break; - if (memcmp(tag->tag_data, conf_service_name, ntohs(tag->tag_len))) - break; - service_match = 1; - } else { - service_match = 1; - } - break; - case TAG_HOST_UNIQ: - host_uniq_tag = tag; - break; - case TAG_AC_COOKIE: - ac_cookie_tag = tag; - break; - case TAG_RELAY_SESSION_ID: - relay_sid_tag = tag; - break; - case TAG_VENDOR_SPECIFIC: - if (ntohs(tag->tag_len) < 4) - continue; - vendor_id = ntohl(*(uint32_t *)tag->tag_data); - if (vendor_id == VENDOR_ADSL_FORUM) - tr101_tag = tag; - break; - } - } - - if (!ac_cookie_tag) { - if (conf_verbose) - log_warn("pppoe: discard PADR packet (no AC-Cookie tag present)\n"); - return; - } - - if (ntohs(ac_cookie_tag->tag_len) != COOKIE_LENGTH) { - if (conf_verbose) - log_warn("pppoe: discard PADR packet (incorrect AC-Cookie tag length)\n"); - return; - } - - if (check_cookie(serv, ethhdr->h_source, (uint8_t *)ac_cookie_tag->tag_data)) { - if (conf_verbose) - log_warn("pppoe: discard PADR packet (incorrect AC-Cookie)\n"); - return; - } - - if (!service_match) { - if (conf_verbose) - log_warn("pppoe: Service-Name mismatch\n"); - pppoe_send_err(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, CODE_PADS, TAG_SERVICE_NAME_ERROR); - return; - } - - pthread_mutex_lock(&serv->lock); - conn = find_channel(serv, (uint8_t *)ac_cookie_tag->tag_data); - if (conn && !conn->ppp.username) { - __sync_add_and_fetch(&stat_PADR_dup_recv, 1); - pppoe_send_PADS(conn); - } - pthread_mutex_unlock(&serv->lock); - - if (conn) - return; - - conn = allocate_channel(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag, tr101_tag, (uint8_t *)ac_cookie_tag->tag_data); - if (!conn) - pppoe_send_err(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, CODE_PADS, TAG_AC_SYSTEM_ERROR); - else { - pppoe_send_PADS(conn); - triton_context_call(&conn->ctx, (triton_event_func)connect_channel, conn); - } -} - -static void pppoe_recv_PADT(struct pppoe_serv_t *serv, uint8_t *pack) -{ - struct ethhdr *ethhdr = (struct ethhdr *)pack; - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - struct pppoe_conn_t *conn; - - if (!memcmp(ethhdr->h_dest, bc_addr, ETH_ALEN)) { - if (conf_verbose) - log_warn("pppoe: discard PADT (destination address is broadcast)\n"); - return; - } - - if (conf_verbose) { - log_info2("recv "); - print_packet(pack); - } - - pthread_mutex_lock(&serv->lock); - conn = serv->conn[ntohs(hdr->sid)]; - if (conn && !memcmp(conn->addr, ethhdr->h_source, ETH_ALEN)) - triton_context_call(&conn->ctx, (void (*)(void *))disconnect, conn); - pthread_mutex_unlock(&serv->lock); -} - -static int pppoe_serv_read(struct triton_md_handler_t *h) -{ - struct pppoe_serv_t *serv = container_of(h, typeof(*serv), hnd); - uint8_t pack[ETHER_MAX_LEN]; - struct ethhdr *ethhdr = (struct ethhdr *)pack; - struct pppoe_hdr *hdr = (struct pppoe_hdr *)(pack + ETH_HLEN); - int n; - - while (1) { - n = read(h->fd, pack, sizeof(pack)); - if (n < 0) { - if (errno == EAGAIN) - break; - log_error("pppoe: read: %s\n", strerror(errno)); - return 0; - } - - if (n < ETH_HLEN + sizeof(*hdr)) { - if (conf_verbose) - log_warn("pppoe: short packet received (%i)\n", n); - continue; - } - - if (mac_filter_check(ethhdr->h_source)) - continue; - - if (memcmp(ethhdr->h_dest, bc_addr, ETH_ALEN) && memcmp(ethhdr->h_dest, serv->hwaddr, ETH_ALEN)) - continue; - - if (!memcmp(ethhdr->h_source, bc_addr, ETH_ALEN)) { - if (conf_verbose) - log_warn("pppoe: discarding packet (host address is broadcast)\n"); - continue; - } - - if ((ethhdr->h_source[0] & 1) != 0) { - if (conf_verbose) - log_warn("pppoe: discarding packet (host address is not unicast)\n"); - continue; - } - - if (n < ETH_HLEN + sizeof(*hdr) + ntohs(hdr->length)) { - if (conf_verbose) - log_warn("pppoe: short packet received\n"); - continue; - } - - if (hdr->ver != 1) { - if (conf_verbose) - log_warn("pppoe: discarding packet (unsupported version %i)\n", hdr->ver); - continue; - } - - if (hdr->type != 1) { - if (conf_verbose) - log_warn("pppoe: discarding packet (unsupported type %i)\n", hdr->type); - } - - switch (hdr->code) { - case CODE_PADI: - pppoe_recv_PADI(serv, pack, n); - break; - case CODE_PADR: - pppoe_recv_PADR(serv, pack, n); - break; - case CODE_PADT: - pppoe_recv_PADT(serv, pack); - break; - } - } - return 0; -} - -static void pppoe_serv_close(struct triton_context_t *ctx) -{ - struct pppoe_serv_t *serv = container_of(ctx, typeof(*serv), ctx); - - triton_md_disable_handler(&serv->hnd, MD_MODE_READ | MD_MODE_WRITE); - - serv->stopping = 1; - - pthread_mutex_lock(&serv->lock); - if (!serv->conn_cnt) { - pthread_mutex_unlock(&serv->lock); - pppoe_server_free(serv); - return; - } - pthread_mutex_unlock(&serv->lock); -} - -void pppoe_server_start(const char *ifname, void *cli) -{ - struct pppoe_serv_t *serv; - int sock; - int opt = 1; - struct ifreq ifr; - struct sockaddr_ll sa; - - pthread_rwlock_rdlock(&serv_lock); - list_for_each_entry(serv, &serv_list, entry) { - if (!strcmp(serv->ifname, ifname)) { - if (cli) - cli_send(cli, "error: already exists\r\n"); - pthread_rwlock_unlock(&serv_lock); - return; - } - } - pthread_rwlock_unlock(&serv_lock); - - serv = _malloc(sizeof(*serv)); - memset(serv, 0, sizeof(*serv)); - - if (init_secret(serv)) { - if (cli) - cli_sendv(cli, "init secret failed\r\n"); - _free(serv); - return; - } - - sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PPP_DISC)); - if (sock < 0) { - if (cli) - cli_sendv(cli, "socket: %s\r\n", strerror(errno)); - log_emerg("pppoe: socket: %s\n", strerror(errno)); - _free(serv); - return; - } - - if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt))) { - if (cli) - cli_sendv(cli, "setsockopt(SO_BROADCAST): %s\r\n", strerror(errno)); - log_emerg("pppoe: setsockopt(SO_BROADCAST): %s\n", strerror(errno)); - goto out_err; - } - - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock, SIOCGIFHWADDR, &ifr)) { - if (cli) - cli_sendv(cli, "ioctl(SIOCGIFHWADDR): %s\r\n", strerror(errno)); - log_emerg("pppoe: ioctl(SIOCGIFHWADDR): %s\n", strerror(errno)); - goto out_err; - } - -#ifdef ARPHDR_ETHER - if (ifr.ifr_hwaddr.sa_family != ARPHDR_ETHER) { - log_emerg("pppoe: interface %s is not ethernet\n", ifname); - goto out_err; - } -#endif - - if ((ifr.ifr_hwaddr.sa_data[0] & 1) != 0) { - if (cli) - cli_sendv(cli, "interface %s has not unicast address\r\n", ifname); - log_emerg("pppoe: interface %s has not unicast address\n", ifname); - goto out_err; - } - - memcpy(serv->hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); - - if (ioctl(sock, SIOCGIFMTU, &ifr)) { - if (cli) - cli_sendv(cli, "ioctl(SIOCGIFMTU): %s\r\n", strerror(errno)); - log_emerg("pppoe: ioctl(SIOCGIFMTU): %s\n", strerror(errno)); - goto out_err; - } - - if (ifr.ifr_mtu < ETH_DATA_LEN) { - if (cli) - cli_sendv(cli, "interface %s has MTU of %i, should be %i\r\n", ifname, ifr.ifr_mtu, ETH_DATA_LEN); - log_emerg("pppoe: interface %s has MTU of %i, should be %i\n", ifname, ifr.ifr_mtu, ETH_DATA_LEN); - } - - if (ioctl(sock, SIOCGIFINDEX, &ifr)) { - if (cli) - cli_sendv(cli, "ioctl(SIOCGIFINDEX): %s\r\n", strerror(errno)); - log_emerg("pppoe: ioctl(SIOCGIFINDEX): %s\n", strerror(errno)); - goto out_err; - } - - memset(&sa, 0, sizeof(sa)); - sa.sll_family = AF_PACKET; - sa.sll_protocol = htons(ETH_P_PPP_DISC); - sa.sll_ifindex = ifr.ifr_ifindex; - - if (bind(sock, (struct sockaddr *)&sa, sizeof(sa))) { - if (cli) - cli_sendv(cli, "bind: %s\n", strerror(errno)); - log_emerg("pppoe: bind: %s\n", strerror(errno)); - goto out_err; - } - - if (fcntl(sock, F_SETFL, O_NONBLOCK)) { - if (cli) - cli_sendv(cli, "failed to set nonblocking mode: %s\n", strerror(errno)); - log_emerg("pppoe: failed to set nonblocking mode: %s\n", strerror(errno)); - goto out_err; - } - - serv->ctx.close = pppoe_serv_close; - serv->ctx.before_switch = log_switch; - serv->hnd.fd = sock; - serv->hnd.read = pppoe_serv_read; - serv->ifname = _strdup(ifname); - pthread_mutex_init(&serv->lock, NULL); - - INIT_LIST_HEAD(&serv->conn_list); - INIT_LIST_HEAD(&serv->pado_list); - - triton_context_register(&serv->ctx, NULL); - triton_md_register_handler(&serv->ctx, &serv->hnd); - triton_md_enable_handler(&serv->hnd, MD_MODE_READ); - triton_context_wakeup(&serv->ctx); - - pthread_rwlock_wrlock(&serv_lock); - list_add_tail(&serv->entry, &serv_list); - pthread_rwlock_unlock(&serv_lock); - - return; - -out_err: - close(sock); - _free(serv); -} - -static void _conn_stop(struct pppoe_conn_t *conn) -{ - ppp_terminate(&conn->ppp, 0, TERM_ADMIN_RESET); -} - -static void _server_stop(struct pppoe_serv_t *serv) -{ - struct pppoe_conn_t *conn; - - if (serv->stopping) - return; - - serv->stopping = 1; - triton_md_disable_handler(&serv->hnd, MD_MODE_READ | MD_MODE_WRITE); - - pthread_mutex_lock(&serv->lock); - if (!serv->conn_cnt) { - pthread_mutex_unlock(&serv->lock); - pppoe_server_free(serv); - return; - } - list_for_each_entry(conn, &serv->conn_list, entry) - triton_context_call(&conn->ctx, (triton_event_func)_conn_stop, conn); - pthread_mutex_unlock(&serv->lock); -} - -void pppoe_server_free(struct pppoe_serv_t *serv) -{ - struct delayed_pado_t *pado; - - pthread_rwlock_wrlock(&serv_lock); - list_del(&serv->entry); - pthread_rwlock_unlock(&serv_lock); - - while (!list_empty(&serv->pado_list)) { - pado = list_entry(serv->pado_list.next, typeof(*pado), entry); - free_delayed_pado(pado); - } - - triton_md_unregister_handler(&serv->hnd); - close(serv->hnd.fd); - triton_context_unregister(&serv->ctx); - _free(serv->ifname); - _free(serv); -} - -void pppoe_server_stop(const char *ifname) -{ - struct pppoe_serv_t *serv; - - pthread_rwlock_rdlock(&serv_lock); - list_for_each_entry(serv, &serv_list, entry) { - if (strcmp(serv->ifname, ifname)) - continue; - triton_context_call(&serv->ctx, (triton_event_func)_server_stop, serv); - break; - } - pthread_rwlock_unlock(&serv_lock); -} - -static int init_secret(struct pppoe_serv_t *serv) -{ - int fd; - DES_cblock key; - - fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - log_emerg("pppoe: cann't open /dev/urandom: %s\n", strerror(errno)); - return -1; - } - - if (read(fd, serv->secret, SECRET_LENGTH) < 0) { - log_emerg("pppoe: faild to read /dev/urandom\n", strerror(errno)); - close(fd); - return -1; - } - - close(fd); - - memset(key, 0, sizeof(key)); - DES_random_key(&key); - DES_set_key(&key, &serv->des_ks); - - return 0; -} - -static void __init pppoe_init(void) -{ - struct conf_sect_t *s = conf_get_section("pppoe"); - struct conf_option_t *opt; - - conn_pool = mempool_create(sizeof(struct pppoe_conn_t)); - pado_pool = mempool_create(sizeof(struct delayed_pado_t)); - - if (!s) { - log_emerg("pppoe: no configuration, disabled...\n"); - return; - } - - list_for_each_entry(opt, &s->items, entry) { - if (!strcmp(opt->name, "interface")) { - if (opt->val) - pppoe_server_start(opt->val, NULL); - } else if (!strcmp(opt->name, "verbose")) { - if (atoi(opt->val) > 0) - conf_verbose = 1; - } else if (!strcmp(opt->name, "ac-name") || !strcmp(opt->name, "AC-Name")) { - if (opt->val && strlen(opt->val)) - conf_ac_name = _strdup(opt->val); - } else if (!strcmp(opt->name, "service-name") || !strcmp(opt->name, "Service-Name")) { - if (opt->val && strlen(opt->val)) - conf_service_name = _strdup(opt->val); - } else if (!strcmp(opt->name, "pado-delay") || !strcmp(opt->name, "PADO-delay")) { - if (dpado_parse(opt->val)) - _exit(EXIT_FAILURE); - } else if (!strcmp(opt->name, "ifname-in-sid")) { - if (!opt->val) - continue; - if (!strcmp(opt->val, "called-sid")) - conf_ifname_in_sid = 1; - else if (!strcmp(opt->val, "calling-sid")) - conf_ifname_in_sid = 2; - else if (!strcmp(opt->val, "both")) - conf_ifname_in_sid = 3; - else if (atoi(opt->val) >= 0) - conf_ifname_in_sid = atoi(opt->val); - } - } - - if (!conf_ac_name) - conf_ac_name = _strdup("accel-pptp"); -} - diff --git a/accel-pptpd/ctrl/pppoe/pppoe.h b/accel-pptpd/ctrl/pppoe/pppoe.h deleted file mode 100644 index 2264dd16..00000000 --- a/accel-pptpd/ctrl/pppoe/pppoe.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef __PPPOE_H -#define __PPPOE_H - -#include <pthread.h> - -#include <openssl/des.h> - -#include <linux/if.h> -#include <linux/if_pppox.h> - -/* PPPoE codes */ -#define CODE_PADI 0x09 -#define CODE_PADO 0x07 -#define CODE_PADR 0x19 -#define CODE_PADS 0x65 -#define CODE_PADT 0xA7 -#define CODE_SESS 0x00 - -/* PPPoE Tags */ -#define TAG_END_OF_LIST 0x0000 -#define TAG_SERVICE_NAME 0x0101 -#define TAG_AC_NAME 0x0102 -#define TAG_HOST_UNIQ 0x0103 -#define TAG_AC_COOKIE 0x0104 -#define TAG_VENDOR_SPECIFIC 0x0105 -#define TAG_RELAY_SESSION_ID 0x0110 -#define TAG_SERVICE_NAME_ERROR 0x0201 -#define TAG_AC_SYSTEM_ERROR 0x0202 -#define TAG_GENERIC_ERROR 0x0203 - -/* Discovery phase states */ -#define STATE_SENT_PADI 0 -#define STATE_RECEIVED_PADO 1 -#define STATE_SENT_PADR 2 -#define STATE_SESSION 3 -#define STATE_TERMINATED 4 - -/* Header size of a PPPoE packet */ -#define PPPOE_OVERHEAD 6 /* type, code, session, length */ -#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD) -#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD) -#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2) - -#define VENDOR_ADSL_FORUM 0xde9 - -#define MAX_SID 65534 -#define SECRET_LENGTH 16 -#define COOKIE_LENGTH 24 - -struct pppoe_tag_t -{ - struct list_head entry; - int type; - int len; -}; - -struct pppoe_packet_t -{ - uint8_t src[ETH_ALEN]; - uint8_t dst[ETH_ALEN]; - int code; - uint16_t sid; - struct list_head tags; -}; - -struct pppoe_serv_t -{ - struct list_head entry; - struct triton_context_t ctx; - struct triton_md_handler_t hnd; - uint8_t hwaddr[ETH_ALEN]; - char *ifname; - - uint8_t secret[SECRET_LENGTH]; - DES_key_schedule des_ks; - - pthread_mutex_t lock; - struct pppoe_conn_t *conn[MAX_SID]; - uint16_t sid; - int stopping:1; - - unsigned int conn_cnt; - struct list_head conn_list; - struct list_head pado_list; -}; - -extern int conf_verbose; -extern char *conf_service_name; -extern char *conf_ac_name; -extern char *conf_pado_delay; - -extern unsigned int stat_active; -extern unsigned int stat_delayed_pado; -extern unsigned long stat_PADI_recv; -extern unsigned long stat_PADO_sent; -extern unsigned long stat_PADR_recv; -extern unsigned long stat_PADR_dup_recv; -extern unsigned long stat_PADS_sent; - -extern pthread_rwlock_t serv_lock; -extern struct list_head serv_list; - -int mac_filter_check(const uint8_t *addr); -void pppoe_server_start(const char *intf, void *client); -void pppoe_server_stop(const char *intf); - -extern int pado_delay; -void dpado_check_next(int conn_cnt); -void dpado_check_prev(int conn_cnt); -int dpado_parse(const char *str); - -struct rad_packet_t; -int tr101_send_access_request(struct pppoe_tag *tr101, struct rad_packet_t *pack); -int tr101_send_accounting_request(struct pppoe_tag *tr101, struct rad_packet_t *pack); - -#endif - diff --git a/accel-pptpd/ctrl/pppoe/tr101.c b/accel-pptpd/ctrl/pppoe/tr101.c deleted file mode 100644 index cfb0fbcf..00000000 --- a/accel-pptpd/ctrl/pppoe/tr101.c +++ /dev/null @@ -1,97 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include <netinet/in.h> -#include <net/ethernet.h> - -#include "triton.h" -#include "ppp.h" -#include "log.h" -#include "radius.h" -#include "memdebug.h" - -#include "pppoe.h" - -#define OPT_CIRCUIT_ID 0x01 -#define OPT_REMOTE_AGENT_ID 0x02 -#define OPT_ACTUAL_DATA_RATE_UP 0x81 -#define OPT_ACTUAL_DATA_RATE_DOWN 0x82 -#define OPT_MIN_DATA_RATE_UP 0x83 -#define OPT_MAX_DATA_RATE_DOWN 0x84 - -static int tr101_send_request(struct pppoe_tag *tr101, struct rad_packet_t *pack, int type) -{ - uint8_t *ptr = (uint8_t *)tr101->tag_data + 4; - uint8_t *endptr = (uint8_t *)tr101->tag_data + ntohs(tr101->tag_len); - int id, len; - char str[64]; - - while (ptr < endptr) { - if (ptr + 2 > endptr) - goto inval; - id = *ptr++; - len = *ptr++; - if (ptr + len - 2 > endptr) - goto inval; - if (type && id > 0x80) - continue; - switch (id) { - case OPT_CIRCUIT_ID: - if (len - 2 > 63) - goto inval; - memcpy(str, ptr, len); - str[len - 2] = 0; - if (rad_packet_add_str(pack, "ADSL-Forum", "ADSL-Agent-Circuit-Id", str)) - return -1; - break; - case OPT_REMOTE_AGENT_ID: - if (len - 2 > 63) - goto inval; - memcpy(str, ptr, len); - str[len - 2] = 0; - if (rad_packet_add_str(pack, "ADSL-Forum", "ADSL-Agent-Remote-Id", str)) - return -1; - break; - case OPT_ACTUAL_DATA_RATE_UP: - if (len != 6) - goto inval; - if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr))) - return -1; - break; - case OPT_ACTUAL_DATA_RATE_DOWN: - if (len != 6) - goto inval; - if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Downstream", ntohl(*(uint32_t *)ptr))) - return -1; - break; - case OPT_MIN_DATA_RATE_UP: - if (len != 6) - goto inval; - if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr))) - return -1; - break; - case OPT_MAX_DATA_RATE_DOWN: - if (len != 6) - goto inval; - if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr))) - return -1; - break; - } - ptr += len - 2; - } - - return 0; - -inval: - log_ppp_warn("pppoe:tr101: invalid tag received\n"); - return -1; -} - -int tr101_send_access_request(struct pppoe_tag *tr101, struct rad_packet_t *pack) -{ - return tr101_send_request(tr101, pack, 1); -} - -int tr101_send_accounting_request(struct pppoe_tag *tr101, struct rad_packet_t *pack) -{ - return tr101_send_request(tr101, pack, 0); -} diff --git a/accel-pptpd/ctrl/pptp/CMakeLists.txt b/accel-pptpd/ctrl/pptp/CMakeLists.txt deleted file mode 100644 index e9c27791..00000000 --- a/accel-pptpd/ctrl/pptp/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -ADD_LIBRARY(pptp SHARED pptp.c) - -INSTALL(TARGETS pptp LIBRARY DESTINATION lib/accel-pptp ) diff --git a/accel-pptpd/ctrl/pptp/pptp.c b/accel-pptpd/ctrl/pptp/pptp.c deleted file mode 100644 index 687aecbc..00000000 --- a/accel-pptpd/ctrl/pptp/pptp.c +++ /dev/null @@ -1,775 +0,0 @@ -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> - -#include "if_pppox.h" - -#include "events.h" -#include "list.h" -#include "pptp_prot.h" -#include "triton.h" -#include "log.h" -#include "ppp.h" -#include "mempool.h" -#include "iprange.h" -#include "utils.h" -#include "cli.h" - -#include "memdebug.h" - -#define STATE_IDLE 0 -#define STATE_ESTB 1 -#define STATE_PPP 2 -#define STATE_FIN 3 -#define STATE_CLOSE 4 - -struct pptp_conn_t -{ - struct triton_context_t ctx; - struct triton_md_handler_t hnd; - struct triton_timer_t timeout_timer; - struct triton_timer_t echo_timer; - int call_id; - int peer_call_id; - int state; - int echo_sent; - - uint8_t *in_buf; - int in_size; - uint8_t *out_buf; - int out_size; - int out_pos; - - struct ppp_ctrl_t ctrl; - struct ppp_t ppp; -}; - -static int conf_timeout = 5; -static int conf_echo_interval = 0; -static int conf_echo_failure = 3; -static int conf_verbose = 0; -static mempool_t conn_pool; - -static unsigned int stat_starting; -static unsigned int stat_active; - -static int pptp_read(struct triton_md_handler_t *h); -static int pptp_write(struct triton_md_handler_t *h); -static void pptp_timeout(struct triton_timer_t *); -static void ppp_started(struct ppp_t *); -static void ppp_finished(struct ppp_t *); - -static void disconnect(struct pptp_conn_t *conn) -{ - log_ppp_debug("pptp: disconnect\n"); - - triton_md_unregister_handler(&conn->hnd); - close(conn->hnd.fd); - - if (conn->timeout_timer.tpd) - triton_timer_del(&conn->timeout_timer); - - if (conn->echo_timer.tpd) - triton_timer_del(&conn->echo_timer); - - if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - conn->state = STATE_CLOSE; - ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } else if (conn->state != STATE_CLOSE) - __sync_sub_and_fetch(&stat_starting, 1); - - triton_event_fire(EV_CTRL_FINISHED, &conn->ppp); - - log_ppp_info1("disconnected\n"); - - triton_context_unregister(&conn->ctx); - - if (conn->ppp.chan_name) - _free(conn->ppp.chan_name); - - _free(conn->in_buf); - _free(conn->out_buf); - _free(conn->ctrl.calling_station_id); - _free(conn->ctrl.called_station_id); - mempool_free(conn); -} - -static int post_msg(struct pptp_conn_t *conn, void *buf, int size) -{ - int n; - if (conn->out_size) { - log_error("pptp: buffer is not empty\n"); - return -1; - } - - n=write(conn->hnd.fd, buf, size); - if (n < 0) { - if (errno == EINTR || errno == EAGAIN) - n = 0; - else { - if (errno != EPIPE) { - if (conf_verbose) - log_ppp_info2("pptp: write: %s\n", strerror(errno)); - return -1; - } - } - } - - if ( n<size ) { - memcpy(conn->out_buf, buf + n, size - n); - triton_md_enable_handler(&conn->hnd, MD_MODE_WRITE); - } - - return 0; -} - -static int send_pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn, int reason) -{ - struct pptp_stop_ctrl_conn msg = { - .header = PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RQST), - .reason_result = hton8(reason), - }; - - if (conf_verbose) - log_ppp_info2("send [PPTP Stop-Ctrl-Conn-Request <Reason %i>]\n", reason); - - return post_msg(conn, &msg, sizeof(msg)); -} - -static int send_pptp_stop_ctrl_conn_rply(struct pptp_conn_t *conn, int reason, int err_code) -{ - struct pptp_stop_ctrl_conn msg = { - .header = PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RPLY), - .reason_result = hton8(reason), - .error_code = hton8(err_code), - }; - - if (conf_verbose) - log_ppp_info2("send [PPTP Stop-Ctrl-Conn-Reply <Result %i> <Error %i>]\n", msg.reason_result, msg.error_code); - - return post_msg(conn, &msg, sizeof(msg)); -} -static int pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn) -{ - struct pptp_stop_ctrl_conn *msg = (struct pptp_stop_ctrl_conn *)conn->in_buf; - if (conf_verbose) - log_ppp_info2("recv [PPTP Stop-Ctrl-Conn-Request <Reason %i>]\n", msg->reason_result); - - send_pptp_stop_ctrl_conn_rply(conn, PPTP_CONN_STOP_OK, 0); - - return -1; -} - -static int pptp_stop_ctrl_conn_rply(struct pptp_conn_t *conn) -{ - struct pptp_stop_ctrl_conn *msg = (struct pptp_stop_ctrl_conn*)conn->in_buf; - if (conf_verbose) - log_ppp_info2("recv [PPTP Stop-Ctrl-Conn-Reply <Result %i> <Error %i>]\n", msg->reason_result, msg->error_code); - return -1; -} - -static int send_pptp_start_ctrl_conn_rply(struct pptp_conn_t *conn, int res_code, int err_code) -{ - struct pptp_start_ctrl_conn msg = { - .header = PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RPLY), - .version = htons(PPTP_VERSION), - .result_code = res_code, - .error_code = err_code, - .framing_cap = htonl(3), - .bearer_cap = htonl(3), - .max_channels = htons(1), - .firmware_rev = htons(PPTP_FIRMWARE_VERSION), - }; - - memset(msg.hostname, 0, sizeof(msg.hostname)); - strcpy((char*)msg.hostname, PPTP_HOSTNAME); - - memset(msg.vendor, 0, sizeof(msg.vendor)); - strcpy((char*)msg.vendor, PPTP_VENDOR); - - if (conf_verbose) - log_ppp_info2("send [PPTP Start-Ctrl-Conn-Reply <Version %i> <Result %i> <Error %i> <Framing %x> <Bearer %x> <Max-Chan %i>]\n", msg.version, msg.result_code, msg.error_code, ntohl(msg.framing_cap), ntohl(msg.bearer_cap), ntohs(msg.max_channels)); - - return post_msg(conn, &msg, sizeof(msg)); -} - -static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn) -{ - struct pptp_start_ctrl_conn *msg = (struct pptp_start_ctrl_conn *)conn->in_buf; - - if (conf_verbose) - log_ppp_info2("recv [PPTP Start-Ctrl-Conn-Request <Version %i> <Framing %x> <Bearer %x> <Max-Chan %i>]\n", msg->version, ntohl(msg->framing_cap), ntohl(msg->bearer_cap), ntohs(msg->max_channels)); - - if (conn->state != STATE_IDLE) { - log_ppp_warn("unexpected PPTP_START_CTRL_CONN_RQST\n"); - if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_EXISTS, 0)) - return -1; - return 0; - } - - if (msg->version != htons(PPTP_VERSION)) { - log_ppp_warn("PPTP version mismatch: expecting %x, received %s\n", PPTP_VERSION, msg->version); - if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_PROTOCOL, 0)) - return -1; - return 0; - } - /*if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) { - log_ppp_warn("connection does not supports sync mode\n"); - if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_GE, 0)) - return -1; - return 0; - }*/ - if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_SUCCESS, 0)) - return -1; - - triton_timer_mod(&conn->timeout_timer, 0); - - conn->state = STATE_ESTB; - - return 0; -} - -static int send_pptp_out_call_rply(struct pptp_conn_t *conn, struct pptp_out_call_rqst *rqst, int call_id, int res_code, int err_code) -{ - struct pptp_out_call_rply msg = { - .header = PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY), - .call_id = htons(call_id), - .call_id_peer = rqst->call_id, - .result_code = res_code, - .error_code = err_code, - .cause_code = 0, - .speed = rqst->bps_max, - .recv_size = rqst->recv_size, - .delay = 0, - .channel = 0, - }; - - if (conf_verbose) - log_ppp_info2("send [PPTP Outgoing-Call-Reply <Call-ID %x> <Peer-Call-ID %x> <Result %i> <Error %i> <Cause %i> <Speed %i> <Window-Size %i> <Delay %i> <Channel %x>]\n", ntohs(msg.call_id), ntohs(msg.call_id_peer), msg.result_code, msg.error_code, ntohs(msg.cause_code), ntohl(msg.speed), ntohs(msg.recv_size), ntohs(msg.delay), ntohl(msg.channel)); - - return post_msg(conn, &msg, sizeof(msg)); -} - -static int pptp_out_call_rqst(struct pptp_conn_t *conn) -{ - struct pptp_out_call_rqst *msg = (struct pptp_out_call_rqst *)conn->in_buf; - struct sockaddr_pppox src_addr, dst_addr; - struct sockaddr_in addr; - socklen_t addrlen; - int pptp_sock; - - if (conf_verbose) - log_ppp_info2("recv [PPTP Outgoing-Call-Request <Call-ID %x> <Call-Serial %x> <Min-BPS %i> <Max-BPS %i> <Bearer %x> <Framing %x> <Window-Size %i> <Delay %i>]\n", ntohs(msg->call_id), ntohs(msg->call_sernum), ntohl(msg->bps_min), ntohl(msg->bps_max), ntohl(msg->bearer), ntohl(msg->framing), ntohs(msg->recv_size), ntohs(msg->delay)); - - if (conn->state != STATE_ESTB) { - log_ppp_warn("unexpected PPTP_OUT_CALL_RQST\n"); - if (send_pptp_out_call_rply(conn, msg, 0, PPTP_CALL_RES_GE, PPTP_GE_NOCONN)) - return -1; - return 0; - } - - memset(&src_addr, 0, sizeof(src_addr)); - src_addr.sa_family = AF_PPPOX; - src_addr.sa_protocol = PX_PROTO_PPTP; - src_addr.sa_addr.pptp.call_id = 0; - addrlen = sizeof(addr); - getsockname(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); - src_addr.sa_addr.pptp.sin_addr = addr.sin_addr; - - memset(&dst_addr, 0, sizeof(dst_addr)); - dst_addr.sa_family = AF_PPPOX; - dst_addr.sa_protocol = PX_PROTO_PPTP; - dst_addr.sa_addr.pptp.call_id = htons(msg->call_id); - addrlen = sizeof(addr); - getpeername(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); - dst_addr.sa_addr.pptp.sin_addr = addr.sin_addr; - - pptp_sock = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP); - if (pptp_sock < 0) { - log_ppp_error("failed to create PPTP socket (%s)\n", strerror(errno)); - return -1; - } - if (bind(pptp_sock, (struct sockaddr*)&src_addr, sizeof(src_addr))) { - log_ppp_error("failed to bind PPTP socket (%s)\n", strerror(errno)); - close(pptp_sock); - return -1; - } - addrlen = sizeof(src_addr); - getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen); - - if (connect(pptp_sock, (struct sockaddr*)&dst_addr, sizeof(dst_addr))) { - log_ppp_error("failed to connect PPTP socket (%s)\n", strerror(errno)); - close(pptp_sock); - return -1; - } - - if (send_pptp_out_call_rply(conn, msg, src_addr.sa_addr.pptp.call_id, PPTP_CALL_RES_OK, 0)) - return -1; - - conn->call_id = src_addr.sa_addr.pptp.call_id; - conn->peer_call_id = msg->call_id; - conn->ppp.fd = pptp_sock; - conn->ppp.chan_name = _strdup(inet_ntoa(dst_addr.sa_addr.pptp.sin_addr)); - - triton_event_fire(EV_CTRL_STARTED, &conn->ppp); - - if (establish_ppp(&conn->ppp)) { - close(pptp_sock); - //if (send_pptp_stop_ctrl_conn_rqst(conn, 0, 0)) - conn->state = STATE_FIN; - return -1; - } - conn->state = STATE_PPP; - __sync_sub_and_fetch(&stat_starting, 1); - __sync_add_and_fetch(&stat_active, 1); - - if (conn->timeout_timer.tpd) - triton_timer_del(&conn->timeout_timer); - - if (conf_echo_interval) { - conn->echo_timer.period = conf_echo_interval * 1000; - triton_timer_add(&conn->ctx, &conn->echo_timer, 0); - } - - return 0; -} - -static int send_pptp_call_disconnect_notify(struct pptp_conn_t *conn, int result) -{ - struct pptp_call_clear_ntfy msg = { - .header = PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_NTFY), - .call_id = htons(conn->peer_call_id), - .result_code = result, - .error_code = 0, - .cause_code = 0, - }; - - if (conf_verbose) - log_ppp_info2("send [PPTP Call-Disconnect-Notify <Call-ID %x> <Result %i> <Error %i> <Cause %i>]\n", ntohs(msg.call_id), msg.result_code, msg.error_code, msg.cause_code); - - return post_msg(conn, &msg, sizeof(msg)); -} - -static int pptp_call_clear_rqst(struct pptp_conn_t *conn) -{ - struct pptp_call_clear_rqst *rqst = (struct pptp_call_clear_rqst *)conn->in_buf; - - if (conf_verbose) - log_ppp_info2("recv [PPTP Call-Clear-Request <Call-ID %x>]\n", ntohs(rqst->call_id)); - - if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - conn->state = STATE_CLOSE; - ppp_terminate(&conn->ppp, TERM_USER_REQUEST, 1); - } - - return send_pptp_call_disconnect_notify(conn, 4); -} - -static int pptp_echo_rqst(struct pptp_conn_t *conn) -{ - struct pptp_echo_rqst *in_msg = (struct pptp_echo_rqst *)conn->in_buf; - struct pptp_echo_rply out_msg = { - .header = PPTP_HEADER_CTRL(PPTP_ECHO_RPLY), - .identifier = in_msg->identifier, - .result_code = 1, - }; - - if (conf_verbose) { - log_ppp_debug("recv [PPTP Echo-Request <Identifier %x>]\n", in_msg->identifier); - log_ppp_debug("send [PPTP Echo-Reply <Identifier %x>]\n", out_msg.identifier); - } - - return post_msg(conn, &out_msg, sizeof(out_msg)); -} - -static int pptp_echo_rply(struct pptp_conn_t *conn) -{ - struct pptp_echo_rply *msg = (struct pptp_echo_rply *)conn->in_buf; - - if (conf_verbose) - log_ppp_debug("recv [PPTP Echo-Reply <Identifier %x>]\n", msg->identifier); - - if (msg->identifier != conn->echo_sent) { - log_ppp_warn("pptp:echo: identifier mismatch\n"); - //return -1; - } - conn->echo_sent = 0; - return 0; -} -static void pptp_send_echo(struct triton_timer_t *t) -{ - struct pptp_conn_t *conn = container_of(t, typeof(*conn), echo_timer); - struct pptp_echo_rqst msg = { - .header = PPTP_HEADER_CTRL(PPTP_ECHO_RQST), - }; - - if (++conn->echo_sent == conf_echo_failure) { - log_ppp_warn("pptp: no echo reply\n"); - disconnect(conn); - return; - } - - conn->echo_sent = random(); - msg.identifier = conn->echo_sent; - - if (conf_verbose) - log_ppp_debug("send [PPTP Echo-Request <Identifier %x>]\n", msg.identifier); - - if (post_msg(conn, &msg, sizeof(msg))) - disconnect(conn); -} - -static int process_packet(struct pptp_conn_t *conn) -{ - struct pptp_header *hdr = (struct pptp_header *)conn->in_buf; - switch(ntohs(hdr->ctrl_type)) - { - case PPTP_START_CTRL_CONN_RQST: - return pptp_start_ctrl_conn_rqst(conn); - case PPTP_STOP_CTRL_CONN_RQST: - return pptp_stop_ctrl_conn_rqst(conn); - case PPTP_STOP_CTRL_CONN_RPLY: - return pptp_stop_ctrl_conn_rply(conn); - case PPTP_OUT_CALL_RQST: - return pptp_out_call_rqst(conn); - case PPTP_ECHO_RQST: - return pptp_echo_rqst(conn); - case PPTP_ECHO_RPLY: - return pptp_echo_rply(conn); - case PPTP_CALL_CLEAR_RQST: - return pptp_call_clear_rqst(conn); - case PPTP_SET_LINK_INFO: - if (conf_verbose) - log_ppp_info2("recv [PPTP Set-Link-Info]\n"); - return 0; - default: - log_ppp_warn("recv [PPTP Unknown (%x)]\n", ntohs(hdr->ctrl_type)); - } - return 0; -} - -static int pptp_read(struct triton_md_handler_t *h) -{ - struct pptp_conn_t *conn=container_of(h,typeof(*conn),hnd); - struct pptp_header *hdr=(struct pptp_header *)conn->in_buf; - int n; - - while(1) { - n = read(h->fd, conn->in_buf + conn->in_size, PPTP_CTRL_SIZE_MAX - conn->in_size); - if (n < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - return 0; - log_ppp_error("pptp: read: %s\n",strerror(errno)); - goto drop; - } - if (n == 0) { - if (conf_verbose) - log_ppp_info2("pptp: disconnect by peer\n"); - goto drop; - } - conn->in_size += n; - if (conn->in_size >= sizeof(*hdr)) { - if (hdr->magic != htonl(PPTP_MAGIC)) { - log_ppp_error("pptp: invalid magic\n"); - goto drop; - } - if (ntohs(hdr->length) >= PPTP_CTRL_SIZE_MAX) { - log_ppp_error("pptp: message is too long\n"); - goto drop; - } - if (ntohs(hdr->length) > conn->in_size) - continue; - if (ntohs(hdr->length) <= conn->in_size) { - if (ntohs(hdr->length) != PPTP_CTRL_SIZE(ntohs(hdr->ctrl_type))) { - log_ppp_error("pptp: invalid message length\n"); - goto drop; - } - if (process_packet(conn)) - goto drop; - conn->in_size -= ntohs(hdr->length); - if (conn->in_size) - memmove(conn->in_buf, conn->in_buf + ntohs(hdr->length), conn->in_size); - } - } - } -drop: - disconnect(conn); - return 1; -} -static int pptp_write(struct triton_md_handler_t *h) -{ - struct pptp_conn_t *conn = container_of(h, typeof(*conn), hnd); - int n; - - while (1) { - n = write(h->fd, conn->out_buf+conn->out_pos, conn->out_size-conn->out_pos); - - if (n < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - n = 0; - else { - if (errno != EPIPE) { - if (conf_verbose) - log_ppp_info2("pptp: post_msg: %s\n", strerror(errno)); - } - disconnect(conn); - return 1; - } - } - - conn->out_pos += n; - if (conn->out_pos == conn->out_size) { - conn->out_pos = 0; - conn->out_size = 0; - triton_md_disable_handler(h, MD_MODE_WRITE); - return 0; - } - } -} -static void pptp_timeout(struct triton_timer_t *t) -{ - struct pptp_conn_t *conn = container_of(t, typeof(*conn), timeout_timer); - disconnect(conn); -} -static void pptp_close(struct triton_context_t *ctx) -{ - struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx); - if (conn->state == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - conn->state = STATE_CLOSE; - ppp_terminate(&conn->ppp, TERM_ADMIN_RESET, 1); - if (send_pptp_call_disconnect_notify(conn, 3)) { - triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); - return; - } - } else { - if (send_pptp_stop_ctrl_conn_rqst(conn, 0)) { - triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); - return; - } - } - - if (conn->timeout_timer.tpd) - triton_timer_mod(&conn->timeout_timer, 0); - else - triton_timer_add(ctx, &conn->timeout_timer, 0); -} -static void ppp_started(struct ppp_t *ppp) -{ - log_ppp_debug("pptp: ppp started\n"); -} -static void ppp_finished(struct ppp_t *ppp) -{ - struct pptp_conn_t *conn = container_of(ppp, typeof(*conn), ppp); - - if (conn->state != STATE_CLOSE) { - log_ppp_debug("pptp: ppp finished\n"); - conn->state = STATE_CLOSE; - __sync_sub_and_fetch(&stat_active, 1); - - if (send_pptp_call_disconnect_notify(conn, 3)) - triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); - else if (send_pptp_stop_ctrl_conn_rqst(conn, 0)) - triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); - else { - if (conn->timeout_timer.tpd) - triton_timer_mod(&conn->timeout_timer, 0); - else - triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); - } - } -} - -//================================== - -struct pptp_serv_t -{ - struct triton_context_t ctx; - struct triton_md_handler_t hnd; -}; - -static int pptp_connect(struct triton_md_handler_t *h) -{ - struct sockaddr_in addr; - socklen_t size = sizeof(addr); - int sock; - struct pptp_conn_t *conn; - - while(1) { - sock = accept(h->fd, (struct sockaddr *)&addr, &size); - if (sock < 0) { - if (errno == EAGAIN) - return 0; - log_error("pptp: accept failed: %s\n", strerror(errno)); - continue; - } - - if (ppp_shutdown) { - close(sock); - continue; - } - - log_info2("pptp: new connection from %s\n", inet_ntoa(addr.sin_addr)); - - if (iprange_client_check(addr.sin_addr.s_addr)) { - log_warn("pptp: IP is out of client-ip-range, droping connection...\n"); - close(sock); - continue; - } - - if (fcntl(sock, F_SETFL, O_NONBLOCK)) { - log_error("pptp: failed to set nonblocking mode: %s, closing connection...\n", strerror(errno)); - close(sock); - continue; - } - - conn = mempool_alloc(conn_pool); - memset(conn, 0, sizeof(*conn)); - conn->hnd.fd = sock; - conn->hnd.read = pptp_read; - conn->hnd.write = pptp_write; - conn->ctx.close = pptp_close; - conn->ctx.before_switch = log_switch; - conn->in_buf = _malloc(PPTP_CTRL_SIZE_MAX); - conn->out_buf = _malloc(PPTP_CTRL_SIZE_MAX); - conn->timeout_timer.expire = pptp_timeout; - conn->timeout_timer.period = conf_timeout * 1000; - conn->echo_timer.expire = pptp_send_echo; - conn->ctrl.ctx = &conn->ctx; - conn->ctrl.started = ppp_started; - conn->ctrl.finished = ppp_finished; - conn->ctrl.max_mtu = PPTP_MAX_MTU; - conn->ctrl.name = "pptp"; - - conn->ctrl.calling_station_id = _malloc(17); - conn->ctrl.called_station_id = _malloc(17); - u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.calling_station_id); - getsockname(sock, &addr, &size); - u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id); - - ppp_init(&conn->ppp); - conn->ppp.ctrl = &conn->ctrl; - - triton_context_register(&conn->ctx, &conn->ppp); - triton_md_register_handler(&conn->ctx, &conn->hnd); - triton_md_enable_handler(&conn->hnd,MD_MODE_READ); - triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); - triton_context_wakeup(&conn->ctx); - - triton_event_fire(EV_CTRL_STARTING, &conn->ppp); - - __sync_add_and_fetch(&stat_starting, 1); - } - return 0; -} -static void pptp_serv_close(struct triton_context_t *ctx) -{ - struct pptp_serv_t *s=container_of(ctx,typeof(*s),ctx); - triton_md_unregister_handler(&s->hnd); - close(s->hnd.fd); - triton_context_unregister(ctx); -} - -static struct pptp_serv_t serv= -{ - .hnd.read = pptp_connect, - .ctx.close = pptp_serv_close, - .ctx.before_switch = log_switch, -}; - -static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client) -{ - cli_send(client, "pptp:\r\n"); - cli_sendv(client," starting: %u\r\n", stat_starting); - cli_sendv(client," active: %u\r\n", stat_active); - - return CLI_CMD_OK; -} - -static void load_config(void) -{ - char *opt; - - opt = conf_get_opt("pptp", "timeout"); - if (opt && atoi(opt) > 0) - conf_timeout = atoi(opt); - - opt = conf_get_opt("pptp", "echo-interval"); - if (opt && atoi(opt) >= 0) - conf_echo_interval = atoi(opt); - - opt = conf_get_opt("pptp", "echo-failure"); - if (opt && atoi(opt) > 0) - conf_echo_failure = atoi(opt); - - opt = conf_get_opt("pptp", "verbose"); - if (opt && atoi(opt) > 0) - conf_verbose = 1; -} - -static void __init pptp_init(void) -{ - struct sockaddr_in addr; - char *opt; - - serv.hnd.fd = socket(PF_INET, SOCK_STREAM, 0); - if (serv.hnd.fd < 0) { - log_emerg("pptp: failed to create server socket: %s\n", strerror(errno)); - return; - } - addr.sin_family = AF_INET; - addr.sin_port = htons(PPTP_PORT); - - opt = conf_get_opt("pptp", "bind"); - if (opt) - addr.sin_addr.s_addr = inet_addr(opt); - else - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - setsockopt(serv.hnd.fd, SOL_SOCKET, SO_REUSEADDR, &serv.hnd.fd, 4); - if (bind (serv.hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { - log_emerg("pptp: failed to bind socket: %s\n", strerror(errno)); - close(serv.hnd.fd); - return; - } - - if (listen (serv.hnd.fd, 100) < 0) { - log_emerg("pptp: failed to listen socket: %s\n", strerror(errno)); - close(serv.hnd.fd); - return; - } - - if (fcntl(serv.hnd.fd, F_SETFL, O_NONBLOCK)) { - log_emerg("pptp: failed to set nonblocking mode: %s\n", strerror(errno)); - close(serv.hnd.fd); - return; - } - - conn_pool = mempool_create(sizeof(struct pptp_conn_t)); - - load_config(); - - triton_context_register(&serv.ctx, NULL); - triton_md_register_handler(&serv.ctx, &serv.hnd); - triton_md_enable_handler(&serv.hnd, MD_MODE_READ); - triton_context_wakeup(&serv.ctx); - - cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat"); - - triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config); -} - diff --git a/accel-pptpd/ctrl/pptp/pptp_prot.h b/accel-pptpd/ctrl/pptp/pptp_prot.h deleted file mode 100644 index ee8cb341..00000000 --- a/accel-pptpd/ctrl/pptp/pptp_prot.h +++ /dev/null @@ -1,299 +0,0 @@ -#ifndef PPTP_PROT_H -#define PPTP_PROT_H - -#include <sys/types.h> - -#define PPTP_MAX_MTU 1436 - -#define hton8(x) (x) -#define ntoh8(x) (x) -#define hton16(x) htons(x) -#define ntoh16(x) ntohs(x) -#define hton32(x) htonl(x) -#define ntoh32(x) ntohl(x) - -/* PPTP magic numbers: ----------------------------------------- */ - -#define PPTP_MAGIC 0x1A2B3C4D /* Magic cookie for PPTP datagrams */ -#define PPTP_PORT 1723 /* PPTP TCP port number */ -#define PPTP_PROTO 47 /* PPTP IP protocol number */ - -/* PPTP result codes:---------------------------------------- */ -#define PPTP_CONN_RES_SUCCESS 1 -#define PPTP_CONN_RES_GE 2 -#define PPTP_CONN_RES_EXISTS 3 -#define PPTP_CONN_RES_AUTH 4 -#define PPTP_CONN_RES_PROTOCOL 5 - -#define PPTP_CONN_STOP_OK 1 -#define PPTP_CONN_STOP_GE 2 - -#define PPTP_CALL_RES_OK 1 -#define PPTP_CALL_RES_GE 2 - -#define PPTP_GE_NOCONN 1 - -/* Control Connection Message Types: --------------------------- */ - -#define PPTP_MESSAGE_CONTROL 1 -#define PPTP_MESSAGE_MANAGE 2 - -/* Control Message Types: -------------------------------------- */ - -/* (Control Connection Management) */ -#define PPTP_START_CTRL_CONN_RQST 1 -#define PPTP_START_CTRL_CONN_RPLY 2 -#define PPTP_STOP_CTRL_CONN_RQST 3 -#define PPTP_STOP_CTRL_CONN_RPLY 4 -#define PPTP_ECHO_RQST 5 -#define PPTP_ECHO_RPLY 6 - -/* (Call Management) */ -#define PPTP_OUT_CALL_RQST 7 -#define PPTP_OUT_CALL_RPLY 8 -#define PPTP_IN_CALL_RQST 9 -#define PPTP_IN_CALL_RPLY 10 -#define PPTP_IN_CALL_CONNECT 11 -#define PPTP_CALL_CLEAR_RQST 12 -#define PPTP_CALL_CLEAR_NTFY 13 - -/* (Error Reporting) */ -#define PPTP_WAN_ERR_NTFY 14 - -/* (PPP Session Control) */ -#define PPTP_SET_LINK_INFO 15 - -/* PPTP version information: --------------------------------------*/ -#define PPTP_VERSION_STRING "1.00" -#define PPTP_VERSION 0x100 -#define PPTP_FIRMWARE_STRING "0.01" -#define PPTP_FIRMWARE_VERSION 0x001 - -#define PPTP_HOSTNAME "local" -#define PPTP_VENDOR "cananian" - -/* PPTP capabilities: ---------------------------------------------*/ - -/* (Framing capabilities for msg sender) */ -#define PPTP_FRAME_ASYNC 1 -#define PPTP_FRAME_SYNC 2 -#define PPTP_FRAME_ANY 3 - -/* (Bearer capabilities for msg sender) */ -#define PPTP_BEARER_ANALOG 1 -#define PPTP_BEARER_DIGITAL 2 -#define PPTP_BEARER_ANY 3 - -#define PPTP_RESULT_GENERAL_ERROR 2 - -/* (Reasons to close a connection) */ -#define PPTP_STOP_NONE 1 /* no good reason */ -#define PPTP_STOP_PROTOCOL 2 /* can't support peer's protocol version */ -#define PPTP_STOP_LOCAL_SHUTDOWN 3 /* requester is being shut down */ - -/* PPTP datagram structures (all data in network byte order): ----------*/ - -struct pptp_header -{ - uint16_t length; /* message length in octets, including header */ - uint16_t pptp_type; /* PPTP message type. 1 for control message. */ - uint32_t magic; /* this should be PPTP_MAGIC. */ - uint16_t ctrl_type; /* Control message type (0-15) */ - uint16_t reserved0; /* reserved. MUST BE ZERO. */ -}__attribute__((packed)); - -struct pptp_start_ctrl_conn /* for control message types 1 and 2 */ -{ - struct pptp_header header; - - uint16_t version; /* PPTP protocol version. = PPTP_VERSION */ - uint8_t result_code; /* these two fields should be zero on rqst msg*/ - uint8_t error_code; /* 0 unless result_code==2 (General Error) */ - uint32_t framing_cap; /* Framing capabilities */ - uint32_t bearer_cap; /* Bearer Capabilities */ - uint16_t max_channels; /* Maximum Channels (=0 for PNS, PAC ignores) */ - uint16_t firmware_rev; /* Firmware or Software Revision */ - uint8_t hostname[64]; /* Host Name (64 octets, zero terminated) */ - uint8_t vendor[64]; /* Vendor string (64 octets, zero term.) */ -}__attribute__((packed)); - -struct pptp_stop_ctrl_conn /* for control message types 3 and 4 */ -{ - struct pptp_header header; - - uint8_t reason_result; /* reason for rqst, result for rply */ - uint8_t error_code; /* MUST be 0, unless rply result==2 (general err)*/ - uint16_t reserved1; /* MUST be 0 */ -}__attribute__((packed)); - -struct pptp_echo_rqst /* for control message type 5 */ -{ - struct pptp_header header; - uint32_t identifier; /* arbitrary value set by sender which is used */ - /* to match up reply and request */ -}__attribute__((packed)); - -struct pptp_echo_rply /* for control message type 6 */ -{ - struct pptp_header header; - uint32_t identifier; /* should correspond to id of rqst */ - uint8_t result_code; - uint8_t error_code; /* =0, unless result_code==2 (general error) */ - uint16_t reserved1; /* MUST BE ZERO */ -}__attribute__((packed)); - -struct pptp_out_call_rqst /* for control message type 7 */ -{ - struct pptp_header header; - uint16_t call_id; /* Call ID (unique id used to multiplex data) */ - uint16_t call_sernum; /* Call Serial Number (used for logging) */ - uint32_t bps_min; /* Minimum BPS (lowest acceptable line speed) */ - uint32_t bps_max; /* Maximum BPS (highest acceptable line speed) */ - uint32_t bearer; /* Bearer type */ - uint32_t framing; /* Framing type */ - uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - uint16_t phone_len; /* Phone Number Length (num. of valid digits) */ - uint16_t reserved1; /* MUST BE ZERO */ - uint8_t phone_num[64]; /* Phone Number (64 octets, null term.) */ - uint8_t subaddress[64]; /* Subaddress (64 octets, null term.) */ -}__attribute__((packed)); - -struct pptp_out_call_rply /* for control message type 8 */ -{ - struct pptp_header header; - uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - uint8_t result_code; /* Result Code (1 is no errors) */ - uint8_t error_code; /* Error Code (=0 unless result_code==2) */ - uint16_t cause_code; /* Cause Code (addt'l failure information) */ - uint32_t speed; /* Connect Speed (in BPS) */ - uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - uint32_t channel; /* Physical Channel ID (for logging) */ -}__attribute__((packed)); - -struct pptp_in_call_rqst /* for control message type 9 */ -{ - struct pptp_header header; - uint16_t call_id; /* Call ID (unique id used to multiplex data) */ - uint16_t call_sernum; /* Call Serial Number (used for logging) */ - uint32_t bearer; /* Bearer type */ - uint32_t channel; /* Physical Channel ID (for logging) */ - uint16_t dialed_len; /* Dialed Number Length (# of valid digits) */ - uint16_t dialing_len; /* Dialing Number Length (# of valid digits) */ - uint8_t dialed_num[64]; /* Dialed Number (64 octets, zero term.) */ - uint8_t dialing_num[64]; /* Dialing Number (64 octets, zero term.) */ - uint8_t subaddress[64]; /* Subaddress (64 octets, zero term.) */ -}__attribute__((packed)); - -struct pptp_in_call_rply /* for control message type 10 */ -{ - struct pptp_header header; - uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - uint8_t result_code; /* Result Code (1 is no errors) */ - uint8_t error_code; /* Error Code (=0 unless result_code==2) */ - uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - uint16_t reserved1; /* MUST BE ZERO */ -}__attribute__((packed)); - -struct pptp_in_call_connect /* for control message type 11 */ -{ - struct pptp_header header; - uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - uint16_t reserved1; /* MUST BE ZERO */ - uint32_t speed; /* Connect Speed (in BPS) */ - uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - uint32_t framing; /* Framing type */ -}__attribute__((packed)); - -struct pptp_call_clear_rqst /* for control message type 12 */ -{ - struct pptp_header header; - uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - uint16_t reserved1; /* MUST BE ZERO */ -}__attribute__((packed)); - -struct pptp_call_clear_ntfy /* for control message type 13 */ -{ - struct pptp_header header; - uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - uint8_t result_code; /* Result Code */ - uint8_t error_code; /* Error Code (=0 unless result_code==2) */ - uint16_t cause_code; /* Cause Code (for ISDN, is Q.931 cause code) */ - uint16_t reserved1; /* MUST BE ZERO */ - uint8_t call_stats[128]; /* Call Statistics: 128 octets, ascii, 0-term */ -}__attribute__((packed)); - -struct pptp_wan_err_ntfy /* for control message type 14 */ -{ - struct pptp_header header; - uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - uint16_t reserved1; /* MUST BE ZERO */ - uint32_t crc_errors; /* CRC errors */ - uint32_t frame_errors; /* Framing errors */ - uint32_t hard_errors; /* Hardware overruns */ - uint32_t buff_errors; /* Buffer overruns */ - uint32_t time_errors; /* Time-out errors */ - uint32_t align_errors; /* Alignment errors */ -}__attribute__((packed)); - -struct pptp_set_link_info /* for control message type 15 */ -{ - struct pptp_header header; - uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst) */ - uint16_t reserved1; /* MUST BE ZERO */ - uint32_t send_accm; /* Send ACCM (for PPP packets; default 0xFFFFFFFF)*/ - uint32_t recv_accm; /* Receive ACCM (for PPP pack.;default 0xFFFFFFFF)*/ -}__attribute__((packed)); - -/* helpful #defines: -------------------------------------------- */ -#define pptp_isvalid_ctrl(header, type, length) \ - (!( ( ntoh16(((struct pptp_header *)header)->length) < (length) ) || \ - ( ntoh16(((struct pptp_header *)header)->pptp_type) !=(type) ) || \ - ( ntoh32(((struct pptp_header *)header)->magic) !=PPTP_MAGIC) || \ - ( ntoh16(((struct pptp_header *)header)->ctrl_type) > PPTP_SET_LINK_INFO) || \ - ( ntoh16(((struct pptp_header *)header)->reserved0) !=0 ) )) - -#define PPTP_HEADER_CTRL(type) \ -{ hton16(PPTP_CTRL_SIZE(type)), \ - hton16(PPTP_MESSAGE_CONTROL), \ - hton32(PPTP_MAGIC), \ - hton16(type), 0 } - -#define PPTP_CTRL_SIZE(type) ( \ -(type==PPTP_START_CTRL_CONN_RQST)?sizeof(struct pptp_start_ctrl_conn): \ -(type==PPTP_START_CTRL_CONN_RPLY)?sizeof(struct pptp_start_ctrl_conn): \ -(type==PPTP_STOP_CTRL_CONN_RQST )?sizeof(struct pptp_stop_ctrl_conn): \ -(type==PPTP_STOP_CTRL_CONN_RPLY )?sizeof(struct pptp_stop_ctrl_conn): \ -(type==PPTP_ECHO_RQST )?sizeof(struct pptp_echo_rqst): \ -(type==PPTP_ECHO_RPLY )?sizeof(struct pptp_echo_rply): \ -(type==PPTP_OUT_CALL_RQST )?sizeof(struct pptp_out_call_rqst): \ -(type==PPTP_OUT_CALL_RPLY )?sizeof(struct pptp_out_call_rply): \ -(type==PPTP_IN_CALL_RQST )?sizeof(struct pptp_in_call_rqst): \ -(type==PPTP_IN_CALL_RPLY )?sizeof(struct pptp_in_call_rply): \ -(type==PPTP_IN_CALL_CONNECT )?sizeof(struct pptp_in_call_connect): \ -(type==PPTP_CALL_CLEAR_RQST )?sizeof(struct pptp_call_clear_rqst): \ -(type==PPTP_CALL_CLEAR_NTFY )?sizeof(struct pptp_call_clear_ntfy): \ -(type==PPTP_WAN_ERR_NTFY )?sizeof(struct pptp_wan_err_ntfy): \ -(type==PPTP_SET_LINK_INFO )?sizeof(struct pptp_set_link_info): \ -0) -#define max(a,b) (((a)>(b))?(a):(b)) -#define PPTP_CTRL_SIZE_MAX ( \ -max(sizeof(struct pptp_start_ctrl_conn), \ -max(sizeof(struct pptp_echo_rqst), \ -max(sizeof(struct pptp_echo_rply), \ -max(sizeof(struct pptp_out_call_rqst), \ -max(sizeof(struct pptp_out_call_rply), \ -max(sizeof(struct pptp_in_call_rqst), \ -max(sizeof(struct pptp_in_call_rply), \ -max(sizeof(struct pptp_in_call_connect), \ -max(sizeof(struct pptp_call_clear_rqst), \ -max(sizeof(struct pptp_call_clear_ntfy), \ -max(sizeof(struct pptp_wan_err_ntfy), \ -max(sizeof(struct pptp_set_link_info), 0))))))))))))) - -#endif |