diff --git a/code/common/nip_addr.h b/code/common/nip_addr.h index 552fd4c875acbbe378625eae95f37c02a9e9faaf..68f8de95cff204863022fcc4ead1afb9cc4d23ed 100644 --- a/code/common/nip_addr.h +++ b/code/common/nip_addr.h @@ -81,24 +81,23 @@ enum nip_32bit_addr_index { NIP_32BIT_ADDR_INDEX_MAX, }; -#define nip_addr_field8 v.u.u8 -#define nip_addr_field16 v.u.u16 -#define nip_addr_field32 v.u.u32 +#define nip_addr_field8 v.u.field8 +#define nip_addr_field16 v.u.field16 +#define nip_addr_field32 v.u.field32 #pragma pack(1) struct nip_addr_field { union { - unsigned char u8[NIP_8BIT_ADDR_INDEX_MAX]; - unsigned short u16[NIP_16BIT_ADDR_INDEX_MAX]; /* big-endian */ - unsigned int u32[NIP_32BIT_ADDR_INDEX_MAX]; /* big-endian */ + unsigned char field8[NIP_8BIT_ADDR_INDEX_MAX]; + unsigned short field16[NIP_16BIT_ADDR_INDEX_MAX]; /* big-endian */ + unsigned int field32[NIP_32BIT_ADDR_INDEX_MAX]; /* big-endian */ } u; }; struct nip_addr { - unsigned char bitlen; + unsigned char bitlen; /* The address length is in bit (not byte) */ struct nip_addr_field v; }; - #pragma pack() enum nip_index { diff --git a/code/linux/net/newip/nip_output.c b/code/linux/net/newip/nip_output.c index a108419f431955253370be9e1a773be5f814305d..d3949379618bf03e944cb9a3d33d698577ada759 100644 --- a/code/linux/net/newip/nip_output.c +++ b/code/linux/net/newip/nip_output.c @@ -460,9 +460,9 @@ void tcp_nip_actual_send_reset(struct sock *sk, struct sk_buff *skb, u32 seq, t1->rst = rst; t1->window = htons(win); t1->check = htons(nip_get_output_checksum_tcp(buff, *saddr, *daddr)); - DEBUG("%s: host dport==%u, net dport==%x, host sport==%u, net sport==0x%x", + DEBUG("%s: host dport=%u, net dport=0x%x, host sport=%u, net sport=0x%x", __func__, ntohs(t1->dest), t1->dest, ntohs(t1->source), t1->source); - DEBUG("%s: host seq==%u, net seq==%x, host ack_seq==%u, net ack_seq==0x%x", + DEBUG("%s: host seq=%u, net seq=0x%x, host ack_seq=%u, net ack_seq=0x%x", __func__, seq, t1->seq, ack_seq, t1->ack_seq); buff->protocol = htons(ETH_P_NEWIP); diff --git a/code/linux/net/newip/route.c b/code/linux/net/newip/route.c index 6fe8365e0a5ea6bfafaf9883719f215455f3b0df..33af9c19fa2c97bb1ffeeee7048d0af28e5c26bc 100644 --- a/code/linux/net/newip/route.c +++ b/code/linux/net/newip/route.c @@ -751,16 +751,20 @@ static int nip_fib_ifdown(struct nip_rt_info *rt, void *arg) { const struct arg_dev_net *adn = arg; const struct net_device *dev = adn->dev; - - if ((rt->dst.dev == dev || !dev) && - rt != adn->net->newip.nip_null_entry && - rt != adn->net->newip.nip_broadcast_entry && - ((dev && netdev_unregistering(dev)) || - !rt->rt_idev->cnf.ignore_routes_with_linkdown)) + bool not_same_dev = (rt->dst.dev == dev || !dev); + bool not_null_entry = (rt != adn->net->newip.nip_null_entry); + bool not_broadcast_entry = (rt != adn->net->newip.nip_broadcast_entry); + bool dev_unregister = (dev && netdev_unregistering(dev)); + bool ignore_route_ifdown = (!rt->rt_idev->cnf.ignore_routes_with_linkdown); + + if (not_same_dev && not_null_entry && not_broadcast_entry && + (dev_unregister || ignore_route_ifdown)) return -1; - DEBUG("%s: don`t del route with %s down, ifindex=%u", - __func__, dev->name, dev->ifindex); + DEBUG("%s: don`t del route with %s down, ifindex=%u, not_same_dev=%u, not_null_entry=%u", + __func__, dev->name, dev->ifindex, not_same_dev, not_null_entry); + DEBUG("%s: not_broadcast_entry=%u, dev_unregister=%u, ignore_route_ifdown=%u", + __func__, not_broadcast_entry, dev_unregister, ignore_route_ifdown); return 0; } diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..395233059debfa57ec929cb02b4796a87fb75864 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2022 Huawei Device Co., Ltd. +# +# +CC=gcc +# CC = aarch64-linux-gnu-gcc +# CC = arm-linux-gnueabi-gcc +CFLAGS=-pthread -static -g + +UT_LIST = nip_addr_cfg_demo nip_route_cfg_demo nip_tcp_server_demo nip_tcp_client_demo nip_udp_server_demo nip_udp_client_demo + +all: $(UT_LIST) + +clean: + rm -f $(UT_LIST) + rm -f nip_lib.o + rm -f libnip_lib.a + + +#lib +NIP_LIB = libnip_lib.a +NIP_DEF_LIB = -L. -lnip_lib + +nip_lib.o: nip_lib.c + $(CC) -c nip_lib.c -o nip_lib.o + +libnip_lib.a: nip_lib.o + ar -rv libnip_lib.a nip_lib.o + +#UT func list +nip_addr_cfg_demo: nip_addr_cfg_demo.c $(NIP_LIB) + $(CC) $(CFLAGS) -o nip_addr_cfg_demo nip_addr_cfg_demo.c $(NIP_DEF_LIB) + +nip_route_cfg_demo: nip_route_cfg_demo.c $(NIP_LIB) + $(CC) $(CFLAGS) -o nip_route_cfg_demo nip_route_cfg_demo.c $(NIP_DEF_LIB) + +nip_tcp_server_demo: nip_tcp_server_demo.c $(NIP_LIB) + $(CC) $(CFLAGS) -o nip_tcp_server_demo nip_tcp_server_demo.c $(NIP_DEF_LIB) + +nip_tcp_client_demo: nip_tcp_client_demo.c $(NIP_LIB) + $(CC) $(CFLAGS) -o nip_tcp_client_demo nip_tcp_client_demo.c $(NIP_DEF_LIB) + +nip_udp_server_demo: nip_udp_server_demo.c $(NIP_LIB) + $(CC) $(CFLAGS) -o nip_udp_server_demo nip_udp_server_demo.c $(NIP_DEF_LIB) + +nip_udp_client_demo: nip_udp_client_demo.c $(NIP_LIB) + $(CC) $(CFLAGS) -o nip_udp_client_demo nip_udp_client_demo.c $(NIP_DEF_LIB) diff --git a/examples/newip_route.h b/examples/newip_route.h new file mode 100644 index 0000000000000000000000000000000000000000..b1f6118de6e4871678b291b65bd8dc5c4e38c7aa --- /dev/null +++ b/examples/newip_route.h @@ -0,0 +1,44 @@ +/* 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_ROUTE_H +#define _NEWIP_ROUTE_H + +#include "nip.h" + +struct nip_rtmsg { + struct nip_addr rtmsg_dst; + struct nip_addr rtmsg_src; + struct nip_addr rtmsg_gateway; + char dev_name[10]; + unsigned int rtmsg_type; + int rtmsg_ifindex; + unsigned int rtmsg_metric; + unsigned long rtmsg_info; + unsigned int rtmsg_flags; +}; + +#endif /* _NEWIP_ROUTE_H */ diff --git a/examples/nip.h b/examples/nip.h new file mode 100644 index 0000000000000000000000000000000000000000..2dff0395384805a9ca01b45ab09995d33309817c --- /dev/null +++ b/examples/nip.h @@ -0,0 +1,109 @@ +/* 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 _NIP_H +#define _NIP_H + +#define NIP_ADDR_LEN_1 1 +#define NIP_ADDR_LEN_2 2 +#define NIP_ADDR_LEN_3 3 +#define NIP_ADDR_LEN_4 4 +#define NIP_ADDR_LEN_5 5 +#define NIP_ADDR_LEN_7 7 +#define NIP_ADDR_LEN_8 8 + +#define NIP_ADDR_BIT_LEN_8 8 +#define NIP_ADDR_BIT_LEN_16 16 +#define NIP_ADDR_BIT_LEN_24 24 +#define NIP_ADDR_BIT_LEN_40 40 +#define NIP_ADDR_BIT_LEN_MAX 64 + +enum nip_8bit_addr_index { + NIP_8BIT_ADDR_INDEX_0 = 0, + NIP_8BIT_ADDR_INDEX_1 = 1, + NIP_8BIT_ADDR_INDEX_2 = 2, + NIP_8BIT_ADDR_INDEX_3 = 3, + NIP_8BIT_ADDR_INDEX_4 = 4, + NIP_8BIT_ADDR_INDEX_5 = 5, + NIP_8BIT_ADDR_INDEX_6 = 6, + NIP_8BIT_ADDR_INDEX_7 = 7, + NIP_8BIT_ADDR_INDEX_MAX, +}; + +enum nip_16bit_addr_index { + NIP_16BIT_ADDR_INDEX_0 = 0, + NIP_16BIT_ADDR_INDEX_1 = 1, + NIP_16BIT_ADDR_INDEX_2 = 2, + NIP_16BIT_ADDR_INDEX_3 = 3, + NIP_16BIT_ADDR_INDEX_MAX, +}; + +enum nip_32bit_addr_index { + NIP_32BIT_ADDR_INDEX_0 = 0, + NIP_32BIT_ADDR_INDEX_1 = 1, + NIP_32BIT_ADDR_INDEX_MAX, +}; + +#define nip_addr_field8 v.u.field8 +#define nip_addr_field16 v.u.field16 +#define nip_addr_field32 v.u.field32 + +#pragma pack(1) +struct nip_addr_field { + union { + unsigned char field8[NIP_8BIT_ADDR_INDEX_MAX]; + unsigned short field16[NIP_16BIT_ADDR_INDEX_MAX]; /* big-endian */ + unsigned int field32[NIP_32BIT_ADDR_INDEX_MAX]; /* big-endian */ + } u; +}; + +struct nip_addr { + unsigned char bitlen; /* The address length is in bit (not byte) */ + struct nip_addr_field v; +}; +#pragma pack() + +enum nip_index { + INDEX_0 = 0, + INDEX_1 = 1, + INDEX_2 = 2, + INDEX_3 = 3, + INDEX_4 = 4, + INDEX_5 = 5, + INDEX_6 = 6, + INDEX_7 = 7, + INDEX_8 = 8, + INDEX_9 = 9, + INDEX_10 = 10, + INDEX_11 = 11, + INDEX_12 = 12, + INDEX_13 = 13, + INDEX_14 = 14, + INDEX_15 = 15, + INDEX_MAX, +}; + +#endif /*_NIP_H*/ diff --git a/examples/nip_addr_cfg_demo.c b/examples/nip_addr_cfg_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..7d2c3106c86a1b69f3455e1461a646b0852bca4e --- /dev/null +++ b/examples/nip_addr_cfg_demo.c @@ -0,0 +1,111 @@ +// 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 +#include +#include +#include +#include +#include +#include + +#include "nip_uapi.h" +#include "nip_lib.h" + +/* get ifindex based on the device name + * struct ifreq ifr; + * struct nip_ifreq ifrn; + * ioctl(fd, SIOGIFINDEX, &ifr); + * ifr.ifr_ifindex; ===> ifindex + */ +int32_t nip_add_addr(int32_t ifindex, const unsigned char *addr, uint8_t addr_len) +{ + int fd, ret; + struct nip_ifreq ifrn; + + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) + return -1; + + memset(&ifrn, 0, sizeof(ifrn)); + ifrn.ifrn_addr.bitlen = addr_len * 8; // Byte length is converted to bit length + memcpy(ifrn.ifrn_addr.nip_addr_field8, addr, addr_len); + ifrn.ifrn_ifindex = ifindex; + + ret = ioctl(fd, SIOCSIFADDR, &ifrn); + if (ret < 0 && errno != EEXIST) { // ignore File Exists error + printf("cfg newip addr fail, ifindex=%d, ret=%d.\n", ifindex, ret); + close(fd); + return -1; + } + + close(fd); + return 0; +} + +/* Before executing the use case, run ifconfig XXX up. + * XXX indicates the NIC name, for example, eth0 and wlan0 + */ +int main(int argc, char **argv) +{ + int ret; + int ifindex = 0; + uint8_t client_addr[INDEX_1] = {0x50}; // 1-byte address of the client: 0x50 + uint8_t server_addr[INDEX_2] = {0xDE, 0x00}; // 2-byte address of the server: 0xDE00 + uint8_t *addr; + uint8_t addr_len; + + if (argc == DEMO_INPUT_1) { + if (!strcmp(*(argv + 1), "server")) { + printf("server cfg addr=0x%02x%02x.\n", + server_addr[INDEX_0], server_addr[INDEX_1]); + addr = server_addr; + addr_len = sizeof(server_addr); + } else if (!strcmp(*(argv + 1), "client")) { + printf("client cfg addr=0x%x02x.\n", client_addr[INDEX_0]); + addr = client_addr; + addr_len = sizeof(client_addr); + } else { + printf("invalid addr cfg input.\n"); + return -1; + } + } else { + printf("unsupport addr cfg input.\n"); + return -1; + } + + ret = nip_get_ifindex(NIC_NAME, &ifindex); + if (ret != 0) + return -1; + + ret = nip_add_addr(ifindex, addr, addr_len); + if (ret != 0) + return -1; + + printf("%s %s(ifindex=%u) cfg addr success.\n", *argv, NIC_NAME, ifindex); + return 0; +} + diff --git a/examples/nip_lib.c b/examples/nip_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..b6a8c7dd23e7a96f0c443de7fbb10558410f0fc2 --- /dev/null +++ b/examples/nip_lib.c @@ -0,0 +1,61 @@ +// 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 +#include +#include +#include +#include +#include +#include /* struct ifreq depend */ + +#include "nip_uapi.h" +#include "nip_lib.h" + +int32_t nip_get_ifindex(const char *ifname, int *ifindex) +{ + int fd; + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ifname); + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) { + printf("creat socket fail, ifname=%s\n", ifname); + return -1; + } + if ((ioctl(fd, SIOCGIFINDEX, &ifr)) < 0) { + printf("get ifindex fail, ifname=%s\n", ifname); + close(fd); + return -1; + } + close(fd); + + printf("%s ifindex=%u\n", ifname, ifr.ifr_ifindex); + *ifindex = ifr.ifr_ifindex; + return 0; +} + diff --git a/examples/nip_lib.h b/examples/nip_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..d52e5f86bbb7a66dc32a93df732cf2d6b922b364 --- /dev/null +++ b/examples/nip_lib.h @@ -0,0 +1,44 @@ +/* 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 _NIP_LIB_H +#define _NIP_LIB_H + +/* Eth0 and wlan0 are optional. Change the value based on the actual interface */ +#define NIC_NAME "eth0" + +#define BUFLEN 2048 +#define LISTEN_MAX 3 +#define PKTCNT 10 // Number of sent packets +#define PKTLEN 1024 // Length of sent packet +#define SLEEP_US 500000 // Packet sending interval (ms) +#define SELECT_TIME 600 +#define TCP_SERVER_PORT 5556 // TCP Server Port +#define UDP_SERVER_PORT 9090 // UDP Server Port + +int nip_get_ifindex(const char *ifname, int *ifindex); + +#endif /* _NIP_LIB_H */ diff --git a/examples/nip_route_cfg_demo.c b/examples/nip_route_cfg_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..5ed1bd1547e90490cd7015267c5a0e4f8031aec3 --- /dev/null +++ b/examples/nip_route_cfg_demo.c @@ -0,0 +1,123 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include + +#include "nip_uapi.h" +#include "nip_lib.h" +#include "newip_route.h" + +/* get ifindex based on the device name + * struct ifreq ifr; + * struct nip_ifreq ifrn; + * ioctl(fd, SIOGIFINDEX, &ifr); + * ifr.ifr_ifindex; ===> ifindex + */ +int nip_route_add(int ifindex, const unsigned char *dst_addr, uint8_t dst_addr_len, + const unsigned char *gateway_addr, uint8_t gateway_addr_len) +{ + int fd, ret; + struct nip_rtmsg rt; + + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) + return -1; + + memset(&rt, 0, sizeof(rt)); + rt.rtmsg_ifindex = ifindex; + rt.rtmsg_flags = RTF_UP; + rt.rtmsg_dst.bitlen = dst_addr_len * 8; + memcpy(rt.rtmsg_dst.nip_addr_field8, dst_addr, dst_addr_len); + + if (gateway_addr) { + rt.rtmsg_gateway.bitlen = gateway_addr_len * 8; + memcpy(rt.rtmsg_gateway.nip_addr_field8, gateway_addr, gateway_addr_len); + rt.rtmsg_flags |= RTF_GATEWAY; + } + + ret = ioctl(fd, SIOCADDRT, &rt); + if (ret < 0 && errno != EEXIST) { // ignore File Exists error + close(fd); + return -1; + } + + close(fd); + return 0; +} + +int main(int argc, char **argv) +{ + int ret; + int ifindex = 0; + uint8_t client_addr[INDEX_1] = {0x50}; // 1-byte address of the client: 0x50 + uint8_t server_addr[INDEX_2] = {0xDE, 0x00}; // 2-byte address of the server: 0xDE00 + uint8_t *dst_addr; + uint8_t dst_addr_len; + uint8_t *gateway_addr; + uint8_t gateway_addr_len; + + if (argc == DEMO_INPUT_1) { + if (!strcmp(*(argv + 1), "server")) { + printf("server cfg route, dst-addr=0x%x02.\n", client_addr[INDEX_0]); + dst_addr = client_addr; + dst_addr_len = 1; + } else if (!strcmp(*(argv + 1), "client")) { + printf("client cfg route, dst-addr=0x%02x%02x.\n", + server_addr[INDEX_0], server_addr[INDEX_1]); + dst_addr = server_addr; + dst_addr_len = 2; + } else { + printf("invalid route cfg input.\n"); + return -1; + } + } else { + printf("unsupport route cfg input.\n"); + return -1; + } + + ret = nip_get_ifindex(NIC_NAME, &ifindex); + if (ret != 0) { + printf("get %s ifindex fail, ret=%d.\n", NIC_NAME, ret); + return -1; + } + + ret = nip_route_add(ifindex, dst_addr, dst_addr_len, NULL, 0); + if (ret != 0) { + printf("get %s ifindex fail, ret=%d.\n", NIC_NAME, ret); + return -1; + } + + printf("%s %s(ifindex=%u) cfg route success.\n", *argv, NIC_NAME, ifindex); + return 0; +} + diff --git a/examples/nip_tcp_client_demo.c b/examples/nip_tcp_client_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..5344e2bbd28053ee59ad49cfe40cdebac02df5fa --- /dev/null +++ b/examples/nip_tcp_client_demo.c @@ -0,0 +1,137 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nip_uapi.h" +#include "nip_lib.h" +#include "newip_route.h" + +#define __USE_GNU +#include +#include + +void *send_recv(void *args) +{ + char buf[BUFLEN]; + int cfd, ret; + int sendtime_sec, sendtime_usec; + int success = 0; + int count = 0; + int no = 0; + fd_set readfds; + struct timeval tv, stTime; + struct thread_args *th_args = (struct thread_args *) args; + struct sockaddr_nin si_server = th_args->si_server; + + cfd = th_args->cfd; + for (int i = 0; i < PKTCNT; i++) { + memset(buf, 0, BUFLEN); + (void)gettimeofday(&stTime, NULL); + sprintf(buf, "%ld %6ld NIP_TCP # %6d", stTime.tv_sec, stTime.tv_usec, count); + if (send(cfd, buf, PKTLEN, 0) < 0) { + perror("send"); + goto END; + } + + FD_ZERO(&readfds); + FD_SET(cfd, &readfds); + tv.tv_sec = SELECT_TIME; + tv.tv_usec = 0; + if (select(cfd + 1, &readfds, NULL, NULL, &tv) < 0) { + perror("select"); + goto END; + } + + if (FD_ISSET(cfd, &readfds)) { + memset(buf, 0, BUFLEN); + ret = recv(cfd, buf, PKTLEN, MSG_WAITALL); + if (ret > 0) { + success += 1; + (void)gettimeofday(&stTime, NULL); + ret = sscanf(buf, "%d %d NIP_TCP # %d", + &sendtime_sec, &sendtime_usec, &no); + printf("Received --%s sock %d success:%6d/%6d/no=%6d\n", + buf, cfd, success, count + 1, no); + } else { + printf("recv fail, ret=%d\n", ret); + goto END; + } + } + count += 1; + usleep(SLEEP_US); + } + +END: return NULL; +} + +int main(int argc, char **argv) +{ + int cfd; + pthread_t th; + struct thread_args th_args; + struct sockaddr_nin si_server; + + cfd = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); + if (cfd < 0) { + perror("socket"); + return -1; + } + printf("creat newip socket, fd=%d\n", cfd); + + memset((char *)&si_server, 0, sizeof(si_server)); + si_server.sin_family = AF_NINET; + si_server.sin_port = htons(TCP_SERVER_PORT); + // 2-byte address of the server: 0xDE00 + si_server.sin_addr.nip_addr_field8[INDEX_0] = 0xDE; + si_server.sin_addr.nip_addr_field8[INDEX_1] = 0x00; + si_server.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit + if (connect(cfd, (struct sockaddr *)&si_server, sizeof(si_server)) < 0) { + perror("connect"); + return -1; + } + printf("connect success, addr=0x%02x%02x, port=%u\n", + si_server.sin_addr.nip_addr_field8[INDEX_0], + si_server.sin_addr.nip_addr_field8[INDEX_1], TCP_SERVER_PORT); + + th_args.si_server = si_server; + th_args.si_server.sin_port = htons(TCP_SERVER_PORT); + th_args.cfd = cfd; + pthread_create(&th, NULL, send_recv, &th_args); + /* Wait for the thread to end and synchronize operations between threads */ + pthread_join(th, NULL); + close(cfd); + return 0; +} + diff --git a/examples/nip_tcp_server_demo.c b/examples/nip_tcp_server_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..f0ef1961a8bcdf336cf57294353e84f339f7a3cd --- /dev/null +++ b/examples/nip_tcp_server_demo.c @@ -0,0 +1,112 @@ +// 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 +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip_uapi.h" +#include "nip_lib.h" +#include "newip_route.h" + +void *recv_send(void *args) +{ + char buf[BUFLEN] = {0}; + int cfd, ret; + + memcpy(&cfd, args, sizeof(int)); + for (int i = 0; i < PKTCNT; i++) { + int recv_num = recv(cfd, buf, PKTLEN, MSG_WAITALL); + + if (recv_num < 0) { + perror("recv"); + goto END; + } else if (recv_num == 0) { /* no data */ + ; + } else { + printf("Received -- %s --:%d\n", buf, recv_num); + ret = send(cfd, buf, recv_num, 0); + if (ret < 0) { + perror("send"); + goto END; + } + printf("Sending -- %s --:%d\n", buf, recv_num); + } + } +END: close(cfd); + return NULL; +} + +int main(int argc, char **argv) +{ + pthread_t th; + int fd, cfd, addr_len; + struct sockaddr_nin si_local; + struct sockaddr_nin si_remote; + + fd = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) { + perror("socket"); + return -1; + } + + memset((char *)&si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_NINET; + si_local.sin_port = htons(TCP_SERVER_PORT); + // 2-byte address of the server: 0xDE00 + si_local.sin_addr.nip_addr_field8[INDEX_0] = 0xDE; + si_local.sin_addr.nip_addr_field8[INDEX_1] = 0x00; + si_local.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit + + if (bind(fd, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { + perror("bind"); + goto END; + } + printf("bind success, addr=0x%02x%02x, port=%u\n", + si_local.sin_addr.nip_addr_field8[INDEX_0], + si_local.sin_addr.nip_addr_field8[INDEX_1], TCP_SERVER_PORT); + + if (listen(fd, LISTEN_MAX) < 0) { + perror("listen"); + goto END; + } + + addr_len = sizeof(si_remote); + memset(&si_remote, 0, sizeof(si_remote)); + cfd = accept(fd, (struct sockaddr *)&si_remote, (socklen_t *)&addr_len); + pthread_create(&th, NULL, recv_send, &cfd); + /* Wait for the thread to end and synchronize operations between threads */ + pthread_join(th, NULL); +END: close(fd); + return 0; +} + diff --git a/examples/nip_uapi.h b/examples/nip_uapi.h new file mode 100644 index 0000000000000000000000000000000000000000..6475ff3a614b7d2a7e895a8919a716ae65f58ff0 --- /dev/null +++ b/examples/nip_uapi.h @@ -0,0 +1,61 @@ +/* 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 _NIP_UAPI_H +#define _NIP_UAPI_H + +#include "nip.h" + +/* AF_NINET by reading/sys/module/newip/parameters/AF_NINET file to get the type value */ +#define PF_NINET 45 +#define AF_NINET PF_NINET + +#define DEMO_INPUT_1 2 // The DEMO program contains one parameter + +/* The following structure must be larger than V4. System calls use V4. + * If the definition is smaller than V4, the read process will have memory overruns + * v4: include\linux\socket.h --> sockaddr (16Byte) + */ +#define POD_SOCKADDR_SIZE 3 +struct sockaddr_nin { + unsigned short sin_family; /* [2Byte] AF_NINET */ + unsigned short sin_port; /* [2Byte] Transport layer port, big-endian */ + struct nip_addr sin_addr; /* [9Byte] NIP address */ + + unsigned char sin_zero[POD_SOCKADDR_SIZE]; /* [3Byte] Byte alignment */ +}; + +struct nip_ifreq { + struct nip_addr ifrn_addr; + int ifrn_ifindex; +}; + +struct thread_args { + int cfd; + struct sockaddr_nin si_server; +}; + +#endif /*_NIP_UAPI_H*/ diff --git a/examples/nip_udp_client_demo.c b/examples/nip_udp_client_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..7bd6d30a4c5fa5e6c1379a647e55b81b7b40349c --- /dev/null +++ b/examples/nip_udp_client_demo.c @@ -0,0 +1,131 @@ +// 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 +#include +#include +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip_uapi.h" +#include "nip_lib.h" +#include "newip_route.h" + +void *send_recv(void *args) +{ + char buf[BUFLEN]; + int cfd, ret; + fd_set readfds; + int success = 0; + int count = 0; + int no = 0; + int sendtime_sec, sendtime_usec; + struct timeval tv; + struct timeval stTime; + struct thread_args *th_args = (struct thread_args *)args; + struct sockaddr_nin si_server = th_args->si_server; + + cfd = th_args->cfd; + while (count < PKTCNT) { + socklen_t slen = sizeof(si_server); + + memset(buf, 0, BUFLEN); + gettimeofday(&stTime, NULL); + sprintf(buf, "%ld %6ld NIP_UDP # %6d", stTime.tv_sec, stTime.tv_usec, count); + + if (sendto(cfd, buf, BUFLEN, 0, (struct sockaddr *)&si_server, slen) < 0) { + perror("sendto"); + goto END; + } + + FD_ZERO(&readfds); + FD_SET(cfd, &readfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + if (select(cfd + 1, &readfds, NULL, NULL, &tv) < 0) { + perror("select"); + goto END; + } + + if (FD_ISSET(cfd, &readfds)) { + memset(buf, 0, BUFLEN); + ret = recvfrom(cfd, buf, BUFLEN, 0, (struct sockaddr *)&si_server, &slen); + if (ret > 0) { + success += 1; + (void)gettimeofday(&stTime, NULL); + ret = sscanf(buf, "%d %d NIP_UDP # %d", &sendtime_sec, + &sendtime_usec, &no); + printf("Received --%s sock %d success:%6d/%6d/no=%6d\n", + buf, cfd, success, count + 1, no); + } else { + printf("recv fail, ret=%d\n", ret); + goto END; + } + } + count += 1; + usleep(SLEEP_US); + } + +END: return NULL; +} + +int main(int argc, char **argv) +{ + int cfd; + pthread_t th; + struct thread_args th_args; + struct sockaddr_nin si_server; + + cfd = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP); + if (cfd < 0) { + perror("socket"); + return -1; + } + + memset((char *)&si_server, 0, sizeof(si_server)); + si_server.sin_family = AF_NINET; + si_server.sin_port = htons(UDP_SERVER_PORT); + // 2-byte address of the server: 0xDE00 + si_server.sin_addr.nip_addr_field8[INDEX_0] = 0xDE; + si_server.sin_addr.nip_addr_field8[INDEX_1] = 0x00; + si_server.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit + + th_args.si_server = si_server; + th_args.si_server.sin_port = htons(UDP_SERVER_PORT); + th_args.cfd = cfd; + pthread_create(&th, NULL, send_recv, &th_args); + /* Wait for the thread to end and synchronize operations between threads */ + pthread_join(th, NULL); + close(cfd); + return 0; +} + diff --git a/examples/nip_udp_server_demo.c b/examples/nip_udp_server_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..612b3e8e3f8cec4dfbd1eb7da344611fa7f761c5 --- /dev/null +++ b/examples/nip_udp_server_demo.c @@ -0,0 +1,115 @@ +// 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 +#include +#include +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip_uapi.h" +#include "nip_lib.h" +#include "newip_route.h" + +void *recv_send(void *args) +{ + char buf[BUFLEN] = {0}; + int fd, ret, recv_num; + int count = 0; + socklen_t slen; + struct sockaddr_nin si_local, si_remote; + + memcpy(&fd, args, sizeof(int)); + while (count < PKTCNT) { + slen = sizeof(si_remote); + memset(buf, 0, sizeof(char) * BUFLEN); + memset(&si_remote, 0, sizeof(si_remote)); + recv_num = recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, &slen); + if (recv_num < 0) { + perror("recvfrom"); + goto END; + } else if (recv_num == 0) { /* no data */ + ; + } else { + printf("Received -- %s -- from 0x%x:%d\n", buf, + si_remote.sin_addr.nip_addr_field16[0], ntohs(si_remote.sin_port)); + slen = sizeof(si_remote); + ret = sendto(fd, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, slen); + if (ret < 0) { + perror("sendto"); + goto END; + } + printf("Sending -- %s -- to 0x%0x:%d\n", buf, + si_remote.sin_addr.nip_addr_field8[0], ntohs(si_remote.sin_port)); + } + count++; + } +END: return NULL; +} + +int main(int argc, char **argv) +{ + int fd; + pthread_t th; + struct sockaddr_nin si_local; + + fd = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) { + perror("socket"); + return -1; + } + + memset((char *)&si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_NINET; + si_local.sin_port = htons(UDP_SERVER_PORT); + // 2-byte address of the server: 0xDE00 + si_local.sin_addr.nip_addr_field8[INDEX_0] = 0xDE; + si_local.sin_addr.nip_addr_field8[INDEX_1] = 0x00; + si_local.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit + + if (bind(fd, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { + perror("bind"); + goto END; + } + + printf("bind success, addr=0x%02x%02x, port=%u\n", + si_local.sin_addr.nip_addr_field8[INDEX_0], + si_local.sin_addr.nip_addr_field8[INDEX_1], UDP_SERVER_PORT); + + pthread_create(&th, NULL, recv_send, &fd); + /* Wait for the thread to end and synchronize operations between threads */ + pthread_join(th, NULL); + +END: close(fd); + return 0; +} +