Exemple #1
0
void dccp_v4_send_check(struct sock *sk, struct sk_buff *skb)
{
	const struct inet_sock *inet = inet_sk(sk);
	struct dccp_hdr *dh = dccp_hdr(skb);

	dccp_csum_outgoing(skb);
	dh->dccph_checksum = dccp_v4_csum_finish(skb,
						 inet->inet_saddr,
						 inet->inet_daddr);
}
Exemple #2
0
struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
				   struct request_sock *req)
{
	struct dccp_hdr *dh;
	struct dccp_request_sock *dreq;
	const u32 dccp_header_size = sizeof(struct dccp_hdr) +
				     sizeof(struct dccp_hdr_ext) +
				     sizeof(struct dccp_hdr_response);
	struct sk_buff *skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1,
					   GFP_ATOMIC);
	if (skb == NULL)
		return NULL;

	/* Reserve space for headers. */
	skb_reserve(skb, sk->sk_prot->max_header);

	skb_dst_set(skb, dst_clone(dst));

	dreq = dccp_rsk(req);
	if (inet_rsk(req)->acked)	/* increase ISS upon retransmission */
		dccp_inc_seqno(&dreq->dreq_iss);
	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
	DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;

	/* Resolve feature dependencies resulting from choice of CCID */
	if (dccp_feat_server_ccid_dependencies(dreq))
		goto response_failed;

	if (dccp_insert_options_rsk(dreq, skb))
		goto response_failed;

	/* Build and checksum header */
	dh = dccp_zeroed_hdr(skb, dccp_header_size);

	dh->dccph_sport	= inet_rsk(req)->loc_port;
	dh->dccph_dport	= inet_rsk(req)->rmt_port;
	dh->dccph_doff	= (dccp_header_size +
			   DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
	dh->dccph_type	= DCCP_PKT_RESPONSE;
	dh->dccph_x	= 1;
	dccp_hdr_set_seq(dh, dreq->dreq_iss);
	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
	dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;

	dccp_csum_outgoing(skb);

	/* We use `acked' to remember that a Response was already sent. */
	inet_rsk(req)->acked = 1;
	DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
	return skb;
response_failed:
	kfree_skb(skb);
	return NULL;
}
Exemple #3
0
struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
				   struct request_sock *req)
{
	struct dccp_hdr *dh;
	struct dccp_request_sock *dreq;
	const u32 dccp_header_size = sizeof(struct dccp_hdr) +
				     sizeof(struct dccp_hdr_ext) +
				     sizeof(struct dccp_hdr_response);
	struct sk_buff *skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1,
					   GFP_ATOMIC);
	if (skb == NULL)
		return NULL;

	
	skb_reserve(skb, sk->sk_prot->max_header);

	skb_dst_set(skb, dst_clone(dst));

	dreq = dccp_rsk(req);
	if (inet_rsk(req)->acked)	
		dccp_inc_seqno(&dreq->dreq_iss);
	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
	DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;

	
	if (dccp_feat_server_ccid_dependencies(dreq))
		goto response_failed;

	if (dccp_insert_options_rsk(dreq, skb))
		goto response_failed;

	
	dh = dccp_zeroed_hdr(skb, dccp_header_size);

	dh->dccph_sport	= inet_rsk(req)->loc_port;
	dh->dccph_dport	= inet_rsk(req)->rmt_port;
	dh->dccph_doff	= (dccp_header_size +
			   DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
	dh->dccph_type	= DCCP_PKT_RESPONSE;
	dh->dccph_x	= 1;
	dccp_hdr_set_seq(dh, dreq->dreq_iss);
	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
	dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;

	dccp_csum_outgoing(skb);

	
	inet_rsk(req)->acked = 1;
	DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
	return skb;
response_failed:
	kfree_skb(skb);
	return NULL;
}
Exemple #4
0
/* answer offending packet in @rcv_skb with Reset from control socket @ctl */
struct sk_buff *dccp_ctl_make_reset(struct sock *sk, struct sk_buff *rcv_skb)
{
    struct dccp_hdr *rxdh = dccp_hdr(rcv_skb), *dh;
    struct dccp_skb_cb *dcb = DCCP_SKB_CB(rcv_skb);
    const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
                       sizeof(struct dccp_hdr_ext) +
                       sizeof(struct dccp_hdr_reset);
    struct dccp_hdr_reset *dhr;
    struct sk_buff *skb;

    skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC);
    if (skb == NULL)
        return NULL;

    skb_reserve(skb, sk->sk_prot->max_header);

    /* Swap the send and the receive. */
    dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
    dh->dccph_type    = DCCP_PKT_RESET;
    dh->dccph_sport    = rxdh->dccph_dport;
    dh->dccph_dport    = rxdh->dccph_sport;
    dh->dccph_doff    = dccp_hdr_reset_len / 4;
    dh->dccph_x    = 1;

    dhr = dccp_hdr_reset(skb);
    dhr->dccph_reset_code = dcb->dccpd_reset_code;

    switch (dcb->dccpd_reset_code) {
    case DCCP_RESET_CODE_PACKET_ERROR:
        dhr->dccph_reset_data[0] = rxdh->dccph_type;
        break;
    case DCCP_RESET_CODE_OPTION_ERROR:    /* fall through */
    case DCCP_RESET_CODE_MANDATORY_ERROR:
        memcpy(dhr->dccph_reset_data, dcb->dccpd_reset_data, 3);
        break;
    }
    /*
     * From RFC 4340, 8.3.1:
     *   If P.ackno exists, set R.seqno := P.ackno + 1.
     *   Else set R.seqno := 0.
     */
    if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
        dccp_hdr_set_seq(dh, ADD48(dcb->dccpd_ack_seq, 1));
    dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dcb->dccpd_seq);

    dccp_csum_outgoing(skb);
    return skb;
}