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