ppp: Move LCP received configuration parsing to a separate function
So it can be reused for proxy LCP negotiation.
This commit is contained in:
parent
9425c725c9
commit
817ce35748
1 changed files with 164 additions and 156 deletions
320
ppp.c
320
ppp.c
|
|
@ -556,6 +556,169 @@ static void ppp_code_rej(sessionidt s, tunnelidt t, uint16_t proto,
|
|||
tunnelsend(buf, l + (q - buf), t);
|
||||
}
|
||||
|
||||
// Process received LCP options from o from packet p.
|
||||
// Set changed to 1 if we changed configuration that should be sent to cluster slaves, fill response on nak or rej
|
||||
static void processreceivedlcpconfreq(sessionidt s, tunnelidt t, uint8_t *p, uint8_t *o, uint16_t x, int *changed, uint8_t **response)
|
||||
{
|
||||
static uint8_t asyncmap[4] = { 0, 0, 0, 0 }; // all zero
|
||||
static uint8_t authproto[5];
|
||||
uint8_t b[MAXETHER];
|
||||
uint8_t *q = NULL;
|
||||
|
||||
while (x > 2)
|
||||
{
|
||||
int type = o[0];
|
||||
int length = o[1];
|
||||
|
||||
if (length == 0 || length == 1 || type == 0 || x < length) break;
|
||||
switch (type)
|
||||
{
|
||||
case 1: // Maximum-Receive-Unit
|
||||
{
|
||||
uint16_t mru = ntohs(*(uint16_t *)(o + 2));
|
||||
if (mru >= MINMTU)
|
||||
{
|
||||
session[s].mru = mru;
|
||||
(*changed)++;
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(3, s, t, " Remote requesting MRU of %u. Rejecting.\n", mru);
|
||||
mru = htons(MRU);
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, response, q, p, o, (uint8_t *) &mru, sizeof(mru));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Async-Control-Character-Map
|
||||
if (!ntohl(*(uint32_t *)(o + 2))) // all bits zero is OK
|
||||
break;
|
||||
|
||||
LOG(3, s, t, " Remote requesting asyncmap. Rejecting.\n");
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, response, q, p, o, asyncmap, sizeof(asyncmap));
|
||||
break;
|
||||
|
||||
case 3: // Authentication-Protocol
|
||||
{
|
||||
int proto = ntohs(*(uint16_t *)(o + 2));
|
||||
char proto_name[] = "0x0000";
|
||||
int alen;
|
||||
|
||||
if (proto == PPPPAP)
|
||||
{
|
||||
if (config->radius_authtypes & AUTHPAP)
|
||||
{
|
||||
sess_local[s].lcp_authtype = AUTHPAP;
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(proto_name, "PAP");
|
||||
}
|
||||
else if (proto == PPPCHAP)
|
||||
{
|
||||
if (config->radius_authtypes & AUTHCHAP
|
||||
&& *(o + 4) == 5) // MD5
|
||||
{
|
||||
sess_local[s].lcp_authtype = AUTHCHAP;
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(proto_name, "CHAP");
|
||||
}
|
||||
else
|
||||
sprintf(proto_name, "%#4.4x", proto);
|
||||
|
||||
LOG(3, s, t, " Remote requesting %s authentication. Rejecting.\n", proto_name);
|
||||
|
||||
alen = add_lcp_auth(authproto, sizeof(authproto), config->radius_authprefer);
|
||||
if (alen < 2) break; // paranoia
|
||||
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, response, q, p, o, authproto + 2, alen - 2);
|
||||
if (q && **response == ConfigNak &&
|
||||
config->radius_authtypes != config->radius_authprefer)
|
||||
{
|
||||
// alternate type
|
||||
alen = add_lcp_auth(authproto, sizeof(authproto), config->radius_authtypes & ~config->radius_authprefer);
|
||||
if (alen < 2) break;
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, response, q, p, o, authproto + 2, alen - 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // Quality-Protocol
|
||||
case 5: // Magic-Number
|
||||
case 7: // Protocol-Field-Compression
|
||||
case 8: // Address-And-Control-Field-Compression
|
||||
break;
|
||||
|
||||
case 17: // Multilink Max-Receive-Reconstructed-Unit
|
||||
{
|
||||
uint16_t mrru = ntohs(*(uint16_t *)(o + 2));
|
||||
session[s].mrru = mrru;
|
||||
(*changed)++;
|
||||
LOG(3, s, t, " Received PPP LCP option MRRU: %d\n",mrru);
|
||||
}
|
||||
break;
|
||||
|
||||
case 18: // Multilink Short Sequence Number Header Format
|
||||
{
|
||||
session[s].mssf = 1;
|
||||
(*changed)++;
|
||||
LOG(3, s, t, " Received PPP LCP option MSSN format\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 19: // Multilink Endpoint Discriminator
|
||||
{
|
||||
uint8_t epdis_class = o[2];
|
||||
int addr;
|
||||
|
||||
session[s].epdis.addr_class = epdis_class;
|
||||
session[s].epdis.length = length - 3;
|
||||
if (session[s].epdis.length > 20)
|
||||
{
|
||||
LOG(1, s, t, "Error: received EndDis Address Length more than 20: %d\n", session[s].epdis.length);
|
||||
session[s].epdis.length = 20;
|
||||
}
|
||||
|
||||
for (addr = 0; addr < session[s].epdis.length; addr++)
|
||||
session[s].epdis.address[addr] = o[3+addr];
|
||||
|
||||
(*changed)++;
|
||||
|
||||
switch (epdis_class)
|
||||
{
|
||||
case LOCALADDR:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis Local Address Class: %d\n",epdis_class);
|
||||
break;
|
||||
case IPADDR:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis IP Address Class: %d\n",epdis_class);
|
||||
break;
|
||||
case IEEEMACADDR:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis IEEE MAC Address Class: %d\n",epdis_class);
|
||||
break;
|
||||
case PPPMAGIC:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis PPP Magic No Class: %d\n",epdis_class);
|
||||
break;
|
||||
case PSNDN:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis PSND No Class: %d\n",epdis_class);
|
||||
break;
|
||||
default:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis NULL Class %d\n",epdis_class);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: // Reject any unknown options
|
||||
LOG(3, s, t, " Rejecting unknown PPP LCP option %d\n", type);
|
||||
q = ppp_conf_rej(s, b, sizeof(b), PPPLCP, response, q, p, o);
|
||||
}
|
||||
x -= length;
|
||||
o += length;
|
||||
}
|
||||
}
|
||||
|
||||
// Process LCP messages
|
||||
void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||
{
|
||||
|
|
@ -648,165 +811,10 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
|||
}
|
||||
else if (*p == ConfigReq)
|
||||
{
|
||||
int x = l - 4;
|
||||
uint8_t *o = (p + 4);
|
||||
uint8_t *response = 0;
|
||||
static uint8_t asyncmap[4] = { 0, 0, 0, 0 }; // all zero
|
||||
static uint8_t authproto[5];
|
||||
int changed = 0;
|
||||
|
||||
while (x > 2)
|
||||
{
|
||||
int type = o[0];
|
||||
int length = o[1];
|
||||
|
||||
if (length == 0 || length == 1 || type == 0 || x < length) break;
|
||||
switch (type)
|
||||
{
|
||||
case 1: // Maximum-Receive-Unit
|
||||
{
|
||||
uint16_t mru = ntohs(*(uint16_t *)(o + 2));
|
||||
if (mru >= MINMTU)
|
||||
{
|
||||
session[s].mru = mru;
|
||||
changed++;
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(3, s, t, " Remote requesting MRU of %u. Rejecting.\n", mru);
|
||||
mru = htons(MRU);
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, &response, q, p, o, (uint8_t *) &mru, sizeof(mru));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Async-Control-Character-Map
|
||||
if (!ntohl(*(uint32_t *)(o + 2))) // all bits zero is OK
|
||||
break;
|
||||
|
||||
LOG(3, s, t, " Remote requesting asyncmap. Rejecting.\n");
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, &response, q, p, o, asyncmap, sizeof(asyncmap));
|
||||
break;
|
||||
|
||||
case 3: // Authentication-Protocol
|
||||
{
|
||||
int proto = ntohs(*(uint16_t *)(o + 2));
|
||||
char proto_name[] = "0x0000";
|
||||
int alen;
|
||||
|
||||
if (proto == PPPPAP)
|
||||
{
|
||||
if (config->radius_authtypes & AUTHPAP)
|
||||
{
|
||||
sess_local[s].lcp_authtype = AUTHPAP;
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(proto_name, "PAP");
|
||||
}
|
||||
else if (proto == PPPCHAP)
|
||||
{
|
||||
if (config->radius_authtypes & AUTHCHAP
|
||||
&& *(o + 4) == 5) // MD5
|
||||
{
|
||||
sess_local[s].lcp_authtype = AUTHCHAP;
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(proto_name, "CHAP");
|
||||
}
|
||||
else
|
||||
sprintf(proto_name, "%#4.4x", proto);
|
||||
|
||||
LOG(3, s, t, " Remote requesting %s authentication. Rejecting.\n", proto_name);
|
||||
|
||||
alen = add_lcp_auth(authproto, sizeof(authproto), config->radius_authprefer);
|
||||
if (alen < 2) break; // paranoia
|
||||
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, &response, q, p, o, authproto + 2, alen - 2);
|
||||
if (q && *response == ConfigNak &&
|
||||
config->radius_authtypes != config->radius_authprefer)
|
||||
{
|
||||
// alternate type
|
||||
alen = add_lcp_auth(authproto, sizeof(authproto), config->radius_authtypes & ~config->radius_authprefer);
|
||||
if (alen < 2) break;
|
||||
q = ppp_conf_nak(s, b, sizeof(b), PPPLCP, &response, q, p, o, authproto + 2, alen - 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // Quality-Protocol
|
||||
case 5: // Magic-Number
|
||||
case 7: // Protocol-Field-Compression
|
||||
case 8: // Address-And-Control-Field-Compression
|
||||
break;
|
||||
|
||||
case 17: // Multilink Max-Receive-Reconstructed-Unit
|
||||
{
|
||||
uint16_t mrru = ntohs(*(uint16_t *)(o + 2));
|
||||
session[s].mrru = mrru;
|
||||
changed++;
|
||||
LOG(3, s, t, " Received PPP LCP option MRRU: %d\n",mrru);
|
||||
}
|
||||
break;
|
||||
|
||||
case 18: // Multilink Short Sequence Number Header Format
|
||||
{
|
||||
session[s].mssf = 1;
|
||||
changed++;
|
||||
LOG(3, s, t, " Received PPP LCP option MSSN format\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 19: // Multilink Endpoint Discriminator
|
||||
{
|
||||
uint8_t epdis_class = o[2];
|
||||
int addr;
|
||||
|
||||
session[s].epdis.addr_class = epdis_class;
|
||||
session[s].epdis.length = length - 3;
|
||||
if (session[s].epdis.length > 20)
|
||||
{
|
||||
LOG(1, s, t, "Error: received EndDis Address Length more than 20: %d\n", session[s].epdis.length);
|
||||
session[s].epdis.length = 20;
|
||||
}
|
||||
|
||||
for (addr = 0; addr < session[s].epdis.length; addr++)
|
||||
session[s].epdis.address[addr] = o[3+addr];
|
||||
|
||||
changed++;
|
||||
|
||||
switch (epdis_class)
|
||||
{
|
||||
case LOCALADDR:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis Local Address Class: %d\n",epdis_class);
|
||||
break;
|
||||
case IPADDR:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis IP Address Class: %d\n",epdis_class);
|
||||
break;
|
||||
case IEEEMACADDR:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis IEEE MAC Address Class: %d\n",epdis_class);
|
||||
break;
|
||||
case PPPMAGIC:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis PPP Magic No Class: %d\n",epdis_class);
|
||||
break;
|
||||
case PSNDN:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis PSND No Class: %d\n",epdis_class);
|
||||
break;
|
||||
default:
|
||||
LOG(3, s, t, " Received PPP LCP option Multilink EndDis NULL Class %d\n",epdis_class);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: // Reject any unknown options
|
||||
LOG(3, s, t, " Rejecting unknown PPP LCP option %d\n", type);
|
||||
q = ppp_conf_rej(s, b, sizeof(b), PPPLCP, &response, q, p, o);
|
||||
}
|
||||
x -= length;
|
||||
o += length;
|
||||
}
|
||||
processreceivedlcpconfreq(s, t, p, p + 4, l - 4, &changed, &response);
|
||||
|
||||
if (changed)
|
||||
cluster_send_session(s);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue