struct pppox_opt *relay_po = NULL;
if (sk->state & PPPOX_BOUND) {
- skb_pull(skb, sizeof(struct pppoe_hdr));
ppp_input(&po->chan, skb);
} else if (sk->state & PPPOX_RELAY) {
relay_po = get_item_by_addr(&po->pppoe_relay);
if ((relay_po->sk->state & PPPOX_CONNECTED) == 0)
goto abort_put;
- skb_pull(skb, sizeof(struct pppoe_hdr));
if (!__pppoe_xmit( relay_po->sk , skb))
goto abort_put;
} else {
{
struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
+ int len = ntohs(ph->length);
struct pppox_opt *po;
struct sock *sk ;
int ret;
+ skb_pull(skb, sizeof(*ph));
+ if (skb->len < len)
+ goto drop;
+
po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source);
+ if (!po)
+ goto drop;
- if (!po) {
- kfree_skb(skb);
- return NET_RX_DROP;
- }
+ if (pskb_trim(skb, len))
+ goto drop;
sk = po->sk;
bh_lock_sock(sk);
sock_put(sk);
return ret;
+ drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
}
/************************************************************************
struct sock *sk = sock->sk;
struct sk_buff *skb = NULL;
int error = 0;
- int len;
- struct pppoe_hdr *ph = NULL;
if (sk->state & PPPOX_BOUND) {
error = -EIO;
m->msg_namelen = 0;
if (skb) {
- error = 0;
- ph = (struct pppoe_hdr *) skb->nh.raw;
- len = ntohs(ph->length);
-
- error = memcpy_toiovec(m->msg_iov, (unsigned char *) &ph->tag[0], len);
- if (error < 0)
- goto do_skb_free;
- error = len;
+ total_len = min_t(int, total_len, skb->len);
+ error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
+ if (error == 0)
+ error = total_len;
}
-do_skb_free:
if (skb)
kfree_skb(skb);
end: