Commit 63e15a36 authored by Jon Grimm's avatar Jon Grimm

[SCTP] sctp_params cleanup (jgrimm)

naming, purge typdef
add macro for walking parameters, stronger validity checks
parent cca1b32f
...@@ -418,6 +418,18 @@ static inline size_t get_user_iov_size(struct iovec *iov, int iovlen) ...@@ -418,6 +418,18 @@ static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
return retval; return retval;
} }
/* Walk through a list of TLV parameters. Don't trust the
* individual parameter lengths and instead depend on
* the chunk length to indicate when to stop. Make sure
* there is room for a param header too.
*/
#define sctp_walk_params(pos, chunk, member)\
_sctp_walk_params(((union sctp_params)(pos)), (chunk), member)
#define _sctp_walk_params(pos, chunk, member)\
for (pos.v = (void *)&chunk->member;\
pos.v <= (void *)chunk + ntohs(chunk->chunk_hdr.length) - sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
/* Round an int up to the next multiple of 4. */ /* Round an int up to the next multiple of 4. */
#define WORD_ROUND(s) (((s)+3)&~3) #define WORD_ROUND(s) (((s)+3)&~3)
......
...@@ -206,9 +206,6 @@ sctp_association_t *sctp_make_temp_asoc(const sctp_endpoint_t *, ...@@ -206,9 +206,6 @@ sctp_association_t *sctp_make_temp_asoc(const sctp_endpoint_t *,
sctp_chunk_t *, sctp_chunk_t *,
const int priority); const int priority);
__u32 sctp_generate_verification_tag(void); __u32 sctp_generate_verification_tag(void);
sctpParam_t sctp_get_my_addrs_raw(const sctp_association_t *,
const int priority, int *addrs_len);
void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag); void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
/* Prototypes for chunk-building functions. */ /* Prototypes for chunk-building functions. */
...@@ -336,7 +333,7 @@ __u32 sctp_generate_tsn(const sctp_endpoint_t *); ...@@ -336,7 +333,7 @@ __u32 sctp_generate_tsn(const sctp_endpoint_t *);
/* 4th level prototypes */ /* 4th level prototypes */
void sctp_param2sockaddr(sockaddr_storage_t *addr, sctp_addr_param_t *, void sctp_param2sockaddr(sockaddr_storage_t *addr, sctp_addr_param_t *,
__u16 port); __u16 port);
int sctp_addr2sockaddr(const sctpParam_t, sockaddr_storage_t *); int sctp_addr2sockaddr(const union sctp_params, sockaddr_storage_t *);
int sockaddr2sctp_addr(const sockaddr_storage_t *, sctp_addr_param_t *); int sockaddr2sctp_addr(const sockaddr_storage_t *, sctp_addr_param_t *);
/* Extern declarations for major data structures. */ /* Extern declarations for major data structures. */
......
...@@ -356,20 +356,6 @@ typedef struct sctp_signed_cookie { ...@@ -356,20 +356,6 @@ typedef struct sctp_signed_cookie {
} sctp_signed_cookie_t; } sctp_signed_cookie_t;
/* This convenience type allows us to avoid casting when walking
* through a parameter list.
*/
typedef union {
__u8 *v;
sctp_paramhdr_t *p;
sctp_cookie_preserve_param_t *bht;
sctp_hostname_param_t *dns;
sctp_cookie_param_t *cookie;
sctp_supported_addrs_param_t *sat;
sctp_ipv4addr_param_t *v4;
sctp_ipv6addr_param_t *v6;
} sctpParam_t;
/* This is another convenience type to allocate memory for address /* This is another convenience type to allocate memory for address
* params for the maximum size and pass such structures around * params for the maximum size and pass such structures around
...@@ -380,6 +366,21 @@ typedef union { ...@@ -380,6 +366,21 @@ typedef union {
sctp_ipv6addr_param_t v6; sctp_ipv6addr_param_t v6;
} sctp_addr_param_t; } sctp_addr_param_t;
/* A convenience type to allow walking through the various
* parameters and avoid casting all over the place.
*/
union sctp_params {
void *v;
sctp_paramhdr_t *p;
sctp_cookie_preserve_param_t *life;
sctp_hostname_param_t *dns;
sctp_cookie_param_t *cookie;
sctp_supported_addrs_param_t *sat;
sctp_ipv4addr_param_t *v4;
sctp_ipv6addr_param_t *v6;
sctp_addr_param_t *addr;
};
/* RFC 2960. Section 3.3.5 Heartbeat. /* RFC 2960. Section 3.3.5 Heartbeat.
* Heartbeat Information: variable length * Heartbeat Information: variable length
* The Sender-specific Heartbeat Info field should normally include * The Sender-specific Heartbeat Info field should normally include
...@@ -430,7 +431,7 @@ struct SCTP_chunk { ...@@ -430,7 +431,7 @@ struct SCTP_chunk {
*/ */
/* We point this at the FIRST TLV parameter to chunk_hdr. */ /* We point this at the FIRST TLV parameter to chunk_hdr. */
sctpParam_t param_hdr; union sctp_params param_hdr;
union { union {
__u8 *v; __u8 *v;
sctp_datahdr_t *data_hdr; sctp_datahdr_t *data_hdr;
...@@ -885,7 +886,7 @@ int sctp_add_bind_addr(sctp_bind_addr_t *, sockaddr_storage_t *, ...@@ -885,7 +886,7 @@ int sctp_add_bind_addr(sctp_bind_addr_t *, sockaddr_storage_t *,
int priority); int priority);
int sctp_del_bind_addr(sctp_bind_addr_t *, sockaddr_storage_t *); int sctp_del_bind_addr(sctp_bind_addr_t *, sockaddr_storage_t *);
int sctp_bind_addr_has_addr(sctp_bind_addr_t *, const sockaddr_storage_t *); int sctp_bind_addr_has_addr(sctp_bind_addr_t *, const sockaddr_storage_t *);
sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, union sctp_params sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
int *addrs_len, int *addrs_len,
int priority); int priority);
int sctp_raw_to_bind_addrs(sctp_bind_addr_t *bp, int sctp_raw_to_bind_addrs(sctp_bind_addr_t *bp,
...@@ -1053,19 +1054,19 @@ int sctp_verify_init(const sctp_association_t *asoc, ...@@ -1053,19 +1054,19 @@ int sctp_verify_init(const sctp_association_t *asoc,
sctp_chunk_t *chunk, sctp_chunk_t *chunk,
sctp_chunk_t **err_chunk); sctp_chunk_t **err_chunk);
int sctp_verify_param(const sctp_association_t *asoc, int sctp_verify_param(const sctp_association_t *asoc,
sctpParam_t param, union sctp_params param,
sctp_cid_t cid, sctp_cid_t cid,
sctp_chunk_t *chunk, sctp_chunk_t *chunk,
sctp_chunk_t **err_chunk); sctp_chunk_t **err_chunk);
int sctp_process_unk_param(const sctp_association_t *asoc, int sctp_process_unk_param(const sctp_association_t *asoc,
sctpParam_t param, union sctp_params param,
sctp_chunk_t *chunk, sctp_chunk_t *chunk,
sctp_chunk_t **err_chunk); sctp_chunk_t **err_chunk);
void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
const sockaddr_storage_t *peer_addr, const sockaddr_storage_t *peer_addr,
sctp_init_chunk_t *peer_init, int priority); sctp_init_chunk_t *peer_init, int priority);
int sctp_process_param(sctp_association_t *asoc, int sctp_process_param(sctp_association_t *asoc,
sctpParam_t param, union sctp_params param,
const sockaddr_storage_t *peer_addr, const sockaddr_storage_t *peer_addr,
sctp_cid_t cid, int priority); sctp_cid_t cid, int priority);
__u32 sctp_generate_tag(const sctp_endpoint_t *ep); __u32 sctp_generate_tag(const sctp_endpoint_t *ep);
......
...@@ -196,18 +196,16 @@ int sctp_del_bind_addr(sctp_bind_addr_t *bp, sockaddr_storage_t *del_addr) ...@@ -196,18 +196,16 @@ int sctp_del_bind_addr(sctp_bind_addr_t *bp, sockaddr_storage_t *del_addr)
* *
* The second argument is the return value for the length. * The second argument is the return value for the length.
*/ */
sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len, union sctp_params sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
int priority) int *addrs_len, int priority)
{ {
sctpParam_t addrparms; union sctp_params addrparms;
sctpParam_t retval; union sctp_params retval;
int addrparms_len; int addrparms_len;
sctp_addr_param_t rawaddr; sctp_addr_param_t rawaddr;
int len; int len;
struct sockaddr_storage_list *addr; struct sockaddr_storage_list *addr;
struct list_head *pos; struct list_head *pos;
retval.v = NULL;
addrparms_len = 0; addrparms_len = 0;
len = 0; len = 0;
...@@ -216,11 +214,11 @@ sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len, ...@@ -216,11 +214,11 @@ sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len,
len += sizeof(sctp_addr_param_t); len += sizeof(sctp_addr_param_t);
} }
addrparms.v = kmalloc(len, priority); retval.v = kmalloc(len, priority);
if (!addrparms.v) if (!retval.v)
goto end_raw; goto end_raw;
retval = addrparms; addrparms = retval;
list_for_each(pos, &bp->address_list) { list_for_each(pos, &bp->address_list) {
addr = list_entry(pos, struct sockaddr_storage_list, list); addr = list_entry(pos, struct sockaddr_storage_list, list);
......
/* SCTP kernel reference Implementation /* SCTP kernel reference Implementation
* Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001-2002 Intel Corp.
* Copyright (c) 2001 International Business Machines Corp. * Copyright (c) 2001-2002 International Business Machines Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
...@@ -166,7 +166,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc, ...@@ -166,7 +166,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
int priority) int priority)
{ {
sctp_inithdr_t init; sctp_inithdr_t init;
sctpParam_t addrs; union sctp_params addrs;
size_t chunksize; size_t chunksize;
sctp_chunk_t *retval = NULL; sctp_chunk_t *retval = NULL;
int addrs_len = 0; int addrs_len = 0;
...@@ -228,7 +228,7 @@ sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *asoc, ...@@ -228,7 +228,7 @@ sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *asoc,
{ {
sctp_inithdr_t initack; sctp_inithdr_t initack;
sctp_chunk_t *retval; sctp_chunk_t *retval;
sctpParam_t addrs; union sctp_params addrs;
int addrs_len; int addrs_len;
sctp_cookie_param_t *cookie; sctp_cookie_param_t *cookie;
int cookie_len; int cookie_len;
...@@ -1482,21 +1482,17 @@ int sctp_verify_init(const sctp_association_t *asoc, ...@@ -1482,21 +1482,17 @@ int sctp_verify_init(const sctp_association_t *asoc,
sctp_chunk_t *chunk, sctp_chunk_t *chunk,
sctp_chunk_t **err_chk_p) sctp_chunk_t **err_chk_p)
{ {
sctpParam_t param; union sctp_params param;
uint8_t *end;
/* FIXME - Verify the fixed fields of the INIT chunk. Also, verify /* FIXME - Verify the fixed fields of the INIT chunk. Also, verify
* the mandatory parameters somewhere here and generate either the * the mandatory parameters somewhere here and generate either the
* "Missing mandatory parameter" error or the "Invalid mandatory * "Missing mandatory parameter" error or the "Invalid mandatory
* parameter" error. */ * parameter" error.
*/
/* Find unrecognized parameters. */ /* Find unrecognized parameters. */
end = ((uint8_t *)peer_init + ntohs(peer_init->chunk_hdr.length)); sctp_walk_params(param, peer_init, init_hdr.params) {
for (param.v = peer_init->init_hdr.params;
param.v < end;
param.v += WORD_ROUND(ntohs(param.p->length))) {
if (!sctp_verify_param(asoc, param, cid, chunk, err_chk_p)) if (!sctp_verify_param(asoc, param, cid, chunk, err_chk_p))
return 0; return 0;
...@@ -1513,7 +1509,7 @@ int sctp_verify_init(const sctp_association_t *asoc, ...@@ -1513,7 +1509,7 @@ int sctp_verify_init(const sctp_association_t *asoc,
* 1 - continue with the chunk * 1 - continue with the chunk
*/ */
int sctp_verify_param(const sctp_association_t *asoc, int sctp_verify_param(const sctp_association_t *asoc,
sctpParam_t param, union sctp_params param,
sctp_cid_t cid, sctp_cid_t cid,
sctp_chunk_t *chunk, sctp_chunk_t *chunk,
sctp_chunk_t **err_chk_p) sctp_chunk_t **err_chk_p)
...@@ -1576,7 +1572,7 @@ int sctp_verify_param(const sctp_association_t *asoc, ...@@ -1576,7 +1572,7 @@ int sctp_verify_param(const sctp_association_t *asoc,
* 1 - continue with the chunk * 1 - continue with the chunk
*/ */
int sctp_process_unk_param(const sctp_association_t *asoc, int sctp_process_unk_param(const sctp_association_t *asoc,
sctpParam_t param, union sctp_params param,
sctp_chunk_t *chunk, sctp_chunk_t *chunk,
sctp_chunk_t **err_chk_p) sctp_chunk_t **err_chk_p)
{ {
...@@ -1640,8 +1636,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1640,8 +1636,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
sctp_init_chunk_t *peer_init, sctp_init_chunk_t *peer_init,
int priority) int priority)
{ {
sctpParam_t param; union sctp_params param;
__u8 *end;
sctp_transport_t *transport; sctp_transport_t *transport;
struct list_head *pos, *temp; struct list_head *pos, *temp;
char *cookie; char *cookie;
...@@ -1660,10 +1655,9 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1660,10 +1655,9 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
sctp_assoc_add_peer(asoc, peer_addr, priority); sctp_assoc_add_peer(asoc, peer_addr, priority);
/* Process the initialization parameters. */ /* Process the initialization parameters. */
end = ((__u8 *)peer_init + ntohs(peer_init->chunk_hdr.length));
for (param.v = peer_init->init_hdr.params; sctp_walk_params(param, peer_init, init_hdr.params) {
param.v < end;
param.v += WORD_ROUND(ntohs(param.p->length))) {
if (!sctp_process_param(asoc, param, peer_addr, cid, if (!sctp_process_param(asoc, param, peer_addr, cid,
priority)) priority))
goto clean_up; goto clean_up;
...@@ -1753,7 +1747,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid, ...@@ -1753,7 +1747,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
* work we do. In particular, we should not build transport * work we do. In particular, we should not build transport
* structures for the addresses. * structures for the addresses.
*/ */
int sctp_process_param(sctp_association_t *asoc, sctpParam_t param, int sctp_process_param(sctp_association_t *asoc, union sctp_params param,
const sockaddr_storage_t *peer_addr, const sockaddr_storage_t *peer_addr,
sctp_cid_t cid, int priority) sctp_cid_t cid, int priority)
{ {
...@@ -1792,7 +1786,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param, ...@@ -1792,7 +1786,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
case SCTP_PARAM_COOKIE_PRESERVATIVE: case SCTP_PARAM_COOKIE_PRESERVATIVE:
asoc->cookie_preserve = asoc->cookie_preserve =
ntohl(param.bht->lifespan_increment); ntohl(param.life->lifespan_increment);
break; break;
case SCTP_PARAM_HOST_NAME_ADDRESS: case SCTP_PARAM_HOST_NAME_ADDRESS:
...@@ -1919,11 +1913,8 @@ void sctp_param2sockaddr(sockaddr_storage_t *addr, sctp_addr_param_t *param, ...@@ -1919,11 +1913,8 @@ void sctp_param2sockaddr(sockaddr_storage_t *addr, sctp_addr_param_t *param,
/* Convert an IP address in an SCTP param into a sockaddr_in. */ /* Convert an IP address in an SCTP param into a sockaddr_in. */
/* Returns true if a valid conversion was possible. */ /* Returns true if a valid conversion was possible. */
int sctp_addr2sockaddr(sctpParam_t p, sockaddr_storage_t *sa) int sctp_addr2sockaddr(union sctp_params p, sockaddr_storage_t *sa)
{ {
if (!p.v)
return 0;
switch (p.p->type) { switch (p.p->type) {
case SCTP_PARAM_IPV4_ADDRESS: case SCTP_PARAM_IPV4_ADDRESS:
sa->v4.sin_addr = *((struct in_addr *)&p.v4->addr); sa->v4.sin_addr = *((struct in_addr *)&p.v4->addr);
......
...@@ -236,8 +236,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep, ...@@ -236,8 +236,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data; chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data;
/* Tag the variable length parameters. */ /* Tag the variable length parameters. */
chunk->param_hdr.v = chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC); new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
if (!new_asoc) if (!new_asoc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment