/* * This is where all NET/ROM frames pass, except for IP-over-NET/ROM which * cannot be fragmented in this manner.
*/ void nr_output(struct sock *sk, struct sk_buff *skb)
{ struct sk_buff *skbn; unsignedchar transport[NR_TRANSPORT_LEN]; int err, frontlen, len;
if (skb->len - NR_TRANSPORT_LEN > NR_MAX_PACKET_SIZE) { /* Save a copy of the Transport Header */
skb_copy_from_linear_data(skb, transport, NR_TRANSPORT_LEN);
skb_pull(skb, NR_TRANSPORT_LEN);
frontlen = skb_headroom(skb);
while (skb->len > 0) { if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) return;
skb_reserve(skbn, frontlen);
len = (NR_MAX_PACKET_SIZE > skb->len) ? skb->len : NR_MAX_PACKET_SIZE;
/* Copy the user data */
skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
skb_pull(skb, len);
/* Duplicate the Transport Header */
skb_push(skbn, NR_TRANSPORT_LEN);
skb_copy_to_linear_data(skbn, transport,
NR_TRANSPORT_LEN); if (skb->len > 0)
skbn->data[4] |= NR_MORE_FLAG;
skb_queue_tail(&sk->sk_write_queue, skbn); /* Throw it on the queue */
}
kfree_skb(skb);
} else {
skb_queue_tail(&sk->sk_write_queue, skb); /* Throw it on the queue */
}
nr_kick(sk);
}
/* * This procedure is passed a buffer descriptor for an iframe. It builds * the rest of the control part of the frame and then writes it out.
*/ staticvoid nr_send_iframe(struct sock *sk, struct sk_buff *skb)
{ struct nr_sock *nr = nr_sk(sk);
if (skb == NULL) return;
skb->data[2] = nr->vs;
skb->data[3] = nr->vr;
if (nr->condition & NR_COND_OWN_RX_BUSY)
skb->data[4] |= NR_CHOKE_FLAG;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.