* provided chunk, as most cause codes will be embedded inside an
* abort chunk.
*/
-void sctp_init_cause(struct sctp_chunk *chunk, __u16 cause_code,
+void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
const void *payload, size_t paylen)
{
sctp_errhdr_t err;
/* Create an Operation Error chunk. */
struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
- __u16 cause_code, const void *payload,
+ __be16 cause_code, const void *payload,
size_t paylen)
{
struct sctp_chunk *retval;
union sctp_addr *dest)
{
memcpy(&chunk->source, src, sizeof(union sctp_addr));
- memcpy(&chunk->dest, dest, sizeof(union sctp_addr));
+ flip_to_h(&chunk->source_h, &chunk->source);
+ flip_to_h(&chunk->dest, dest);
}
/* Extract the source address from a chunk. */
{
/* If we have a known transport, use that. */
if (chunk->transport) {
- return &chunk->transport->ipaddr;
+ return &chunk->transport->ipaddr_h;
} else {
/* Otherwise, extract it from the IP header. */
- return &chunk->source;
+ return &chunk->source_h;
}
}
if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
ssn = 0;
} else {
- sid = htons(chunk->subh.data_hdr->stream);
+ sid = ntohs(chunk->subh.data_hdr->stream);
if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid);
else
retval = kmalloc(*cookie_len, GFP_ATOMIC);
- if (!retval) {
- *cookie_len = 0;
+ if (!retval)
goto nodata;
- }
/* Clear this memory since we are sending this data structure
* out on the network.
ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len);
if (sctp_sk(ep->base.sk)->hmac) {
+ struct hash_desc desc;
+
/* Sign the message. */
sg.page = virt_to_page(&cookie->c);
sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
sg.length = bodysize;
keylen = SCTP_SECRET_SIZE;
key = (char *)ep->secret_key[ep->current_key];
+ desc.tfm = sctp_sk(ep->base.sk)->hmac;
+ desc.flags = 0;
- sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen,
- &sg, 1, cookie->signature);
+ if (crypto_hash_setkey(desc.tfm, key, keylen) ||
+ crypto_hash_digest(&desc, &sg, bodysize, cookie->signature))
+ goto free_cookie;
}
-nodata:
return retval;
+
+free_cookie:
+ kfree(retval);
+nodata:
+ *cookie_len = 0;
+ return NULL;
}
/* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */
sctp_scope_t scope;
struct sk_buff *skb = chunk->skb;
struct timeval tv;
+ struct hash_desc desc;
/* Header size is static data prior to the actual cookie, including
* any padding.
sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
sg.length = bodysize;
key = (char *)ep->secret_key[ep->current_key];
+ desc.tfm = sctp_sk(ep->base.sk)->hmac;
+ desc.flags = 0;
memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
- sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen, &sg,
- 1, digest);
+ if (crypto_hash_setkey(desc.tfm, key, keylen) ||
+ crypto_hash_digest(&desc, &sg, bodysize, digest)) {
+ *error = -SCTP_IERROR_NOMEM;
+ goto fail;
+ }
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
/* Try the previous key. */
key = (char *)ep->secret_key[ep->last_key];
memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
- sctp_crypto_hmac(sctp_sk(ep->base.sk)->hmac, key, &keylen,
- &sg, 1, digest);
+ if (crypto_hash_setkey(desc.tfm, key, keylen) ||
+ crypto_hash_digest(&desc, &sg, bodysize, digest)) {
+ *error = -SCTP_IERROR_NOMEM;
+ goto fail;
+ }
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
/* Yikes! Still bad signature! */
goto fail;
}
- if (ntohs(chunk->sctp_hdr->source) != bear_cookie->peer_addr.v4.sin_port ||
+ if (chunk->sctp_hdr->source != bear_cookie->peer_addr.v4.sin_port ||
ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
*error = -SCTP_IERROR_BAD_PORTS;
goto fail;
/* Check to see if the cookie is stale. If there is already
* an association, there is no need to check cookie's expiration
* for init collision case of lost COOKIE ACK.
+ * If skb has been timestamped, then use the stamp, otherwise
+ * use current time. This introduces a small possibility that
+ * that a cookie may be considered expired, but his would only slow
+ * down the new association establishment instead of every packet.
*/
- skb_get_timestamp(skb, &tv);
+ if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
+ skb_get_timestamp(skb, &tv);
+ else
+ do_gettimeofday(&tv);
+
if (!asoc && tv_lt(bear_cookie->expiration, tv)) {
__u16 len;
/*
/* Also, add the destination address. */
if (list_empty(&retval->base.bind_addr.address_list)) {
- sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1,
+ union sctp_addr tmp;
+ flip_to_n(&tmp, &chunk->dest);
+ sctp_add_bind_addr(&retval->base.bind_addr, &tmp, 1,
GFP_ATOMIC);
}
struct sctp_transport *transport;
struct list_head *pos, *temp;
char *cookie;
+ union sctp_addr tmp;
/* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet.
* added as the primary transport. The source address seems to
* be a a better choice than any of the embedded addresses.
*/
- if (peer_addr)
- if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
+ if (peer_addr) {
+ flip_to_n(&tmp, peer_addr);
+ if(!sctp_assoc_add_peer(asoc, &tmp, gfp, SCTP_ACTIVE))
goto nomem;
+ }
/* Process the initialization parameters. */
sctp_scope_t scope;
time_t stale;
struct sctp_af *af;
+ union sctp_addr tmp;
/* We maintain all INIT parameters in network byte order all the
* time. This allows us to not worry about whether the parameters
case SCTP_PARAM_IPV4_ADDRESS:
af = sctp_get_af_specific(param_type2af(param.p->type));
af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
+ flip_to_n(&tmp, &addr);
scope = sctp_scope(peer_addr);
- if (sctp_in_scope(&addr, scope))
- if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
+ if (sctp_in_scope(&tmp, scope))
+ if (!sctp_assoc_add_peer(asoc, &tmp, gfp, SCTP_UNCONFIRMED))
return 0;
break;
union sctp_addr *laddr,
struct sockaddr *addrs,
int addrcnt,
- __u16 flags)
+ __be16 flags)
{
sctp_addip_param_t param;
struct sctp_chunk *retval;
/* Add response parameters to an ASCONF_ACK chunk. */
static void sctp_add_asconf_response(struct sctp_chunk *chunk, __u32 crr_id,
- __u16 err_code, sctp_addip_param_t *asconf_param)
+ __be16 err_code, sctp_addip_param_t *asconf_param)
{
sctp_addip_param_t ack_param;
sctp_errhdr_t err_param;
int asconf_param_len = 0;
int err_param_len = 0;
- __u16 response_type;
+ __be16 response_type;
if (SCTP_ERROR_NO_ERROR == err_code) {
response_type = SCTP_PARAM_SUCCESS_REPORT;
}
/* Process a asconf parameter. */
-static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
+static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
struct sctp_chunk *asconf,
sctp_addip_param_t *asconf_param)
{
union sctp_addr addr;
struct list_head *pos;
union sctp_addr_param *addr_param;
-
+ union sctp_addr tmp, tmp_addr;
+
addr_param = (union sctp_addr_param *)
((void *)asconf_param + sizeof(sctp_addip_param_t));
return SCTP_ERROR_INV_PARAM;
af->from_addr_param(&addr, addr_param, asoc->peer.port, 0);
+ flip_to_n(&tmp_addr, &addr);
switch (asconf_param->param_hdr.type) {
case SCTP_PARAM_ADD_IP:
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
* Due to Resource Shortage'.
*/
- peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_UNCONFIRMED);
+ peer = sctp_assoc_add_peer(asoc, &tmp_addr, GFP_ATOMIC, SCTP_UNCONFIRMED);
if (!peer)
return SCTP_ERROR_RSRC_LOW;
* an Error Cause TLV set to the new error code 'Request to
* Delete Source IP Address'
*/
- if (sctp_cmp_addr_exact(sctp_source(asconf), &addr))
+ flip_to_n(&tmp, sctp_source(asconf));
+ if (sctp_cmp_addr_exact(&tmp, &tmp_addr))
return SCTP_ERROR_DEL_SRC_IP;
- sctp_assoc_del_peer(asoc, &addr);
+ sctp_assoc_del_peer(asoc, &tmp_addr);
break;
case SCTP_PARAM_SET_PRIMARY:
- peer = sctp_assoc_lookup_paddr(asoc, &addr);
+ peer = sctp_assoc_lookup_paddr(asoc, &tmp_addr);
if (!peer)
return SCTP_ERROR_INV_PARAM;
sctp_addip_param_t *asconf_param;
struct sctp_chunk *asconf_ack;
- __u16 err_code;
+ __be16 err_code;
int length = 0;
int chunk_len = asconf->skb->len;
__u32 serial;
struct sctp_transport *transport;
struct sctp_sockaddr_entry *saddr;
int retval = 0;
+ union sctp_addr tmp;
addr_param = (union sctp_addr_param *)
((void *)asconf_param + sizeof(sctp_addip_param_t));
/* We have checked the packet before, so we do not check again. */
af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
af->from_addr_param(&addr, addr_param, bp->port, 0);
+ flip_to_n(&tmp, &addr);
switch (asconf_param->param_hdr.type) {
case SCTP_PARAM_ADD_IP:
sctp_write_lock(&asoc->base.addr_lock);
list_for_each(pos, &bp->address_list) {
saddr = list_entry(pos, struct sctp_sockaddr_entry, list);
- if (sctp_cmp_addr_exact(&saddr->a, &addr))
+ if (sctp_cmp_addr_exact(&saddr->a, &tmp))
saddr->use_as_src = 1;
}
sctp_write_unlock(&asoc->base.addr_lock);
case SCTP_PARAM_DEL_IP:
sctp_local_bh_disable();
sctp_write_lock(&asoc->base.addr_lock);
- retval = sctp_del_bind_addr(bp, &addr);
+ retval = sctp_del_bind_addr(bp, &tmp);
sctp_write_unlock(&asoc->base.addr_lock);
sctp_local_bh_enable();
list_for_each(pos, &asoc->peer.transport_addr_list) {
* All TLVs after the failed response are considered unsuccessful unless a
* specific success indication is present for the parameter.
*/
-static __u16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
+static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
sctp_addip_param_t *asconf_param,
int no_err)
{
sctp_errhdr_t *err_param;
int length;
int asconf_ack_len = asconf_ack->skb->len;
- __u16 err_code;
+ __be16 err_code;
if (no_err)
err_code = SCTP_ERROR_NO_ERROR;
int all_param_pass = 0;
int no_err = 1;
int retval = 0;
- __u16 err_code = SCTP_ERROR_NO_ERROR;
+ __be16 err_code = SCTP_ERROR_NO_ERROR;
/* Skip the chunkhdr and addiphdr from the last asconf sent and store
* a pointer to address parameter.