Home | History | Annotate | Line # | Download | only in libnpftest
npf_mbuf_subr.c revision 1.2
      1 /*	$NetBSD: npf_mbuf_subr.c,v 1.2 2012/05/30 21:38:04 rmind Exp $	*/
      2 
      3 /*
      4  * NPF testing - helper routines.
      5  *
      6  * Public Domain.
      7  */
      8 
      9 #include <sys/types.h>
     10 #include <sys/kmem.h>
     11 
     12 #include "npf_impl.h"
     13 #include "npf_test.h"
     14 
     15 struct mbuf *
     16 mbuf_getwithdata(const void *data, size_t len)
     17 {
     18 	struct mbuf *m;
     19 	void *dst;
     20 
     21 	m = m_gethdr(M_WAITOK, MT_HEADER);
     22 	assert(m != NULL);
     23 	dst = mtod(m, void *);
     24 	memcpy(dst, data, len);
     25 	m->m_len = len;
     26 	return m;
     27 }
     28 
     29 struct mbuf *
     30 mbuf_construct_ether(int proto)
     31 {
     32 	struct mbuf *m0, *m1;
     33 	struct ether_header *ethdr;
     34 
     35 	m0 = m_gethdr(M_WAITOK, MT_HEADER);
     36 	ethdr = mtod(m0, struct ether_header *);
     37 	ethdr->ether_type = htons(ETHERTYPE_IP);
     38 	m0->m_len = sizeof(struct ether_header);
     39 
     40 	m1 = mbuf_construct(proto);
     41 	m0->m_next = m1;
     42 	m1->m_next = NULL;
     43 	return m0;
     44 }
     45 
     46 struct mbuf *
     47 mbuf_construct(int proto)
     48 {
     49 	struct mbuf *m;
     50 	struct ip *iphdr;
     51 	struct tcphdr *th;
     52 	int size;
     53 
     54 	m = m_gethdr(M_WAITOK, MT_HEADER);
     55 	iphdr = mtod(m, struct ip *);
     56 
     57 	iphdr->ip_v = IPVERSION;
     58 	iphdr->ip_hl = sizeof(struct ip) >> 2;
     59 	iphdr->ip_off = 0;
     60 	iphdr->ip_ttl = 64;
     61 	iphdr->ip_p = proto;
     62 
     63 	size = sizeof(struct ip);
     64 
     65 	switch (proto) {
     66 	case IPPROTO_TCP:
     67 		th = (void *)(iphdr + 1);
     68 		th->th_off = sizeof(struct tcphdr) >> 2;
     69 		size += sizeof(struct tcphdr);
     70 		break;
     71 	case IPPROTO_UDP:
     72 		size += sizeof(struct udphdr);
     73 		break;
     74 	case IPPROTO_ICMP:
     75 		size += offsetof(struct icmp, icmp_data);
     76 		break;
     77 	}
     78 	iphdr->ip_len = htons(size);
     79 
     80 	m->m_len = size;
     81 	m->m_next = NULL;
     82 	return m;
     83 }
     84 
     85 void *
     86 mbuf_return_hdrs(struct mbuf *m, bool ether, struct ip **ip)
     87 {
     88 	struct ip *iphdr;
     89 
     90 	if (ether) {
     91 		struct mbuf *mn = m->m_next;
     92 		iphdr = mtod(mn, struct ip *);
     93 	} else {
     94 		iphdr = mtod(m, struct ip *);
     95 	}
     96 	*ip = iphdr;
     97 	return (void *)(iphdr + 1);
     98 }
     99 
    100 void
    101 mbuf_icmp_append(struct mbuf *m, struct mbuf *m_orig)
    102 {
    103 	struct ip *iphdr = mtod(m, struct ip *);
    104 	const size_t hlen = iphdr->ip_hl << 2;
    105 	struct icmp *ic = (struct icmp *)((uint8_t *)iphdr + hlen);
    106 	const size_t addlen = m_orig->m_len;
    107 
    108 	iphdr->ip_len = htons(ntohs(iphdr->ip_len) + addlen);
    109 	memcpy(&ic->icmp_ip, mtod(m_orig, struct ip *), addlen);
    110 	m->m_len += addlen;
    111 	m_freem(m_orig);
    112 }
    113