mirror of
https://github.com/Stichting-MINIX-Research-Foundation/netbsd.git
synced 2025-09-08 23:00:18 -04:00
162 lines
3.0 KiB
C
162 lines
3.0 KiB
C
/* $NetBSD$ */
|
|
|
|
/*
|
|
* NPF testing - helper routines.
|
|
*
|
|
* Public Domain.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/kmem.h>
|
|
|
|
#include "npf_impl.h"
|
|
#include "npf_test.h"
|
|
|
|
struct mbuf *
|
|
mbuf_getwithdata(const void *data, size_t len)
|
|
{
|
|
struct mbuf *m;
|
|
void *dst;
|
|
|
|
m = m_gethdr(M_WAITOK, MT_HEADER);
|
|
assert(m != NULL);
|
|
dst = mtod(m, void *);
|
|
memcpy(dst, data, len);
|
|
m->m_pkthdr.len = len;
|
|
m->m_len = len;
|
|
return m;
|
|
}
|
|
|
|
struct mbuf *
|
|
mbuf_construct_ether(int proto)
|
|
{
|
|
struct mbuf *m0, *m1;
|
|
struct ether_header *ethdr;
|
|
|
|
m0 = m_gethdr(M_WAITOK, MT_HEADER);
|
|
ethdr = mtod(m0, struct ether_header *);
|
|
ethdr->ether_type = htons(ETHERTYPE_IP);
|
|
m0->m_pkthdr.len = sizeof(struct ether_header);
|
|
m0->m_len = sizeof(struct ether_header);
|
|
|
|
m1 = mbuf_construct(proto);
|
|
m0->m_next = m1;
|
|
m1->m_next = NULL;
|
|
return m0;
|
|
}
|
|
|
|
static int
|
|
mbuf_fill_proto(int proto, void *l4data)
|
|
{
|
|
struct tcphdr *th;
|
|
int size = 0;
|
|
|
|
switch (proto) {
|
|
case IPPROTO_TCP:
|
|
th = l4data;
|
|
th->th_off = sizeof(struct tcphdr) >> 2;
|
|
size = sizeof(struct tcphdr);
|
|
break;
|
|
case IPPROTO_UDP:
|
|
size = sizeof(struct udphdr);
|
|
break;
|
|
case IPPROTO_ICMP:
|
|
size = offsetof(struct icmp, icmp_data);
|
|
break;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
struct mbuf *
|
|
mbuf_construct(int proto)
|
|
{
|
|
struct mbuf *m;
|
|
struct ip *iphdr;
|
|
void *l4data;
|
|
int size;
|
|
|
|
m = m_gethdr(M_WAITOK, MT_HEADER);
|
|
iphdr = mtod(m, struct ip *);
|
|
|
|
iphdr->ip_v = IPVERSION;
|
|
iphdr->ip_hl = sizeof(struct ip) >> 2;
|
|
iphdr->ip_off = 0;
|
|
iphdr->ip_ttl = 64;
|
|
iphdr->ip_p = proto;
|
|
|
|
size = sizeof(struct ip);
|
|
l4data = (void *)(iphdr + 1);
|
|
size += mbuf_fill_proto(proto, l4data);
|
|
iphdr->ip_len = htons(size);
|
|
|
|
m->m_pkthdr.len = size;
|
|
m->m_len = size;
|
|
m->m_next = NULL;
|
|
return m;
|
|
}
|
|
|
|
struct mbuf *
|
|
mbuf_construct6(int proto)
|
|
{
|
|
struct mbuf *m;
|
|
struct ip6_hdr *ip6;
|
|
void *l4data;
|
|
int size;
|
|
|
|
m = m_gethdr(M_WAITOK, MT_HEADER);
|
|
ip6 = mtod(m, struct ip6_hdr *);
|
|
|
|
ip6->ip6_vfc = IPV6_VERSION;
|
|
ip6->ip6_nxt = proto;
|
|
ip6->ip6_hlim = 64;
|
|
|
|
size = sizeof(struct ip6_hdr);
|
|
l4data = (void *)(ip6 + 1);
|
|
size += mbuf_fill_proto(proto, l4data);
|
|
ip6->ip6_plen = htons(size);
|
|
|
|
m->m_pkthdr.len = size;
|
|
m->m_len = size;
|
|
m->m_next = NULL;
|
|
return m;
|
|
}
|
|
|
|
void *
|
|
mbuf_return_hdrs(struct mbuf *m, bool ether, struct ip **ip)
|
|
{
|
|
struct ip *iphdr;
|
|
|
|
if (ether) {
|
|
struct mbuf *mn = m->m_next;
|
|
iphdr = mtod(mn, struct ip *);
|
|
} else {
|
|
iphdr = mtod(m, struct ip *);
|
|
}
|
|
*ip = iphdr;
|
|
return (void *)(iphdr + 1);
|
|
}
|
|
|
|
void *
|
|
mbuf_return_hdrs6(struct mbuf *m, struct ip6_hdr **ip6)
|
|
{
|
|
struct ip6_hdr *ip6hdr = mtod(m, struct ip6_hdr *);
|
|
|
|
*ip6 = ip6hdr;
|
|
return (void *)(ip6hdr + 1);
|
|
}
|
|
|
|
void
|
|
mbuf_icmp_append(struct mbuf *m, struct mbuf *m_orig)
|
|
{
|
|
struct ip *iphdr = mtod(m, struct ip *);
|
|
const size_t hlen = iphdr->ip_hl << 2;
|
|
struct icmp *ic = (struct icmp *)((uint8_t *)iphdr + hlen);
|
|
const size_t addlen = m_length(m_orig);
|
|
|
|
iphdr->ip_len = htons(ntohs(iphdr->ip_len) + addlen);
|
|
memcpy(&ic->icmp_ip, mtod(m_orig, struct ip *), addlen);
|
|
m->m_pkthdr.len += addlen;
|
|
m->m_len += addlen;
|
|
m_freem(m_orig);
|
|
}
|