ppp: use common code to get options from pppcp packet data

This commit is contained in:
Kristen Carlson Accardi 2010-03-26 18:34:29 -07:00 committed by Marcel Holtmann
parent 5260379d98
commit 8777e778f3
1 changed files with 40 additions and 31 deletions

View File

@ -1140,6 +1140,22 @@ static void remove_config_option(gpointer elem, gpointer user_data)
data->config_options = g_list_delete_link(data->config_options, list); data->config_options = g_list_delete_link(data->config_options, list);
} }
static struct ppp_option *extract_ppp_option(guint8 *packet_data)
{
struct ppp_option *option;
guint8 otype = packet_data[0];
guint8 olen = packet_data[1];
option = g_try_malloc0(olen);
if (option == NULL)
return NULL;
option->type = otype;
option->length = olen;
memcpy(option->data, &packet_data[2], olen-2);
return option;
}
static guint8 pppcp_process_configure_request(struct pppcp_data *data, static guint8 pppcp_process_configure_request(struct pppcp_data *data,
struct pppcp_packet *packet) struct pppcp_packet *packet)
{ {
@ -1157,14 +1173,13 @@ static guint8 pppcp_process_configure_request(struct pppcp_data *data,
* check the options. * check the options.
*/ */
while (i < len) { while (i < len) {
guint8 otype = packet->data[i]; option = extract_ppp_option(&packet->data[i]);
guint8 olen = packet->data[i+1];
option = g_try_malloc0(olen);
if (option == NULL) if (option == NULL)
break; break;
option->type = otype;
option->length = olen; /* skip ahead to the next option */
memcpy(option->data, &packet->data[i+2], olen-2); i += option->length;
if (action->option_scan) if (action->option_scan)
rval = action->option_scan(option, data); rval = action->option_scan(option, data);
switch (rval) { switch (rval) {
@ -1182,10 +1197,9 @@ static guint8 pppcp_process_configure_request(struct pppcp_data *data,
option); option);
break; break;
case OPTION_ERR: case OPTION_ERR:
g_printerr("unhandled option type %d\n", otype); g_printerr("unhandled option type %d\n", option->type);
g_free(option);
} }
/* skip ahead to the next option */
i += olen;
} }
/* make sure all required config options were included */ /* make sure all required config options were included */
@ -1242,16 +1256,12 @@ static guint8 pppcp_process_configure_ack(struct pppcp_data *data,
* and apply them. * and apply them.
*/ */
while (i < len) { while (i < len) {
guint8 otype = packet->data[i]; acked_option = extract_ppp_option(&packet->data[i]);
guint8 olen = packet->data[i + 1];
acked_option = g_try_malloc0(olen);
if (acked_option == NULL) if (acked_option == NULL)
break; break;
acked_option->type = otype;
acked_option->length = olen;
memcpy(acked_option->data, &packet->data[i + 2], olen - 2);
list = g_list_find_custom(data->config_options, list = g_list_find_custom(data->config_options,
GUINT_TO_POINTER((guint) otype), is_option); GUINT_TO_POINTER((guint) acked_option->type),
is_option);
if (list) { if (list) {
/* /*
* once we've applied the option, delete it from * once we've applied the option, delete it from
@ -1266,10 +1276,11 @@ static guint8 pppcp_process_configure_ack(struct pppcp_data *data,
g_list_delete_link(data->config_options, list); g_list_delete_link(data->config_options, list);
} else } else
g_printerr("oops -- found acked option %d we didn't request\n", acked_option->type); g_printerr("oops -- found acked option %d we didn't request\n", acked_option->type);
g_free(acked_option);
/* skip ahead to the next option */ /* skip ahead to the next option */
i += olen; i += acked_option->length;
g_free(acked_option);
} }
return RCA; return RCA;
} }
@ -1300,14 +1311,13 @@ static guint8 pppcp_process_configure_nak(struct pppcp_data *data,
* modify a value there, or add a new option. * modify a value there, or add a new option.
*/ */
while (i < len) { while (i < len) {
guint8 otype = packet->data[i]; naked_option = extract_ppp_option(&packet->data[i]);
guint8 olen = packet->data[i+1];
naked_option = g_try_malloc0(olen);
if (naked_option == NULL) if (naked_option == NULL)
break; break;
naked_option->type = otype;
naked_option->length = olen; /* skip ahead to the next option */
memcpy(naked_option->data, &packet->data[i + 2], olen - 2); i += naked_option->length;
if (action->option_scan) if (action->option_scan)
rval = action->option_scan(naked_option, data); rval = action->option_scan(naked_option, data);
if (rval == OPTION_ACCEPT) { if (rval == OPTION_ACCEPT) {
@ -1316,7 +1326,8 @@ static guint8 pppcp_process_configure_nak(struct pppcp_data *data,
* match. * match.
*/ */
list = g_list_find_custom(data->config_options, list = g_list_find_custom(data->config_options,
GUINT_TO_POINTER((guint) otype), is_option); GUINT_TO_POINTER((guint) naked_option->type),
is_option);
if (list) { if (list) {
/* modify current option value to match */ /* modify current option value to match */
config_option = list->data; config_option = list->data;
@ -1326,10 +1337,11 @@ static guint8 pppcp_process_configure_nak(struct pppcp_data *data,
* we need to reallocate * we need to reallocate
*/ */
if ((config_option->length == if ((config_option->length ==
naked_option->length) && (olen - 2)) { naked_option->length) &&
(naked_option - 2)) {
memcpy(config_option->data, memcpy(config_option->data,
naked_option->data, naked_option->data,
olen - 2); naked_option->length - 2);
} else { } else {
/* XXX implement this */ /* XXX implement this */
g_printerr("uh oh, option value doesn't match\n"); g_printerr("uh oh, option value doesn't match\n");
@ -1344,9 +1356,6 @@ static guint8 pppcp_process_configure_nak(struct pppcp_data *data,
g_printerr("oops, option wasn't acceptable\n"); g_printerr("oops, option wasn't acceptable\n");
g_free(naked_option); g_free(naked_option);
} }
/* skip ahead to the next option */
i += olen;
} }
return RCN; return RCN;
} }