FreeBSD/tools/tools/netmap/pkt-gen.c
/*
 * initialize one packet and prepare for the next one.
 * The copy could be done better instead of repeating it each time.
 */
initialize one packet and prepare for the next one.
The copy could be done better instead of repeating it each time.
initialize one packet and prepare for the next one . The copy could be done better instead of repeating it each time .
static void
initialize_packet(struct targ *targ)
{
	struct pkt *pkt = &targ->pkt;
	struct ether_header *eh;
	struct ip *ip;
	struct udphdr *udp;
	uint16_t paylen = targ->g->pkt_size - sizeof(*eh) - sizeof(struct ip);
	const char *payload = targ->g->options & OPT_INDIRECT ?
		indirect_payload : default_payload;
	int i, l0 = strlen(payload);
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *file;
	struct pcap_pkthdr *header;
	const unsigned char *packet;
	if (targ->g->packet_file != NULL) {
		if ((file = pcap_open_offline(targ->g->packet_file,
			    errbuf)) == NULL)
			D("failed to open pcap file %s",
			    targ->g->packet_file);
		if (pcap_next_ex(file, &header, &packet) < 0)
			D("failed to read packet from %s",
			    targ->g->packet_file);
		if ((targ->frame = malloc(header->caplen)) == NULL)
			D("out of memory");
		bcopy(packet, (unsigned char *)targ->frame, header->caplen);
		targ->g->pkt_size = header->caplen;
		pcap_close(file);
		return;
	}
	for (i = 0; i < paylen; i += l0) {
		if (l0 > paylen - i)
			l0 = paylen - i; 
		bcopy(payload, pkt->body + i, l0);
	}
	pkt->body[i-1] = '\0';
	ip = &pkt->ip;
        ip->ip_v = IPVERSION;
        ip->ip_hl = 5;
        ip->ip_id = 0;
        ip->ip_tos = IPTOS_LOWDELAY;
	ip->ip_len = ntohs(targ->g->pkt_size - sizeof(*eh));
        ip->ip_id = 0;
        ip->ip_off = htons(IP_DF); 
        ip->ip_ttl = IPDEFTTL;
	ip->ip_p = IPPROTO_UDP;
	ip->ip_dst.s_addr = htonl(targ->g->dst_ip.start);
	ip->ip_src.s_addr = htonl(targ->g->src_ip.start);
	ip->ip_sum = wrapsum(checksum(ip, sizeof(*ip), 0));
	udp = &pkt->udp;
        udp->uh_sport = htons(targ->g->src_ip.port0);
        udp->uh_dport = htons(targ->g->dst_ip.port0);
	udp->uh_ulen = htons(paylen);
	udp->uh_sum = wrapsum(checksum(udp, sizeof(*udp),
                    checksum(pkt->body,
                        paylen - sizeof(*udp),
                        checksum(&ip->ip_src, 2 * sizeof(ip->ip_src),
                            IPPROTO_UDP + (u_int32_t)ntohs(udp->uh_ulen)
                        )
                    )
                ));
	eh = &pkt->eh;
	bcopy(&targ->g->src_mac.start, eh->ether_shost, 6);
	bcopy(&targ->g->dst_mac.start, eh->ether_dhost, 6);
	eh->ether_type = htons(ETHERTYPE_IP);
	bzero(&pkt->vh, sizeof(pkt->vh));
#ifdef TRASH_VHOST_HDR
	pkt->vh.fields[0] = 0xff;
	pkt->vh.fields[1] = 0xff;
	pkt->vh.fields[2] = 0xff;
	pkt->vh.fields[3] = 0xff;
	pkt->vh.fields[4] = 0xff;
	pkt->vh.fields[5] = 0xff;
#endif 
}
static void initialize_packet ( struct targ * targ ) { struct pkt * pkt = & targ -> pkt ; struct ether_header * eh ; struct ip * ip ; struct udphdr * udp ; uint16_t paylen = targ -> g -> pkt_size - sizeof ( * eh ) - sizeof ( struct ip ) ; const char * payload = targ -> g -> options & OPT_INDIRECT ? indirect_payload : default_payload ; int i , l0 = strlen ( payload ) ; char errbuf [ PCAP_ERRBUF_SIZE ] ; pcap_t * file ; struct pcap_pkthdr * header ; const unsigned char * packet ; if ( targ -> g -> packet_file != NULL ) { if ( ( file = pcap_open_offline ( targ -> g -> packet_file , errbuf ) ) == NULL ) D ( " " , targ -> g -> packet_file ) ; if ( pcap_next_ex ( file , & header , & packet ) < 0 ) D ( " " , targ -> g -> packet_file ) ; if ( ( targ -> frame = malloc ( header -> caplen ) ) == NULL ) D ( " " ) ; bcopy ( packet , ( unsigned char * ) targ -> frame , header -> caplen ) ; targ -> g -> pkt_size = header -> caplen ; pcap_close ( file ) ; return ; } for ( i = 0 ; i < paylen ; i += l0 ) { if ( l0 > paylen - i ) l0 = paylen - i ; bcopy ( payload , pkt -> body + i , l0 ) ; } pkt -> body [ i - 1 ] = ' \0 ' ; ip = & pkt -> ip ; ip -> ip_v = IPVERSION ; ip -> ip_hl = 5 ; ip -> ip_id = 0 ; ip -> ip_tos = IPTOS_LOWDELAY ; ip -> ip_len = ntohs ( targ -> g -> pkt_size - sizeof ( * eh ) ) ; ip -> ip_id = 0 ; ip -> ip_off = htons ( IP_DF ) ; ip -> ip_ttl = IPDEFTTL ; ip -> ip_p = IPPROTO_UDP ; ip -> ip_dst . s_addr = htonl ( targ -> g -> dst_ip . start ) ; ip -> ip_src . s_addr = htonl ( targ -> g -> src_ip . start ) ; ip -> ip_sum = wrapsum ( checksum ( ip , sizeof ( * ip ) , 0 ) ) ; udp = & pkt -> udp ; udp -> uh_sport = htons ( targ -> g -> src_ip . port0 ) ; udp -> uh_dport = htons ( targ -> g -> dst_ip . port0 ) ; udp -> uh_ulen = htons ( paylen ) ; udp -> uh_sum = wrapsum ( checksum ( udp , sizeof ( * udp ) , checksum ( pkt -> body , paylen - sizeof ( * udp ) , checksum ( & ip -> ip_src , 2 * sizeof ( ip -> ip_src ) , IPPROTO_UDP + ( u_int32_t ) ntohs ( udp -> uh_ulen ) ) ) ) ) ; eh = & pkt -> eh ; bcopy ( & targ -> g -> src_mac . start , eh -> ether_shost , 6 ) ; bcopy ( & targ -> g -> dst_mac . start , eh -> ether_dhost , 6 ) ; eh -> ether_type = htons ( ETHERTYPE_IP ) ; bzero ( & pkt -> vh , sizeof ( pkt -> vh ) ) ; #ifdef TRASH_VHOST_HDR pkt -> vh . fields [ 0 ] = 0xff ; pkt -> vh . fields [ 1 ] = 0xff ; pkt -> vh . fields [ 2 ] = 0xff ; pkt -> vh . fields [ 3 ] = 0xff ; pkt -> vh . fields [ 4 ] = 0xff ; pkt -> vh . fields [ 5 ] = 0xff ; #endif }
initialize one packet and prepare for the next one.
initialize one packet and prepare for the next one .
/* Read a packet from a PCAP file if asked. */ /* create a nice NUL-terminated string */ // last round /* prepare the headers */ /* Don't fragment */ /* Magic: taken from sbin/dhclient/packet.c */ /* set bogus content */ /* TRASH_VHOST_HDR */ // dump_payload((void *)pkt, targ->g->pkt_size, NULL, 0);