2 * Add functionality "LAC" to l2tpns.
3 * Used to forward a ppp session to another "LNS".
14 /* sequence diagram: Client <--> LAC <--> LNS1 <--> LNS2
17 * Client <-------------------> LAC
18 * Challenge (CHAP/PAP)
19 * Client <-------------------> LAC
21 * LAC --------------------> LNS1 (Tunnel Open)
23 * LAC <-------------------- LNS1 (Tunnel Open)
25 * LAC --------------------> LNS1 (Tunnel Open)
27 * LAC <-------------------- LNS1 (Tunnel Open)
29 * LAC --------------------> LNS1 (Session Open)
31 * LAC <-------------------- LNS1 (Session Open)
33 * LAC --------------------> LNS1 (Session Open)
35 * LAC <-------------------- LNS1 (Session Open)
37 * Client <---------------------------------------------> LNS1
38 * Challenge (CHAP/PAP)
39 * Client <---------------------------------------------> LNS1
41 * LNS1 --------------------> LNS2 (Tunnel Open)
43 * LNS1 <-------------------- LNS2 (Tunnel Open)
45 * LNS1 --------------------> LNS2 (Tunnel Open)
47 * LNS1 <-------------------- LNS2 (Tunnel Open)
49 * LNS1 --------------------> LNS2 (Session Open)
51 * LNS1 <-------------------- LNS2 (Session Open)
53 * LNS1 --------------------> LNS2 (Session Open)
55 * LNS1 <-------------------- LNS2 (Session Open)
57 * Client <------------------------------------------------------------------------> LNS2
58 * PAP/CHAP Authentification
59 * Client <------------------------------------------------------------------------> LNS2
61 * Client <------------------------------------------------------------------------> LNS2
65 #define MAXRLNSTUNNEL 101
67 typedef uint16_t confrlnsidt
;
70 * Possible configrlns states
71 * TUNNELFREE -> TUNNELOPEN -> TUNNELDIE -> TUNNELFREE
75 CONFRLNSFREE
= 0, // Not in use
76 CONFRLNSSET
// Config Set
82 tunnelidt tid
; // near end tunnel ID
83 int state
; // conf state (tunnelstate enum)
84 in_addr_t ip
; // Ip for far end
85 uint16_t port
; // port for far end
86 hasht auth
; // request authenticator
87 char strmaskuser
[MAXUSER
];
88 char l2tp_secret
[64]; // L2TP shared secret
92 configrlns
*pconfigrlns
= NULL
; // Array of tunnel structures.
94 // Init data structures
95 void initremotelnsdata()
99 if ( !(pconfigrlns
= shared_malloc(sizeof(pconfigrlns
[0]) * MAXRLNSTUNNEL
)) )
101 LOG(0, 0, 0, "Error doing malloc for tunnels lac: %s\n", strerror(errno
));
105 memset(pconfigrlns
, 0, sizeof(pconfigrlns
[0]) * MAXRLNSTUNNEL
);
107 // Mark all the tunnels as undefined (waiting to be filled in by a download).
108 for (i
= 1; i
< MAXRLNSTUNNEL
; i
++)
109 pconfigrlns
[i
].state
= CONFRLNSFREE
; // mark it as not filled in.
111 config
->highest_rlnsid
= 0;
114 // Check if must be forwarded to another LNS
115 int forwardtolns(sessionidt s
, char * puser
)
120 for (i
= 1; i
<= config
->highest_rlnsid
; ++i
)
122 if ( NULL
!= strstr(puser
, pconfigrlns
[i
].strmaskuser
))
124 t
= pconfigrlns
[i
].tid
;
126 if ((t
!= 0) && (tunnel
[t
].ip
!= pconfigrlns
[i
].ip
))
128 pconfigrlns
[i
].tid
= t
= 0;
129 LOG(1, 0, t
, "Tunnel ID inconsistency\n");
134 if (main_quit
== QUIT_SHUTDOWN
) return 0;
137 if (!(t
= lac_new_tunnel()))
139 LOG(1, 0, 0, "No more tunnels\n");
140 STAT(tunnel_overflow
);
144 tunnel
[t
].ip
= pconfigrlns
[i
].ip
;
145 tunnel
[t
].port
= pconfigrlns
[i
].port
;
146 tunnel
[t
].window
= 4; // default window
147 STAT(tunnel_created
);
148 LOG(1, 0, t
, "New (REMOTE LNS) tunnel to %s:%u ID %u\n", fmtaddr(htonl(tunnel
[t
].ip
), 0), tunnel
[t
].port
, t
);
150 random_data(pconfigrlns
[i
].auth
, sizeof(pconfigrlns
[i
].auth
));
152 pconfigrlns
[i
].tid
= t
;
154 lac_send_SCCRQ(t
, pconfigrlns
[i
].auth
, sizeof(pconfigrlns
[i
].auth
));
156 else if (tunnel
[t
].state
== TUNNELOPEN
)
158 if (main_quit
!= QUIT_SHUTDOWN
)
160 /**********************/
161 /** Open New session **/
162 /**********************/
163 sessionidt new_sess
= sessionfree
;
165 sessionfree
= session
[new_sess
].next
;
166 memset(&session
[new_sess
], 0, sizeof(session
[new_sess
]));
168 if (new_sess
> config
->cluster_highest_sessionid
)
169 config
->cluster_highest_sessionid
= new_sess
;
171 session
[new_sess
].opened
= time_now
;
172 session
[new_sess
].tunnel
= t
;
173 session
[new_sess
].last_packet
= session
[s
].last_data
= time_now
;
175 session
[new_sess
].ppp
.phase
= Establish
;
176 session
[new_sess
].ppp
.lcp
= Starting
;
178 // Sent ICRQ Incoming-call-request
179 lac_send_ICRQ(t
, new_sess
);
181 // Set session to forward to another LNS
182 session
[s
].forwardtosession
= new_sess
;
183 session
[new_sess
].forwardtosession
= s
;
185 STAT(session_created
);
189 lac_tunnelshutdown(t
, "Shutting down", 6, 0, 0);
190 pconfigrlns
[i
].tid
= 0;
196 LOG(1, 0, t
, "(REMOTE LNS) tunnel is not open\n");
206 static tunnelidt
getidrlns(tunnelidt t
)
210 for (idrlns
= 1; idrlns
<= config
->highest_rlnsid
; ++idrlns
)
212 if (pconfigrlns
[idrlns
].tid
== t
) return idrlns
;
218 int istunneltolns(tunnelidt t
)
222 for (idrlns
= 1; idrlns
<= config
->highest_rlnsid
; ++idrlns
)
224 if (pconfigrlns
[idrlns
].tid
== t
) return 1;
230 void calc_lac_auth(tunnelidt t
, uint8_t id
, uint8_t *out
)
235 idrlns
= getidrlns(t
);
238 MD5_Update(&ctx
, &id
, 1);
239 MD5_Update(&ctx
, pconfigrlns
[idrlns
].l2tp_secret
, strlen(pconfigrlns
[idrlns
].l2tp_secret
));
240 MD5_Update(&ctx
, pconfigrlns
[idrlns
].auth
, 16);
241 MD5_Final(out
, &ctx
);
244 // Forward session to external LNS
245 int session_forward_tolns(uint8_t *buf
, int len
, sessionidt sess
, uint16_t proto
)
247 uint16_t t
= 0, s
= 0;
248 uint8_t *p
= buf
+ 2; // First word L2TP options
250 s
= session
[sess
].forwardtosession
;
251 if (session
[s
].forwardtosession
!= sess
)
253 LOG(0, sess
, session
[sess
].tunnel
, "Link Session (%u) broken\n", s
);
257 t
= session
[s
].tunnel
;
260 LOG(1, s
, t
, "Session with invalid tunnel ID\n");
269 *(uint16_t *) p
= htons(tunnel
[t
].far
); // tunnel
271 *(uint16_t *) p
= htons(session
[s
].far
); // session
276 *(uint16_t *) p
= htons(tunnel
[t
].ns
); // sequence
278 *(uint16_t *) p
= htons(tunnel
[t
].nr
); // sequence
282 if ((proto
== PPPIP
) || (proto
== PPPMP
) ||(proto
== PPPIPV6
&& config
->ipv6_prefix
.s6_addr
[0]))
284 session
[sess
].last_packet
= session
[sess
].last_data
= time_now
;
287 session
[sess
].last_packet
= time_now
;
289 tunnelsend(buf
, len
, t
); // send it...
294 int addremotelns(char *mask
, char *IP_RemoteLNS
, char *Port_RemoteLNS
, char *SecretRemoteLNS
)
298 for (idrlns
= 1; idrlns
< MAXRLNSTUNNEL
; ++idrlns
)
300 if (pconfigrlns
[idrlns
].state
== CONFRLNSFREE
)
302 snprintf((char *) pconfigrlns
[idrlns
].strmaskuser
, sizeof(pconfigrlns
[idrlns
].strmaskuser
), "%s", mask
);
303 pconfigrlns
[idrlns
].ip
= ntohl(inet_addr(IP_RemoteLNS
));
304 pconfigrlns
[idrlns
].port
= atoi(Port_RemoteLNS
);
305 snprintf((char *) pconfigrlns
[idrlns
].l2tp_secret
, sizeof(pconfigrlns
[idrlns
].l2tp_secret
), "%s", SecretRemoteLNS
);
307 config
->highest_rlnsid
= idrlns
;
309 pconfigrlns
[idrlns
].state
= CONFRLNSSET
;
311 LOG(1, 0, 0, "New Remote LNS conf (count %u) mask:%s IP:%s Port:%u l2tpsecret:*****\n", idrlns
,
312 pconfigrlns
[idrlns
].strmaskuser
, fmtaddr(htonl(pconfigrlns
[idrlns
].ip
), 0),
313 pconfigrlns
[idrlns
].port
);
319 LOG(0, 0, 0, "No more Remote LNS Conf Free\n");