// IPv6 パケットのビルド BUF *BuildIPv6(IPV6_ADDR *dest_ip, IPV6_ADDR *src_ip, UINT id, UCHAR protocol, UCHAR hop_limit, void *data, UINT size) { IPV6_HEADER_PACKET_INFO info; IPV6_HEADER ip_header; BUF *buf; UINT size_for_headers; // 引数チェック if (dest_ip == NULL || src_ip == NULL || data == NULL) { return NULL; } if (hop_limit == 0) { hop_limit = 255; } // IPv6 ヘッダ Zero(&ip_header, sizeof(ip_header)); IPV6_SET_VERSION(&ip_header, 6); ip_header.HopLimit = hop_limit; Copy(&ip_header.SrcAddress, src_ip, sizeof(IPV6_ADDR)); Copy(&ip_header.DestAddress, dest_ip, sizeof(IPV6_ADDR)); // ヘッダパケット情報の整理 Zero(&info, sizeof(info)); info.IPv6Header = &ip_header; info.Protocol = protocol; info.Payload = data; info.PayloadSize = size; buf = BuildIPv6PacketHeader(&info, &size_for_headers); if (buf == NULL) { return NULL; } return buf; }
void add_ip_header ( char *position, char *original_packet_position, int ip_payload_length, lisp_addr_t *src_addr, lisp_addr_t *dst_addr) { struct iphdr *iph = NULL; struct iphdr *inner_iph = NULL; struct ip6_hdr *ip6h = NULL; struct ip6_hdr *inner_ip6h = NULL; uint8_t tos = 0; uint8_t ttl = 0; inner_iph = (struct iphdr *) original_packet_position; /* We SHOULD copy ttl and tos fields from the inner packet to the encapsulated one */ if (inner_iph->version == 4 ) { tos = inner_iph->tos; ttl = inner_iph->ttl; } else { inner_ip6h = (struct ip6_hdr *) original_packet_position; ttl = inner_ip6h->ip6_hops; /* ttl = Hops limit in IPv6 */ //tos = (inner_ip6h->ip6_flow & 0x0ff00000) >> 20; /* 4 bits version, 8 bits Traffic Class, 20 bits flow-ID */ tos = IPV6_GET_TC(*inner_ip6h); /* tos = Traffic class field in IPv6 */ } /* * Construct and add the outer ip header */ switch (dst_addr->afi){ case AF_INET: iph = (struct iphdr *) position; iph->version = 4; //iph->ihl = sizeof ( struct iphdr ) >>2; iph->ihl = 5; /* Minimal IPv4 header */ /*XXX Beware, hardcoded. Supposing no IP options */ iph->tos = tos; iph->tot_len = htons(ip_payload_length); iph->frag_off = htons(IP_DF); /* Do not fragment flag. See 5.4.1 in LISP RFC (6830) */ iph->ttl = ttl; iph->protocol = IPPROTO_UDP; iph->check = 0; //Computed by the NIC (checksum offloading) iph->daddr = dst_addr->address.ip.s_addr; iph->saddr = src_addr->address.ip.s_addr; break; case AF_INET6: ip6h = ( struct ip6_hdr *) position; IPV6_SET_VERSION(ip6h, 6); IPV6_SET_TC(ip6h,tos); IPV6_SET_FLOW_LABEL(ip6h,0); ip6h->ip6_plen = htons(ip_payload_length); ip6h->ip6_nxt = IPPROTO_UDP; ip6h->ip6_hops = ttl; memcopy_lisp_addr(&(ip6h->ip6_dst),dst_addr); memcopy_lisp_addr(&(ip6h->ip6_src),src_addr); break; default: break; } }