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