2024-02-21 15:06:48 +08:00
|
|
|
#ifndef _IPV6_UTILS_H
|
|
|
|
|
#define _IPV6_UTILS_H
|
2024-01-11 16:46:33 +08:00
|
|
|
|
|
|
|
|
#ifdef __cpluscplus
|
|
|
|
|
extern "C"
|
|
|
|
|
{
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <netinet/ip6.h>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* IPv6 Header Format
|
|
|
|
|
*
|
|
|
|
|
* 0 1 2 3
|
|
|
|
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
* |Version| Traffic Class | Flow Label |
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
* | Payload Length | Next Header | Hop Limit |
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
* | |
|
|
|
|
|
* + +
|
|
|
|
|
* | |
|
|
|
|
|
* + Source Address +
|
|
|
|
|
* | |
|
|
|
|
|
* + +
|
|
|
|
|
* | |
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
* | |
|
|
|
|
|
* + +
|
|
|
|
|
* | |
|
|
|
|
|
* + Destination Address +
|
|
|
|
|
* | |
|
|
|
|
|
* + +
|
|
|
|
|
* | |
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
2024-02-22 18:52:04 +08:00
|
|
|
*
|
|
|
|
|
* Fragment Header
|
|
|
|
|
*
|
|
|
|
|
* 0 1 2 3
|
|
|
|
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
* | Next Header | Reserved | Fragment Offset |Res|M|
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
* | Identification |
|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
2024-01-11 16:46:33 +08:00
|
|
|
*/
|
|
|
|
|
|
2024-02-21 15:06:48 +08:00
|
|
|
/******************************************************************************
|
|
|
|
|
* get
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
2024-01-11 16:46:33 +08:00
|
|
|
static inline uint8_t ipv6_hdr_get_version(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
return (ntohl(hdr->ip6_flow) & 0xf0000000) >> 28;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint8_t ipv6_hdr_get_traffic_class(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
return (ntohl(hdr->ip6_flow) & 0x0ff00000) >> 20;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint32_t ipv6_hdr_get_flow_label(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
return ntohl(hdr->ip6_flow) & 0x000fffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint16_t ipv6_hdr_get_payload_len(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
return ntohs(hdr->ip6_plen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint8_t ipv6_hdr_get_next_header(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
return hdr->ip6_nxt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint8_t ipv6_hdr_get_hop_limit(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
return hdr->ip6_hlim;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 15:06:48 +08:00
|
|
|
static inline struct in6_addr ipv6_hdr_get_src_in6_addr(const struct ip6_hdr *hdr)
|
2024-01-11 16:46:33 +08:00
|
|
|
{
|
|
|
|
|
return hdr->ip6_src;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 15:06:48 +08:00
|
|
|
static inline struct in6_addr ipv6_hdr_get_dst_in6_addr(const struct ip6_hdr *hdr)
|
2024-01-11 16:46:33 +08:00
|
|
|
{
|
|
|
|
|
return hdr->ip6_dst;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-22 18:52:04 +08:00
|
|
|
static inline struct ip6_frag *ipv6_hdr_get_frag_ext(const struct ip6_hdr *hdr)
|
|
|
|
|
{
|
|
|
|
|
if (hdr->ip6_nxt != IPPROTO_FRAGMENT)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return (struct ip6_frag *)((char *)hdr + sizeof(struct ip6_hdr));
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 15:06:48 +08:00
|
|
|
/******************************************************************************
|
|
|
|
|
* set
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_version(struct ip6_hdr *hdr, uint8_t version)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_flow = htonl((ntohl(hdr->ip6_flow) & 0x0fffffff) | (version << 28));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_traffic_class(struct ip6_hdr *hdr, uint8_t traffic_class)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_flow = htonl((ntohl(hdr->ip6_flow) & 0xf00fffff) | (traffic_class << 20));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_flow_label(struct ip6_hdr *hdr, uint32_t flow_label)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_flow = htonl((ntohl(hdr->ip6_flow) & 0xfff00000) | flow_label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_payload_len(struct ip6_hdr *hdr, uint16_t payload_len)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_plen = htons(payload_len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_next_header(struct ip6_hdr *hdr, uint8_t next_header)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_nxt = next_header;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_hop_limit(struct ip6_hdr *hdr, uint8_t hop_limit)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_hlim = hop_limit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_src_in6_addr(struct ip6_hdr *hdr, struct in6_addr src_addr)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_src = src_addr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_hdr_set_dst_in6_addr(struct ip6_hdr *hdr, struct in6_addr dst_addr)
|
|
|
|
|
{
|
|
|
|
|
hdr->ip6_dst = dst_addr;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-23 18:19:52 +08:00
|
|
|
/******************************************************************************
|
|
|
|
|
* IPv6 frag extension headers
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
static inline uint8_t ipv6_frag_get_next_header(const struct ip6_frag *frag)
|
|
|
|
|
{
|
|
|
|
|
return frag->ip6f_nxt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint16_t ipv6_frag_get_offset(const struct ip6_frag *frag)
|
|
|
|
|
{
|
|
|
|
|
return ntohs(frag->ip6f_offlg & IP6F_OFF_MASK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint32_t ipv6_frag_get_ident(const struct ip6_frag *frag)
|
|
|
|
|
{
|
|
|
|
|
return ntohl(frag->ip6f_ident);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool ipv6_frag_get_more(const struct ip6_frag *frag)
|
|
|
|
|
{
|
|
|
|
|
return (frag->ip6f_offlg & IP6F_MORE_FRAG);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_frag_set_next_header(struct ip6_frag *frag, uint8_t next_header)
|
|
|
|
|
{
|
|
|
|
|
frag->ip6f_nxt = next_header;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_frag_set_offset(struct ip6_frag *frag, uint16_t offset)
|
|
|
|
|
{
|
|
|
|
|
frag->ip6f_offlg = (frag->ip6f_offlg & ~IP6F_OFF_MASK) | htons(offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_frag_set_ident(struct ip6_frag *frag, uint32_t ident)
|
|
|
|
|
{
|
|
|
|
|
frag->ip6f_ident = htonl(ident);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ipv6_frag_set_more(struct ip6_frag *frag, bool more)
|
|
|
|
|
{
|
|
|
|
|
if (more)
|
|
|
|
|
{
|
|
|
|
|
frag->ip6f_offlg |= IP6F_MORE_FRAG;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
frag->ip6f_offlg &= ~IP6F_MORE_FRAG;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-21 15:06:48 +08:00
|
|
|
|
2024-01-11 16:46:33 +08:00
|
|
|
#ifdef __cpluscplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|