summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/pppoe/tr101.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl/pppoe/tr101.c')
-rw-r--r--accel-pppd/ctrl/pppoe/tr101.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/accel-pppd/ctrl/pppoe/tr101.c b/accel-pppd/ctrl/pppoe/tr101.c
new file mode 100644
index 00000000..cfb0fbcf
--- /dev/null
+++ b/accel-pppd/ctrl/pppoe/tr101.c
@@ -0,0 +1,97 @@
+#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);
+}