From f8efe2454332834c0a55f58c8d1edf3885e76727 Mon Sep 17 00:00:00 2001 From: duxbbo Date: Mon, 18 Jul 2022 04:03:27 +0000 Subject: [PATCH] add protocol def Signed-off-by: duxbbo --- code/net/newip/nip_hdr.h | 234 ++++++++++++++++++++++++++ code/net/newip/nip_hdr_decap.c | 292 +++++++++++++++++++++++++++++++++ code/net/newip/nip_hdr_encap.c | 175 ++++++++++++++++++++ 3 files changed, 701 insertions(+) create mode 100644 code/net/newip/nip_hdr.h create mode 100644 code/net/newip/nip_hdr_decap.c create mode 100644 code/net/newip/nip_hdr_encap.c diff --git a/code/net/newip/nip_hdr.h b/code/net/newip/nip_hdr.h new file mode 100644 index 0000000..1622c5d --- /dev/null +++ b/code/net/newip/nip_hdr.h @@ -0,0 +1,234 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _NEWIP_HDR_H +#define _NEWIP_HDR_H + +#include + +/* Ethernet head 14B, +2B byte alignment, +66 to avoid + * HMAC driver SKB space expansion caused by Coredum problem + */ +#define NIP_ETH_HDR_BASE_LEN 14 +#define NIP_ETH_HDR_LEN (NIP_ETH_HDR_BASE_LEN + 2 + 66) + +/* bitmap1 + bitmap2 + TTL + total len + nexthd + daddr + saddr + * 1B 1B 1B 2B 1B 7B 7B = 20B + * NIP_HDR_MAX 可以从50 修改成 20 + * V4 TCP 1448 + * NIP TCP 1430 + 30 = 1460 + */ +#define NIP_HDR_MAX 8 // 50 -> 8 +#define NIP_UDP_HDR_LEN 8 +#define NIP_MIN_MTU (NIP_HDR_MAX + NIP_UDP_HDR_LEN) +#define NIP_BYTE_ALIGNMENT 2 + +#define NIP_BITMAP_HAVE_MORE_BIT 0x01 + +/* Bitmap 1st Byte: bit0 - bit7 */ +#define NIP_BITMAP_INVALID_SET 0x80 /* Bit 0 is set */ +#define NIP_BITMAP_INCLUDE_TTL 0x40 /* Bit 1 is set */ +#define NIP_BITMAP_INCLUDE_TOTAL_LEN 0x20 /* Bit 2 is set */ +#define NIP_BITMAP_INCLUDE_NEXT_HDR 0x10 /* Bit 3 is set */ +#define NIP_BITMAP_INCLUDE_RES1 0x08 /* Bit 4 is set */ +#define NIP_BITMAP_INCLUDE_DADDR 0x04 /* Bit 5 is set */ +#define NIP_BITMAP_INCLUDE_SADDR 0x02 /* Bit 6 is set */ +#define NIP_BITMAP_HAVE_BYTE_2 NIP_BITMAP_HAVE_MORE_BIT /* Bit 7 is set */ + +/* Bitmap 2nd Byte: bit0 - bit7 */ +#define NIP_BITMAP_INCLUDE_HDR_LEN 0x80 /* Bit 0 is set */ +#define NIP_BITMAP_INCLUDE_RES2 0x40 /* Bit 1 is set */ +#define NIP_BITMAP_INCLUDE_RES3 0x20 /* Bit 2 is set */ +#define NIP_BITMAP_INCLUDE_RES4 0x10 /* Bit 3 is set */ +#define NIP_BITMAP_INCLUDE_RES5 0x08 /* Bit 4 is set */ +#define NIP_BITMAP_INCLUDE_RES6 0x04 /* Bit 5 is set */ +#define NIP_BITMAP_INCLUDE_RES7 0x02 /* Bit 6 is set */ +#define NIP_BITMAP_HAVE_BYTE_3 NIP_BITMAP_HAVE_MORE_BIT /* Bit 7 is set */ + +/* Bitmap 1st Byte: + * | valid | ttl | total_len | next_hdr | res1 | daddr | saddr | have byte2 | + * | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | + */ +#define NIP_UDP_BITMAP_1 0x56 +#define NIP_UDP_BITMAP_1_INC_2 0x57 + +/* Bitmap 1st Byte: + * | valid | ttl | total_len | next_hdr | res1 | daddr | saddr | have byte2 | + * | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | + */ +#define NIP_NORMAL_BITMAP_1 0x76 +#define NIP_NORMAL_BITMAP_1_INC_2 0x77 + +/* Bitmap 2nd Byte: + * | hdr_len | res2 | res2 | res2 | res2 | res2 | res2 | have byte3 | + * | 0 or 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + */ +#define NIP_NODATA_BITMAP_2 0x00 +#define NIP_NORMAL_BITMAP_2 0x80 + +/* invalid Bitmap 2nd Byte: + * | hdr_len | res2 | res2 | res2 | res2 | res2 | res2 | have byte3 | + * | 0 or 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + */ +#define NIP_INVALID_BITMAP_2 0x7F + +#define NIP_DEFAULT_TTL 128 +#define NIP_ARP_DEFAULT_TTL 64 +#define IPPROTO_NIP_ICMP 0xB1 + +enum NIP_HDR_DECAP_ERR { + NIP_HDR_BITMAP_INVALID = 1, + NIP_HDR_BITMAP_NUM_OUT_RANGE = 2, + NIP_HDR_NO_TTL = 3, + NIP_HDR_NO_NEXT_HDR = 4, + NIP_HDR_NO_DADDR = 5, + NIP_HDR_DECAP_DADDR_ERR = 6, + NIP_HDR_DADDR_INVALID = 7, + NIP_HDR_DECAP_SADDR_ERR = 8, + NIP_HDR_SADDR_INVALID = 9, + NIP_HDR_RCV_BUF_READ_OUT_RANGE = 10, + NIP_HDR_UNKNOWN_AND_NO_HDR_LEN = 11, + NIP_HDR_LEN_INVALID = 12, + NIP_HDR_LEN_OUT_RANGE = 13, + + NIP_HDR_DECAP_ERRCODE_MAX, +}; + +/* The newIP header contains variable-length fields. + * The header structure is defined only for function parameter transmission. + * The fields are parsed in the original packet and saved + */ +struct nip_hdr_decap { + struct nip_addr saddr; /* Source address, network order.(big end) */ + struct nip_addr daddr; /* Destination address, network order.(big end) */ + + unsigned char ttl; /* Hop count limit */ + unsigned char nexthdr; /* Upper-layer Protocol Type: IPPROTO_UDP */ + unsigned char hdr_len; /* Indicates the length of the packet header */ + unsigned char hdr_real_len; /* Indicates the actual length of the packet header */ + + unsigned short total_len; /* Packet length (Header + packet), network order.(big end) */ + unsigned short no_hdr_len : 1; /* The header does not contain a header length field */ + unsigned short include_unknown_bit : 1; /* There is no other bitmap field */ + unsigned short include_saddr : 1; + unsigned short include_daddr : 1; + unsigned short include_ttl : 1; + unsigned short include_nexthdr : 1; + unsigned short include_hdr_len : 1; + unsigned short include_total_len : 1; + unsigned short res : 8; + + unsigned int rcv_buf_len; +}; + +/* The newIP packet header function is an incoming or outgoing parameter, + * which is not the content encapsulated in the packet + */ +#define BITMAP_MAX 8 +#define RES_NUM 2 +struct nip_hdr_encap { + struct nip_addr daddr; /* Destination address, network order.(big end) */ + struct nip_addr saddr; /* Source address, network order.(big end) */ + + unsigned char ttl; /* Hop count limit */ + unsigned char nexthdr; /* Upper-layer Protocol Type: IPPROTO_UDP */ + unsigned short total_len; /* Packet header length + packet data length */ + + void *usr_data; /* User data pointer */ + unsigned int usr_data_len; /* Length of data sent by the user */ + unsigned int trans_hdr_len; /* Transport layer header length */ + + unsigned short sport; + unsigned short dport; + + /* The following are the output parameters */ + unsigned char bitmap[BITMAP_MAX]; /* Bitmap currently supports a maximum of 8 bytes */ + unsigned int bitmap_num; /* Number of valid elements in the bitmap array */ + + unsigned char *hdr_buf; /* Cache the newIP header */ + unsigned int hdr_buf_pos; /* Buf Buffer writable address offset */ + unsigned short *frag_id_pos; /* Fragment Offset in the original packet */ + unsigned char *hdr_len_pos; /* Indicates the actual length of the packet header */ + unsigned short *total_len_pos; /* Total length position of the packet */ + + /* Whether the bitmap of the packet header carries a flag */ + unsigned char encap_ttl : 1; + unsigned char encap_hdr_len : 1; + unsigned char encap_daddr : 1; + unsigned char encap_saddr : 1; + unsigned char encap_total_len : 1; + unsigned char encap_res : 3; +}; + +/* Packet segment information */ +struct nip_pkt_seg_info { + unsigned int mid_pkt_num; /* Number of intermediate segments */ + unsigned int last_pkt_num; /* Number of last segments */ + + unsigned int mid_usr_pkt_len; /* Middle segment data length (8B aligned) */ + unsigned int last_usr_pkt_len; /* Length of the last data segment */ + + unsigned char *usr_data; /* Holds a pointer to the user's raw data */ + unsigned int usr_data_len; /* Length of user data read this time */ +}; + +void nip_calc_pkt_frag_num(unsigned int mtu, unsigned int usr_data_len, + struct nip_pkt_seg_info *seg_info); + +void nip_hdr_udp_encap(struct nip_hdr_encap *head); + +/* need update total len after this func, call nip_update_total_len */ +void nip_hdr_comm_encap(struct nip_hdr_encap *head); + +/* input must be network order. */ +void nip_update_total_len(struct nip_hdr_encap *head, unsigned short total_len); + +/* Note: a function call requires its own byte order conversion.(niph->total_len) */ +int nip_hdr_parse(unsigned char *buf, unsigned int buf_len, struct nip_hdr_decap *niph); + +struct udp_hdr { + unsigned short sport; + unsigned short dport; + unsigned short len; + unsigned short checksum; +}; + +/* input must be network order. */ +static inline void nip_build_udp_hdr(unsigned short sport, unsigned short dport, + unsigned short len, unsigned char *buf, + unsigned short checksum) +{ + struct udp_hdr *uh; + + uh = (struct udp_hdr *)buf; + uh->sport = sport; + uh->dport = dport; + uh->len = len; + uh->checksum = checksum; +} + +#endif /* _NEWIP_HDR_H */ + diff --git a/code/net/newip/nip_hdr_decap.c b/code/net/newip/nip_hdr_decap.c new file mode 100644 index 0000000..bf8743b --- /dev/null +++ b/code/net/newip/nip_hdr_decap.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "nip_hdr.h" + +/* Must carry the current field */ +static int _get_nip_hdr_bitmap(unsigned char *buf, + unsigned char bitmap[], + unsigned char bitmap_index_max) +{ + int i = 0; + unsigned char *p = buf; + + if (*p & NIP_BITMAP_INVALID_SET) + return -NIP_HDR_BITMAP_INVALID; + + do { + if (i >= bitmap_index_max) + return -NIP_HDR_BITMAP_NUM_OUT_RANGE; + + bitmap[i] = *p; + p++; + } while (bitmap[i++] & NIP_BITMAP_HAVE_MORE_BIT); + + return i; +} + +/* Must carry the current field */ +static int _get_nip_hdr_ttl(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + if (!(bitmap & NIP_BITMAP_INCLUDE_TTL)) + return -NIP_HDR_NO_TTL; + + niph->ttl = *buf; + niph->include_ttl = 1; + + return sizeof(niph->ttl); +} + +/* Optional fields */ +/* Communication between devices of the same version may not carry packet Header length, + * but communication between devices of different versions must carry packet header length + */ +static int _get_nip_hdr_len(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + if (!(bitmap & NIP_BITMAP_INCLUDE_HDR_LEN)) + return 0; + + /* Total_len is a network sequence and cannot be + * compared directly with the local sequence + */ + niph->hdr_len = *buf; + niph->include_hdr_len = 1; + + if (niph->include_total_len && niph->hdr_len >= niph->rcv_buf_len) + return -NIP_HDR_LEN_OUT_RANGE; + + return sizeof(niph->hdr_len); +} + +/* Must carry the current field */ +static int _get_nip_hdr_nexthdr(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + if (!(bitmap & NIP_BITMAP_INCLUDE_NEXT_HDR)) + return -NIP_HDR_NO_NEXT_HDR; + + niph->nexthdr = *buf; + niph->include_nexthdr = 1; + + return sizeof(niph->nexthdr); +} + +/* Must carry the current field */ +/* Note: niph->saddr is network order.(big end) */ +static int _get_nip_hdr_daddr(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + unsigned char *p; + + if (!(bitmap & NIP_BITMAP_INCLUDE_DADDR)) + return -NIP_HDR_NO_DADDR; + + p = decode_nip_addr(buf, &niph->daddr); + if (!p) + return -NIP_HDR_DECAP_DADDR_ERR; + + if (nip_addr_invalid(&niph->daddr)) + return -NIP_HDR_DADDR_INVALID; + + niph->include_daddr = 1; + return (niph->daddr.bitlen / NIP_ADDR_BIT_LEN_8); +} + +/* Optional fields */ +/* Note: niph->daddr is network order.(big end) */ +static int _get_nip_hdr_saddr(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + unsigned char *p; + + if (!(bitmap & NIP_BITMAP_INCLUDE_SADDR)) + return 0; + + p = decode_nip_addr(buf, &niph->saddr); + if (!p) + return -NIP_HDR_DECAP_SADDR_ERR; + + if (nip_addr_invalid(&niph->saddr)) + return -NIP_HDR_SADDR_INVALID; + + niph->include_saddr = 1; + return (niph->saddr.bitlen / NIP_ADDR_BIT_LEN_8); +} + +/* Optional fields: tcp/arp need, udp needless */ +/* Note: niph->total_len is network order.(big end), need change to host order */ +static int _get_nip_total_len(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + if (!(bitmap & NIP_BITMAP_INCLUDE_TOTAL_LEN)) + return 0; + + /* Total_len is a network sequence and cannot be + * compared directly with the local sequence + */ + niph->total_len = *((unsigned short *)buf); + niph->include_total_len = 1; + + return sizeof(niph->total_len); +} + +static int _nip_hdr_bitmap0_parse(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + int len; + int len_total = 0; + + len = _get_nip_hdr_ttl(buf, bitmap, niph); + if (len < 0) + return len; + len_total += len; + + /* Optional fields */ + len = _get_nip_total_len(buf + len_total, bitmap, niph); + if (len < 0) + return len; + len_total += len; + + len = _get_nip_hdr_nexthdr(buf + len_total, bitmap, niph); + if (len < 0) + return len; + len_total += len; + + len = _get_nip_hdr_daddr(buf + len_total, bitmap, niph); + if (len < 0) + return len; + len_total += len; + + len = _get_nip_hdr_saddr(buf + len_total, bitmap, niph); + if (len < 0) + return len; + len_total += len; + + return len_total; +} + +static int _nip_hdr_bitmap1_parse(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + int len; + int len_total = 0; + + /* If add new field needs to be modified with the macro definition */ + if (bitmap & NIP_INVALID_BITMAP_2) + niph->include_unknown_bit = 1; + + /* Optional fields */ + len = _get_nip_hdr_len(buf + len_total, bitmap, niph); + if (len < 0) + return len; + len_total += len; + + return len_total; +} + +static int _nip_hdr_unknown_bit_check(unsigned char *buf, + unsigned char bitmap, + struct nip_hdr_decap *niph) +{ + niph->include_unknown_bit = 1; + return 0; +} + +#define FACTORY_NUM_MAX 3 +static int (*hdr_parse_factory[FACTORY_NUM_MAX])(unsigned char *, + unsigned char, + struct nip_hdr_decap *) = { + _nip_hdr_bitmap0_parse, + _nip_hdr_bitmap1_parse, + _nip_hdr_unknown_bit_check, +}; + +static int nip_hdr_check(struct nip_hdr_decap *niph) +{ + if (niph->include_unknown_bit && !niph->include_hdr_len) + /* different ver pkt but no hdr len */ + return -NIP_HDR_UNKNOWN_AND_NO_HDR_LEN; + + if (niph->include_hdr_len) { + if (niph->hdr_len == 0 || + niph->hdr_len < niph->hdr_real_len) + return -NIP_HDR_LEN_INVALID; + } + + return 0; +} + +/* Note: + * 1.niph->total_len is network order.(big end), need change to host order + * 2.niph->saddr/daddr is network order.(big end) + */ +int nip_hdr_parse(unsigned char *buf, unsigned int buf_len, struct nip_hdr_decap *niph) +{ + int i = 0; + int len; + int ret; + unsigned char bitmap[BITMAP_MAX] = {0}; + int num = _get_nip_hdr_bitmap(buf, bitmap, BITMAP_MAX); + + if (num <= 0) + return num; + + niph->hdr_real_len = num * sizeof(bitmap[0]); + buf += niph->hdr_real_len; + + niph->rcv_buf_len = buf_len; + while (i < num) { + if (i >= FACTORY_NUM_MAX) + break; + len = hdr_parse_factory[i](buf, bitmap[i], niph); + if (len < 0) + return len; + + buf += len; + niph->hdr_real_len += len; + if (niph->hdr_real_len >= buf_len) + return -NIP_HDR_RCV_BUF_READ_OUT_RANGE; + i++; + } + + ret = nip_hdr_check(niph); + if (ret < 0) + return ret; + + return niph->hdr_len > niph->hdr_real_len ? + niph->hdr_len : niph->hdr_real_len; +} + diff --git a/code/net/newip/nip_hdr_encap.c b/code/net/newip/nip_hdr_encap.c new file mode 100644 index 0000000..4a034da --- /dev/null +++ b/code/net/newip/nip_hdr_encap.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "nip_hdr.h" + +#define INTEGER_MULTIPLE_OF_8 (~7) /* ~7 is an integer multiple of 8 */ +#define FMT_FACTORY_NUM_MAX 1 +#define ENCAP_FACTORY_NUM_MAX 1 + +void nip_calc_pkt_frag_num(unsigned int mtu, unsigned int usr_data_len, + struct nip_pkt_seg_info *seg_info) +{ + unsigned int mid_usr_pkt_len = (mtu - NIP_HDR_MAX - NIP_UDP_HDR_LEN) & + INTEGER_MULTIPLE_OF_8; + unsigned int mid_pkt_num = usr_data_len / mid_usr_pkt_len; + unsigned int last_usr_pkt_len = 0; + + if (usr_data_len != 0) { + last_usr_pkt_len = usr_data_len % mid_usr_pkt_len; + if (last_usr_pkt_len == 0) { + last_usr_pkt_len = mid_usr_pkt_len; + mid_pkt_num--; + } + } + + seg_info->last_pkt_num = 1; + seg_info->mid_pkt_num = mid_pkt_num; + seg_info->mid_usr_pkt_len = mid_usr_pkt_len; + seg_info->last_usr_pkt_len = last_usr_pkt_len; +} + +static inline void _nip_hdr_ttl_encap(struct nip_hdr_encap *head) +{ + *(head->hdr_buf + head->hdr_buf_pos) = head->ttl; + head->hdr_buf_pos += sizeof(head->ttl); +} + +static inline void _nip_hdr_len_encap(struct nip_hdr_encap *head) +{ + head->hdr_len_pos = head->hdr_buf + head->hdr_buf_pos; + head->hdr_buf_pos += 1; +} + +static inline void _nip_update_hdr_len(struct nip_hdr_encap *head) +{ + *head->hdr_len_pos = head->hdr_buf_pos; +} + +static inline void _nip_hdr_nexthdr_encap(struct nip_hdr_encap *head) +{ + *(head->hdr_buf + head->hdr_buf_pos) = head->nexthdr; + head->hdr_buf_pos += sizeof(head->nexthdr); +} + +static inline void _nip_hdr_daddr_encap(struct nip_hdr_encap *head) +{ + (void)build_nip_addr(&head->daddr, (head->hdr_buf + head->hdr_buf_pos)); + head->hdr_buf_pos += (head->daddr.bitlen / NIP_ADDR_BIT_LEN_8); +} + +static inline void _nip_hdr_saddr_encap(struct nip_hdr_encap *head) +{ + (void)build_nip_addr(&head->saddr, (head->hdr_buf + head->hdr_buf_pos)); + head->hdr_buf_pos += (head->saddr.bitlen / NIP_ADDR_BIT_LEN_8); +} + +static inline void _nip_hdr_total_len_encap(struct nip_hdr_encap *head) +{ + head->total_len_pos = (unsigned short *)(head->hdr_buf + head->hdr_buf_pos); + head->hdr_buf_pos += sizeof(head->total_len); +} + +/* total_len must be network order.(big end) */ +void nip_update_total_len(struct nip_hdr_encap *head, unsigned short total_len) +{ + *head->total_len_pos = total_len; +} + +static inline void _nip_hdr_encap_udp_bitmap(struct nip_hdr_encap *head) +{ + /* bitmap(1B) + ttl(1B) + total_len(2B) + nexthdr(1B) + daddr(xB) + saddr(xB) */ + /* If the length of the destination address and the source address is even, + * the length of the packet header must be odd. You need to add 1-byte alignment + * and 1-byte bitmap + */ + if (((head->daddr.bitlen / NIP_ADDR_BIT_LEN_8) + (head->saddr.bitlen / NIP_ADDR_BIT_LEN_8)) + % NIP_BYTE_ALIGNMENT != 0) { + head->hdr_buf[0] = NIP_UDP_BITMAP_1; + head->hdr_buf_pos = 1; + } else { + head->hdr_buf[0] = NIP_UDP_BITMAP_1_INC_2; + head->hdr_buf[1] = NIP_NODATA_BITMAP_2; + head->hdr_buf_pos = 2; + } +} + +static inline void _nip_hdr_encap_comm_bitmap(struct nip_hdr_encap *head) +{ + /* bitmap(1B) + ttl(1B) + nexthdr(1B) + daddr(xB) + saddr(xB) */ + /* If the length of the destination address and the source address is even, + * the length of the packet header must be odd. You need to add 1-byte alignment + * and 1-byte bitmap + */ + if (((head->daddr.bitlen / NIP_ADDR_BIT_LEN_8) + (head->saddr.bitlen / NIP_ADDR_BIT_LEN_8)) + % NIP_BYTE_ALIGNMENT != 0) { + head->hdr_buf[0] = NIP_NORMAL_BITMAP_1; + head->hdr_buf_pos = 1; + } else { + head->hdr_buf[0] = NIP_NORMAL_BITMAP_1_INC_2; + head->hdr_buf[1] = NIP_NODATA_BITMAP_2; + head->hdr_buf_pos = 2; + } +} + +#define NEWIP_BYTE_ALIGNMENT_ENABLE 1 // 0: disable; 1: enable + +void nip_hdr_udp_encap(struct nip_hdr_encap *head) +{ + /* Encapsulate the bitmap into the newIP packet header BUF */ +#if (NEWIP_BYTE_ALIGNMENT_ENABLE == 1) + _nip_hdr_encap_udp_bitmap(head); +#else + head->hdr_buf[0] = NIP_UDP_BITMAP_1; + head->hdr_buf_pos = 1; +#endif + + /* Encapsulate bitmap fields into newIP packet header BUF */ + _nip_hdr_ttl_encap(head); + _nip_hdr_nexthdr_encap(head); + _nip_hdr_daddr_encap(head); + _nip_hdr_saddr_encap(head); +} + +/* need update total len after this func, call nip_update_total_len */ +void nip_hdr_comm_encap(struct nip_hdr_encap *head) +{ + /* Encapsulate the bitmap into the newIP packet header BUF */ +#if (NEWIP_BYTE_ALIGNMENT_ENABLE == 1) + _nip_hdr_encap_comm_bitmap(head); +#else + head->hdr_buf[0] = NIP_NORMAL_BITMAP_1; + head->hdr_buf_pos = 1; +#endif + + /* Encapsulate bitmap fields into newIP packet header BUF */ + _nip_hdr_ttl_encap(head); + _nip_hdr_total_len_encap(head); /* ARP/TCP need include hdr total len */ + _nip_hdr_nexthdr_encap(head); + _nip_hdr_daddr_encap(head); + _nip_hdr_saddr_encap(head); +} + -- Gitee