1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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);
}
|