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
|
From 12778d1e9296b6dbf190a80dcf407b24f9821f95 Mon Sep 17 00:00:00 2001
From: zsdc <taras@vyos.io>
Date: Tue, 4 Apr 2023 11:15:26 +0300
Subject: [PATCH] L2TP: Include Calling-Number to Calling-Station-ID RADIUS
attribute
Patch authored by Alexander Serkin from
https://phabricator.accel-ppp.org/T59
---
accel-pppd/ctrl/l2tp/l2tp.c | 112 ++++++++++++++++++++++++++++++------
1 file changed, 93 insertions(+), 19 deletions(-)
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index 027d710..c541c60 100644
--- a/accel-pppd/ctrl/l2tp/l2tp.c
+++ b/accel-pppd/ctrl/l2tp/l2tp.c
@@ -123,6 +123,11 @@ struct l2tp_sess_t
struct l2tp_conn_t *paren_conn;
uint16_t sid;
uint16_t peer_sid;
+/* We will keep l2tp attributes Calling-Number/Called-Number and their length while the session exists */
+ char *calling_num;
+ int calling_num_len;
+ char *called_num;
+ int called_num_len;
unsigned int ref_count;
int state1;
@@ -979,6 +984,10 @@ static void __session_destroy(struct l2tp_sess_t *sess)
_free(sess->ctrl.calling_station_id);
if (sess->ctrl.called_station_id)
_free(sess->ctrl.called_station_id);
+ if (sess->calling_num)
+ _free(sess->calling_num);
+ if (sess->called_num)
+ _free(sess->called_num);
log_session(log_info2, sess, "session destroyed\n");
@@ -1771,25 +1780,52 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess)
sess->ctrl.max_mtu = conf_ppp_max_mtu;
sess->ctrl.mppe = conf_mppe;
- sess->ctrl.calling_station_id = _malloc(17);
- if (sess->ctrl.calling_station_id == NULL) {
- log_session(log_error, sess,
- "impossible to start data channel:"
- " allocation of calling station ID failed\n");
- goto err;
+ /* If l2tp calling number avp exists, we use it, otherwise we use lac ip */
+ if (sess->calling_num != NULL) {
+ sess->ctrl.calling_station_id = _malloc(sess->calling_num_len+1);
+ if (sess->ctrl.calling_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of calling station ID failed\n");
+ goto err;
+ }else {
+ strcpy(sess->ctrl.calling_station_id, sess->calling_num);
+ }
+ } else {
+ sess->ctrl.calling_station_id = _malloc(17);
+ if (sess->ctrl.calling_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of calling station ID failed\n");
+ goto err;
+ } else {
+ u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr,
+ sess->ctrl.calling_station_id);
+ }
}
- u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr,
- sess->ctrl.calling_station_id);
-
- sess->ctrl.called_station_id = _malloc(17);
- if (sess->ctrl.called_station_id == NULL) {
- log_session(log_error, sess,
- "impossible to start data channel:"
- " allocation of called station ID failed\n");
- goto err;
+ /* If l2tp called number avp exists, we use it, otherwise we use my ip */
+ if (sess->called_num != NULL) {
+ sess->ctrl.called_station_id = _malloc(sess->called_num_len+1);
+ if (sess->ctrl.called_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of called station ID failed\n");
+ goto err;
+ } else {
+ strcpy(sess->ctrl.called_station_id, sess->called_num);
+ }
+ } else {
+ sess->ctrl.called_station_id = _malloc(17);
+ if (sess->ctrl.called_station_id == NULL) {
+ log_session(log_error, sess,
+ "impossible to start data channel:"
+ " allocation of called station ID failed\n");
+ goto err;
+ } else {
+ u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr,
+ sess->ctrl.called_station_id);
+ }
}
- u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr,
- sess->ctrl.called_station_id);
if (conf_ip_pool) {
sess->ppp.ses.ipv4_pool_name = _strdup(conf_ip_pool);
@@ -3295,6 +3331,10 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
uint16_t sid = 0;
uint16_t res = 0;
uint16_t err = 0;
+ uint8_t *calling[254] = {0};
+ uint8_t *called[254] = {0};
+ int n = 0;
+ int m = 0;
if (conn->state != STATE_ESTB && conn->lns_mode) {
log_tunnel(log_warn, conn, "discarding unexpected ICRQ\n");
@@ -3332,7 +3372,17 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
case Call_Serial_Number:
case Bearer_Type:
case Calling_Number:
+ /* Save Calling-Number L2TP attribute locally */
+ if (attr->attr->id == Calling_Number) {
+ n = attr->length;
+ memcpy(calling,attr->val.octets,n);
+ }
case Called_Number:
+ /* Save Called-Number L2TP attribute locally */
+ if (attr->attr->id == Called_Number) {
+ m = attr->length;
+ memcpy(called,attr->val.octets,m);
+ }
case Sub_Address:
case Physical_Channel_ID:
break;
@@ -3371,6 +3421,30 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
sess->peer_sid = peer_sid;
sid = sess->sid;
+ /* Allocate memory for Calling-Number if exists, and put it to l2tp_sess_t structure */
+ if (calling != NULL && n > 0) {
+ sess->calling_num = _malloc(n+1);
+ if (sess->calling_num == NULL) {
+ log_tunnel(log_warn, conn, "can't allocate memory for Calling Number attribute. Will use LAC IP instead\n");
+ }else{
+ memcpy(sess->calling_num, calling, n);
+ sess->calling_num[n] = '\0';
+ sess->calling_num_len = n;
+ }
+ }
+
+ /* Allocate memory for Called-Number if exists, and put it to l2tp_sess_t structure */
+ if (called != NULL && m > 1) {
+ sess->called_num = _malloc(m+1);
+ if (sess->called_num == NULL) {
+ log_tunnel(log_warn, conn, "can't allocate memory for Called Number attribute. Will use my IP instead\n");
+ } else {
+ memcpy(sess->called_num, called, m);
+ sess->called_num[m] = '\0';
+ sess->called_num_len = m;
+ }
+ }
+
if (unknown_attr) {
log_tunnel(log_error, conn, "impossible to handle ICRQ:"
" unknown mandatory attribute type %i,"
@@ -3390,8 +3464,8 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn,
goto out_reject;
}
- log_tunnel(log_info1, conn, "new session %hu-%hu created following"
- " reception of ICRQ\n", sid, peer_sid);
+ log_tunnel(log_info1, conn, "new session %hu-%hu with calling num %s len %d, called num %s len %d created following"
+ " reception of ICRQ\n", sid, peer_sid, sess->calling_num, sess->calling_num_len, sess->called_num, sess->called_num_len);
return 0;
--
2.34.1
|