kernels/linux-2.4.0/drivers/net/pppoe.c
/************************************************************************
 *
 * xmit function for internal use.
 *
 ***********************************************************************/
xmit function for internal use.
xmit function for internal use .
int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
{
	struct net_device *dev = sk->protinfo.pppox->pppoe_dev;
	struct pppoe_hdr hdr;
	struct pppoe_hdr *ph;
	int headroom = skb_headroom(skb);
	int data_len = skb->len;
	if (sk->dead  || !(sk->state & PPPOX_CONNECTED)) {
		goto abort;
	}
	hdr.ver	= 1;
	hdr.type = 1;
	hdr.code = 0;
	hdr.sid	= sk->num;
	hdr.length = htons(skb->len);
	if (!dev) {
		goto abort;
	}
	if (headroom < (sizeof(struct pppoe_hdr) + dev->hard_header_len)) {
		struct sk_buff *skb2;
		skb2 = dev_alloc_skb(32+skb->len +
				     sizeof(struct pppoe_hdr) +
				     dev->hard_header_len);
		if (skb2 == NULL)
			goto abort;
		skb_reserve(skb2, dev->hard_header_len + sizeof(struct pppoe_hdr));
		memcpy(skb_put(skb2, skb->len), skb->data, skb->len);
		skb_unlink(skb);
		kfree_skb(skb);
		skb = skb2;
	}
	ph = (struct pppoe_hdr *) skb_push(skb, sizeof(struct pppoe_hdr));
	memcpy(ph, &hdr, sizeof(struct pppoe_hdr));
	skb->protocol = __constant_htons(ETH_P_PPP_SES);
	skb->nh.raw = skb->data;
	skb->dev = dev;
	dev->hard_header(skb, dev, ETH_P_PPP_SES,
			 sk->protinfo.pppox->pppoe_pa.remote,
			 NULL, data_len);
	if (dev_queue_xmit(skb) < 0)
		goto abort;
	return 1;
 abort:
	return 0;
}
int __pppoe_xmit ( struct sock * sk , struct sk_buff * skb ) { struct net_device * dev = sk -> protinfo . pppox -> pppoe_dev ; struct pppoe_hdr hdr ; struct pppoe_hdr * ph ; int headroom = skb_headroom ( skb ) ; int data_len = skb -> len ; if ( sk -> dead || ! ( sk -> state & PPPOX_CONNECTED ) ) { goto abort ; } hdr . ver = 1 ; hdr . type = 1 ; hdr . code = 0 ; hdr . sid = sk -> num ; hdr . length = htons ( skb -> len ) ; if ( ! dev ) { goto abort ; } if ( headroom < ( sizeof ( struct pppoe_hdr ) + dev -> hard_header_len ) ) { struct sk_buff * skb2 ; skb2 = dev_alloc_skb ( 32 + skb -> len + sizeof ( struct pppoe_hdr ) + dev -> hard_header_len ) ; if ( skb2 == NULL ) goto abort ; skb_reserve ( skb2 , dev -> hard_header_len + sizeof ( struct pppoe_hdr ) ) ; memcpy ( skb_put ( skb2 , skb -> len ) , skb -> data , skb -> len ) ; skb_unlink ( skb ) ; kfree_skb ( skb ) ; skb = skb2 ; } ph = ( struct pppoe_hdr * ) skb_push ( skb , sizeof ( struct pppoe_hdr ) ) ; memcpy ( ph , & hdr , sizeof ( struct pppoe_hdr ) ) ; skb -> protocol = __constant_htons ( ETH_P_PPP_SES ) ; skb -> nh . raw = skb -> data ; skb -> dev = dev ; dev -> hard_header ( skb , dev , ETH_P_PPP_SES , sk -> protinfo . pppox -> pppoe_pa . remote , NULL , data_len ) ; if ( dev_queue_xmit ( skb ) < 0 ) goto abort ; return 1 ; abort : return 0 ; }
xmit function for internal use.
xmit function for internal use .
/* Copy the skb if there is no space for the header. */