예제 #1
0
void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
{
	struct sockaddr_llc *addr;

       /* save primitive for use by the user. */
	addr		  = llc_ui_skb_cb(skb);

	memset(addr, 0, sizeof(*addr));
	addr->sllc_family = sk->sk_family;
	addr->sllc_arphrd = skb->dev->type;
	addr->sllc_test   = prim == LLC_TEST_PRIM;
	addr->sllc_xid    = prim == LLC_XID_PRIM;
	addr->sllc_ua     = prim == LLC_DATAUNIT_PRIM;
	llc_pdu_decode_sa(skb, addr->sllc_mac);
	llc_pdu_decode_ssap(skb, &addr->sllc_sap);
}
예제 #2
0
/**
 *	llc_ui_recvmsg - copy received data to the socket user.
 *	@sock: Socket to copy data from.
 *	@msg: Various user space related information.
 *	@size: Size of user buffer.
 *	@flags: User specified flags.
 *
 *	Copy received data to the socket user.
 *	Returns non-negative upon success, negative otherwise.
 */
static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
			  struct msghdr *msg, size_t size, int flags)
{
	struct sock *sk = sock->sk;
	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
	struct sk_buff *skb;
	size_t copied = 0;
	int rc = -ENOMEM, timeout;
	int noblock = flags & MSG_DONTWAIT;

	dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
		llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
	lock_sock(sk);
	timeout = sock_rcvtimeo(sk, noblock);
	rc = llc_ui_wait_for_data(sk, timeout);
	if (rc) {
		dprintk("%s: llc_ui_wait_for_data failed recv "
			"in %02X from %02X\n", __FUNCTION__,
			llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
		goto out;
	}
	skb = skb_dequeue(&sk->sk_receive_queue);
	if (!skb) /* shutdown */
		goto out;
	copied = skb->len;
	if (copied > size)
		copied = size;
	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
	if (rc)
		goto dgram_free;
	if (skb->len > copied) {
		skb_pull(skb, copied);
		skb_queue_head(&sk->sk_receive_queue, skb);
	}
	if (uaddr)
		memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
	msg->msg_namelen = sizeof(*uaddr);
	if (!skb->list) {
dgram_free:
		kfree_skb(skb);
	}
out:
	release_sock(sk);
	return rc ? : copied;
}