diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-01-29 04:31:00 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-01-29 04:36:38 +0100 |
commit | ef84539fb7dc68712bd0c530cfedb29c3374df5e (patch) | |
tree | d7ea0e1247a47755d5fc757ba5b94fe59394c2eb /openbsc | |
parent | 18c5cadc4680280dd6ce55a2922d2bd71a69734f (diff) |
[sccp] Split Connection DT1 into two parts
This is the last of supported messages to be split into a parse
and handle routine. Now all parse routines can be used by the NAT.
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/src/sccp/sccp.c | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c index ae08b5db2..e435ecf23 100644 --- a/openbsc/src/sccp/sccp.c +++ b/openbsc/src/sccp/sccp.c @@ -377,9 +377,44 @@ int _sccp_parse_connection_release_complete(struct msgb *msgb, struct sccp_parse return 0; } -int _sccp_parse_connection_dt1(struct msgb *msg, struct sccp_parse_result *result) +int _sccp_parse_connection_dt1(struct msgb *msgb, struct sccp_parse_result *result) { - return -1; + static int header_size = sizeof(struct sccp_data_form1); + static int variable_offset = offsetof(struct sccp_data_form1, variable_start); + + struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *)msgb->l2h; + + /* we don't have enough size for the struct */ + if (msgb_l2len(msgb) < header_size) { + DEBUGP(DSCCP, "msgb > header_size %u %u\n", + msgb_l2len(msgb), header_size); + return -1; + } + + if (dt1->segmenting != 0) { + DEBUGP(DSCCP, "This packet has segmenting, not supported: %d\n", dt1->segmenting); + return -1; + } + + result->destination_local_reference = &dt1->destination_local_reference; + + /* some more size checks in here */ + if (msgb_l2len(msgb) < variable_offset + dt1->variable_start + 1) { + DEBUGP(DSCCP, "Not enough space for variable start: %u %u\n", + msgb_l2len(msgb), dt1->variable_start); + return -1; + } + + result->data_len = msgb->l2h[variable_offset + dt1->variable_start]; + msgb->l3h = &msgb->l2h[dt1->variable_start + variable_offset + 1]; + + if (msgb_l3len(msgb) < result->data_len) { + DEBUGP(DSCCP, "Not enough room for the payload: %u %u\n", + msgb_l3len(msgb), result->data_len); + return -1; + } + + return 0; } int _sccp_parse_udt(struct msgb *msgb, struct sccp_parse_result *result) @@ -895,57 +930,30 @@ found: } /* Handle the Data Form 1 message */ -static int _sccp_handle_connection_dt1(struct msgb *data) +static int _sccp_handle_connection_dt1(struct msgb *msgb) { - static int variable_offset = offsetof(struct sccp_data_form1, variable_start); - static int header_size = sizeof(struct sccp_data_form1); - - struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *)data->l2h; + struct sccp_parse_result result; struct sccp_connection *conn; - int size; - /* we don't have enough size for the struct */ - if (msgb_l2len(data) < header_size) { - DEBUGP(DSCCP, "msgb > header_size %u %u\n", - msgb_l2len(data), header_size); + if (_sccp_parse_connection_dt1(msgb, &result) != 0) return -1; - } - - if (dt1->segmenting != 0) { - DEBUGP(DSCCP, "This packet has segmenting, not supported: %d\n", dt1->segmenting); - return -1; - } /* lookup if we have a connection with the given reference */ llist_for_each_entry(conn, &sccp_connections, list) { if (conn->data_cb && memcmp(&conn->source_local_reference, - &dt1->destination_local_reference, + result.destination_local_reference, sizeof(conn->source_local_reference)) == 0) { - - /* some more size checks in here */ - if (msgb_l2len(data) < variable_offset + dt1->variable_start + 1) { - DEBUGP(DSCCP, "Not enough space for variable start: %u %u\n", - msgb_l2len(data), dt1->variable_start); - return -1; - } - - size = data->l2h[variable_offset + dt1->variable_start]; - data->l3h = &data->l2h[dt1->variable_start + variable_offset + 1]; - - if (msgb_l3len(data) < size) { - DEBUGP(DSCCP, "Not enough room for the payload: %u %u\n", - msgb_l3len(data), size); - return -1; - } - - conn->data_cb(conn, data, size); - return 0; + goto found; } } DEBUGP(DSCCP, "No connection found for dt1 data\n"); return -1; + +found: + conn->data_cb(conn, msgb, result.data_len); + return 0; } /* confirm a connection release */ |