1/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
2/*
3 * Copyright (c) 2022 Huawei Device Co., Ltd.
4 *
5 * Description: Provide operations and conversions
6 * related to NewIP address.
7 *
8 * Author: Yang Yanjun <yangyanjun@huawei.com>
9 *
10 * Data: 2022-07-18
11 */
12#ifndef _UAPI_NEWIP_ADDR_H
13#define _UAPI_NEWIP_ADDR_H
14
15#define NIP_ADDR_LEN_1 1
16#define NIP_ADDR_LEN_2 2
17#define NIP_ADDR_LEN_3 3
18#define NIP_ADDR_LEN_4 4
19#define NIP_ADDR_LEN_5 5
20#define NIP_ADDR_LEN_7 7
21#define NIP_ADDR_LEN_8 8
22
23#define NIP_ADDR_BIT_LEN_8    8
24#define NIP_ADDR_BIT_LEN_16   16
25#define NIP_ADDR_BIT_LEN_24   24
26#define NIP_ADDR_BIT_LEN_40   40
27#define NIP_ADDR_BIT_LEN_MAX  64
28
29enum nip_addr_check_value {
30	ADDR_FIRST_DC = 0xDC,
31	ADDR_FIRST_F0 = 0xF0,
32	ADDR_FIRST_F1,
33	ADDR_FIRST_F2,
34	ADDR_FIRST_F3,
35	ADDR_FIRST_FE = 0xFE,
36	ADDR_FIRST_FF = 0xFF,
37	ADDR_SECOND_MIN_DD = 0xDD,
38	ADDR_SECOND_MIN_F1 = 0x14,    /* f1 14 00 */
39	ADDR_THIRD_MIN_F2 = 0x01,     /* f2 00 01 00 00 */
40	ADDR_THIRD_MIN_F3 = 0x01,     /* F3 0001 0000 0000 */
41};
42
43enum nip_8bit_addr_index {
44	NIP_8BIT_ADDR_INDEX_0 = 0,
45	NIP_8BIT_ADDR_INDEX_1 = 1,
46	NIP_8BIT_ADDR_INDEX_2 = 2,
47	NIP_8BIT_ADDR_INDEX_3 = 3,
48	NIP_8BIT_ADDR_INDEX_4 = 4,
49	NIP_8BIT_ADDR_INDEX_5 = 5,
50	NIP_8BIT_ADDR_INDEX_6 = 6,
51	NIP_8BIT_ADDR_INDEX_7 = 7,
52	NIP_8BIT_ADDR_INDEX_MAX,
53};
54
55enum nip_16bit_addr_index {
56	NIP_16BIT_ADDR_INDEX_0 = 0,
57	NIP_16BIT_ADDR_INDEX_1 = 1,
58	NIP_16BIT_ADDR_INDEX_2 = 2,
59	NIP_16BIT_ADDR_INDEX_3 = 3,
60	NIP_16BIT_ADDR_INDEX_MAX,
61};
62
63enum nip_32bit_addr_index {
64	NIP_32BIT_ADDR_INDEX_0 = 0,
65	NIP_32BIT_ADDR_INDEX_1 = 1,
66	NIP_32BIT_ADDR_INDEX_MAX,
67};
68
69#define NIP_ADDR_FIELD8 v.u.field8
70#define NIP_ADDR_FIELD16 v.u.field16
71#define NIP_ADDR_FIELD32 v.u.field32
72
73#pragma pack(1)
74struct nip_addr_field {
75	union {
76		unsigned char   field8[NIP_8BIT_ADDR_INDEX_MAX];
77		unsigned short field16[NIP_16BIT_ADDR_INDEX_MAX]; /* big-endian */
78		unsigned int   field32[NIP_32BIT_ADDR_INDEX_MAX]; /* big-endian */
79	} u;
80};
81
82struct nip_addr {
83	unsigned char bitlen; /* The address length is in bit (not byte) */
84	struct nip_addr_field v;
85};
86
87#pragma pack()
88
89enum nip_index {
90	INDEX_0 = 0,
91	INDEX_1 = 1,
92	INDEX_2 = 2,
93	INDEX_3 = 3,
94	INDEX_4 = 4,
95	INDEX_5 = 5,
96	INDEX_6 = 6,
97	INDEX_7 = 7,
98	INDEX_8 = 8,
99	INDEX_9 = 9,
100	INDEX_10 = 10,
101	INDEX_11 = 11,
102	INDEX_12 = 12,
103	INDEX_13 = 13,
104	INDEX_14 = 14,
105	INDEX_15 = 15,
106	INDEX_MAX,
107};
108
109extern const struct nip_addr nip_any_addr;
110extern const struct nip_addr nip_broadcast_addr_arp;
111
112struct nip_buff {
113	unsigned char *data;
114	unsigned int remaining_len;
115};
116
117static inline void nip_buff_pull(struct nip_buff *nbuf, unsigned int len)
118{
119	if (len > nbuf->remaining_len)
120		return;
121
122	nbuf->data += len;
123	nbuf->remaining_len -= len;
124}
125
126int nip_addr_invalid(const struct nip_addr *addr);
127int nip_addr_public(const struct nip_addr *addr);
128int nip_addr_any(const struct nip_addr *addr);
129int get_nip_addr_len(const struct nip_addr *addr);
130unsigned char *build_nip_addr(const struct nip_addr *addr, unsigned char *buf);
131unsigned char *decode_nip_addr(struct nip_buff *nbuf, struct nip_addr *addr);
132int is_nip_local_addr(const struct nip_addr *addr);
133
134#endif /* _UAPI_NEWIP_ADDR_H */
135
136