static struct sk_buff *fill_packet_ipv6(struct net_device *odev, 				   struct pktgen_dev *pkt_dev){	struct sk_buff *skb = NULL;	__u8 *eth;	struct udphdr *udph;	int datalen;	struct ipv6hdr *iph;        struct pktgen_hdr *pgh = NULL;        	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);	if (!skb) {		sprintf(pkt_dev->result, "No memory");		return NULL;	}	skb_reserve(skb, 16);	/*  Reserve for ethernet and IP header  */	eth = (__u8 *) skb_push(skb, 14);	iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));        /* Update any of the values, used when we're incrementing various         * fields.         */	mod_cur_headers(pkt_dev);		memcpy(eth, pkt_dev->hh, 12);	*(u16*)&eth[12] = __constant_htons(ETH_P_IPV6);	        	datalen = pkt_dev->cur_pkt_size-14- 		sizeof(struct ipv6hdr)-sizeof(struct udphdr); /* Eth + IPh + UDPh */	if (datalen < sizeof(struct pktgen_hdr)) { 		datalen = sizeof(struct pktgen_hdr);		if (net_ratelimit())			printk(KERN_INFO "pktgen: increased datalen to %d\n", datalen);	}	udph->source = htons(pkt_dev->cur_udp_src);	udph->dest = htons(pkt_dev->cur_udp_dst);	udph->len = htons(datalen + sizeof(struct udphdr)); 	udph->check = 0;  /* No checksum */	 *(u32*)iph = __constant_htonl(0x60000000); /* Version + flow */	iph->hop_limit = 32;	iph->payload_len = htons(sizeof(struct udphdr) + datalen);	iph->nexthdr = IPPROTO_UDP;	ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);	ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);	skb->mac.raw = ((u8 *)iph) - 14;	skb->protocol = __constant_htons(ETH_P_IPV6);	skb->dev = odev;	skb->pkt_type = PACKET_HOST;	if (pkt_dev->nfrags <= 0)                 pgh = (struct pktgen_hdr *)skb_put(skb, datalen);	else {		int frags = pkt_dev->nfrags;		int i;                pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);                		if (frags > MAX_SKB_FRAGS)			frags = MAX_SKB_FRAGS;		if (datalen > frags*PAGE_SIZE) {			skb_put(skb, datalen-frags*PAGE_SIZE);			datalen = frags*PAGE_SIZE;		}		i = 0;		while (datalen > 0) {			struct page *page = alloc_pages(GFP_KERNEL, 0);			skb_shinfo(skb)->frags[i].page = page;			skb_shinfo(skb)->frags[i].page_offset = 0;			skb_shinfo(skb)->frags[i].size =				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);			datalen -= skb_shinfo(skb)->frags[i].size;			skb->len += skb_shinfo(skb)->frags[i].size;			skb->data_len += skb_shinfo(skb)->frags[i].size;			i++;			skb_shinfo(skb)->nr_frags = i;		}		while (i < frags) {			int rem;			if (i == 0)				break;			rem = skb_shinfo(skb)->frags[i - 1].size / 2;			if (rem == 0)				break;			skb_shinfo(skb)->frags[i - 1].size -= rem;			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];			get_page(skb_shinfo(skb)->frags[i].page);			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;			skb_shinfo(skb)->frags[i].size = rem;			i++;			skb_shinfo(skb)->nr_frags = i;		}	}        /* Stamp the time, and sequence number, convert them to network byte order */	/* should we update cloned packets too ? */        if (pgh) {              struct timeval timestamp;	      	      pgh->pgh_magic = htonl(PKTGEN_MAGIC);	      pgh->seq_num   = htonl(pkt_dev->seq_num);	      	      do_gettimeofday(&timestamp);	      pgh->tv_sec    = htonl(timestamp.tv_sec);	      pgh->tv_usec   = htonl(timestamp.tv_usec);        }        pkt_dev->seq_num++;        	return skb;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/64053beeb5a5f9cd79903a8c3dd35d1ef0a4685f/pktgen.c/clean/net/core/pktgen.c