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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
#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_MIN_DATA_RATE_DOWN 0x84
#define OPT_ATT_DATA_RATE_UP 0x85
#define OPT_ATT_DATA_RATE_DOWN 0x86
#define OPT_MAX_DATA_RATE_UP 0x87
#define OPT_MAX_DATA_RATE_DOWN 0x88
#define OPT_MIN_DATA_RATE_UP_LP 0x89
#define OPT_MIN_DATA_RATE_DOWN_LP 0x8A
#define OPT_MAX_INTERL_DELAY_UP 0x8B
#define OPT_ACTUAL_INTERL_DELAY_UP 0x8C
#define OPT_MAX_INTER_DELAY_DOWN 0x8D
#define OPT_ACTUAL_INTER_DELAY_DOWN 0x8E
#define ACCESS_LOOP_ENCAP 0x90
#define IFW_SESSION 0xFE
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 > endptr)
goto inval;
/* Section 4 of RFC 4679 states that attributes 0x83 to 0x8E
* mustn't be included in RADIUS access requests.
*/
if (type && id > 0x82 && id < 0x90) {
ptr += len;
continue;
}
switch (id) {
case OPT_CIRCUIT_ID:
if (len > 63)
goto inval;
memcpy(str, ptr, len);
str[len] = 0;
if (rad_packet_add_str(pack, "ADSL-Forum", "ADSL-Agent-Circuit-Id", str))
return -1;
break;
case OPT_REMOTE_AGENT_ID:
if (len > 63)
goto inval;
memcpy(str, ptr, len);
str[len] = 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 != 4)
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 != 4)
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 != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_DOWN:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Downstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_ATT_DATA_RATE_UP:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Attainable-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_ATT_DATA_RATE_DOWN:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Attainable-Data-Rate-Downstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MAX_DATA_RATE_UP:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MAX_DATA_RATE_DOWN:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Downstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_UP_LP:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream-Low-Power", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_DOWN_LP:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Downstream-Low-Power", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MAX_INTERL_DELAY_UP:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Interleaving-Delay-Upstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_ACTUAL_INTERL_DELAY_UP:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Interleaving-Delay-Upstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_MAX_INTER_DELAY_DOWN:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Interleaving-Delay-Downstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case OPT_ACTUAL_INTER_DELAY_DOWN:
if (len != 4)
goto inval;
if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Interleaving-Delay-Downstream", ntohl(*(uint32_t *)ptr)))
return -1;
break;
case ACCESS_LOOP_ENCAP:
if (len != 3)
goto inval;
memcpy(str, ptr, 3);
if (rad_packet_add_octets(pack, "ADSL-Forum", "Access-Loop-Encapsulation", (uint8_t *)str, 3))
return -1;
break;
case IFW_SESSION:
if (len != 0)
goto inval;
if (rad_packet_add_octets(pack, "ADSL-Forum", "IWF-Session", NULL, 0))
return -1;
break;
}
ptr += len;
}
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);
}
|