From 98fe373f1b38b4176139e24435e93cce28ed2a67 Mon Sep 17 00:00:00 2001 From: yangyanjun Date: Thu, 1 Sep 2022 16:39:53 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0newip=20demo=E6=A0=B7?= =?UTF-8?q?=E4=BE=8B=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangyanjun --- examples/Makefile | 49 ++++++++++++++ examples/newip_route.h | 37 ++++++++++ examples/nip.h | 64 ++++++++++++++++++ examples/nip_addr_cfg_demo.c | 97 +++++++++++++++++++++++++++ examples/nip_api.c | 69 +++++++++++++++++++ examples/nip_api.h | 17 +++++ examples/nip_route_cfg_demo.c | 105 +++++++++++++++++++++++++++++ examples/nip_tcp_client_demo.c | 119 +++++++++++++++++++++++++++++++++ examples/nip_tcp_server_demo.c | 93 ++++++++++++++++++++++++++ examples/nip_udp_client_demo.c | 110 ++++++++++++++++++++++++++++++ examples/nip_udp_server_demo.c | 72 ++++++++++++++++++++ 11 files changed, 832 insertions(+) create mode 100644 examples/Makefile create mode 100644 examples/newip_route.h create mode 100644 examples/nip.h create mode 100644 examples/nip_addr_cfg_demo.c create mode 100644 examples/nip_api.c create mode 100644 examples/nip_api.h create mode 100644 examples/nip_route_cfg_demo.c create mode 100644 examples/nip_tcp_client_demo.c create mode 100644 examples/nip_tcp_server_demo.c create mode 100644 examples/nip_udp_client_demo.c create mode 100644 examples/nip_udp_server_demo.c diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..8f90266 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (c) 2022 Huawei Device Co., Ltd. +# +# Makefile for the Linux newip layer +# +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_api.o + rm -f libnip_api.a + + +#lib +NIP_LIB = libnip_api.a +NIP_DEF_LIB = -L. -lnip_api + +nip_api.o: nip_api.c + $(CC) -c nip_api.c -o nip_api.o + +libnip_api.a: nip_api.o + ar -rv libnip_api.a nip_api.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 0000000..d8b850a --- /dev/null +++ b/examples/newip_route.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * Based on include/uapi/linux/ipv6_route.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _NEWIP_ROUTE_H +#define _NEWIP_ROUTE_H + +#include "nip.h" + +struct nip_arpmsg { + struct nip_addr dst_addr; + char ifrn_name[10]; + __u8 lladdr[10]; +}; + +struct nip_rtmsg { + struct nip_addr rtmsg_dst; + struct nip_addr rtmsg_src; + struct nip_addr rtmsg_gateway; + char dev_name[10]; + __u32 rtmsg_type; + int rtmsg_ifindex; + __u32 rtmsg_metric; + unsigned long rtmsg_info; + __u32 rtmsg_flags; +}; + +#endif /* _NEWIP_ROUTE_H */ diff --git a/examples/nip.h b/examples/nip.h new file mode 100644 index 0000000..e9ea37a --- /dev/null +++ b/examples/nip.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _NIP_H +#define _NIP_H + +#include + +// AF_NINET可通过读取 /sys/module/newip/parameters/af_ninet 文件来获取类型数值。 +#define PF_NINET 45 +#define AF_NINET PF_NINET + +#define NIP_BITLEN_MAX 64 + +#define nip_addr_field8 v.u.u8 +#define nip_addr_field16 v.u.u16 +#define nip_addr_field32 v.u.u32 + +/* New IP address field */ +#pragma pack(1) +struct nip_addr_field { + union { + __u8 u8[8]; + __be16 u16[4]; + __be32 u32[2]; + } u; +}; +#pragma pack() + +/* New IP topology address structure */ +#pragma pack(1) +struct nip_addr { + uint8_t bitlen; // address bitlength + struct nip_addr_field v; +}; +#pragma pack() + +/* 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; +}; + +#endif /*_NIP_H*/ diff --git a/examples/nip_addr_cfg_demo.c b/examples/nip_addr_cfg_demo.c new file mode 100644 index 0000000..7645f91 --- /dev/null +++ b/examples/nip_addr_cfg_demo.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include + +#include "nip.h" +#include "nip_api.h" + +/* 基于设备名字获取ifindex + * 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) +{ + int32_t sockfd, ret; + struct nip_ifreq ifrn; + + sockfd = socket(AF_NINET, SOCK_DGRAM, 0); + if (sockfd < 0) { + return -1; + } + + memset(&ifrn, 0, sizeof(ifrn)); + ifrn.ifrn_addr.bitlen = addr_len * 8; // 字节长度转换成bit长度 + memcpy(ifrn.ifrn_addr.nip_addr_field8, addr, addr_len); + ifrn.ifrn_ifindex = ifindex; + + ret = ioctl(sockfd, SIOCSIFADDR, &ifrn); + if (ret < 0 && errno != EEXIST) { // ignore File Exists error + printf("cfg newip addr fail, ifindex=%d, ret=%d.\n", ifindex, ret); + close(sockfd); + return -1; + } + + close(sockfd); + return 0; +} + +/* 执行用例前先执行ifconfig xxx up,xxx表示网卡名,比如eth0,wlan0 */ +int main(int argc, char **argv) +{ + int ret; + int32_t ifindex = 0; + const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 + uint8_t client_addr[1] = {0x50}; // 客户端1字节地址: 0x50 + uint8_t server_addr[2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 + uint8_t *addr; + uint8_t addr_len; + + if (argc == 2) { + if (!strcmp(*(argv + 1), "server")) { + printf("server cfg addr=0x%02x%02x.\n", server_addr[0], server_addr[1]); + addr = server_addr; + addr_len = 2; + } else if (!strcmp(*(argv + 1), "client")) { + printf("client cfg addr=0x%x02x.\n", client_addr[0]); + addr = client_addr; + addr_len = 1; + } else { + printf("invalid addr cfg input.\n"); + return -1; + } + } else { + printf("unsupport addr cfg input.\n"); + return -1; + } + + ret = set_netcard_up(ifname); + if (ret != 0) { + return -1; + } + + ret = nip_get_ifindex(ifname, &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, ifname, ifindex); + return 0; +} + diff --git a/examples/nip_api.c b/examples/nip_api.c new file mode 100644 index 0000000..7f2c5e9 --- /dev/null +++ b/examples/nip_api.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include + +#include "nip.h" +#include "nip_api.h" + +int32_t nip_get_ifindex(const char *ifname, int32_t *ifindex) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ifname); + int 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; +} + +int32_t set_netcard_up(const char *ifname) +{ + int32_t fd; + struct ifreq ifr; + + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) { + return -1; + } + + strcpy(ifr.ifr_name, ifname); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + printf("get %s flag fail.", ifname); + close(fd); + return -1; + } + + strcpy(ifr.ifr_name, ifname); + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + printf("set %s up fail.", ifname); + close(fd); + return -1; + } + + printf("set %s up success.", ifname); + close(fd); + return 0; +} + diff --git a/examples/nip_api.h b/examples/nip_api.h new file mode 100644 index 0000000..2dab3f2 --- /dev/null +++ b/examples/nip_api.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _NIP_API_H +#define _NIP_API_H + +int32_t nip_get_ifindex(const char *ifname, int32_t *ifindex); + +#endif /* _NIP_API_H */ diff --git a/examples/nip_route_cfg_demo.c b/examples/nip_route_cfg_demo.c new file mode 100644 index 0000000..3dbebf7 --- /dev/null +++ b/examples/nip_route_cfg_demo.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nip.h" +#include "newip_route.h" +#include "nip_api.h" + +/* 基于设备名字获取ifindex + * struct ifreq ifr; + * struct nip_ifreq ifrn; + * ioctl(fd, SIOGIFINDEX, &ifr); + * ifr.ifr_ifindex; ===> 函数入参 ifindex + */ +int32_t nip_route_add(int32_t ifindex, const unsigned char *dst_addr, uint8_t dst_addr_len, + const unsigned char *gateway_addr, uint8_t gateway_addr_len) +{ + int32_t sockfd, ret; + struct nip_rtmsg rt; + + sockfd = socket(AF_NINET, SOCK_DGRAM, 0); + if (sockfd < 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(sockfd, SIOCADDRT, &rt); + if (ret < 0 && errno != EEXIST) { // ignore File Exists error + close(sockfd); + return -1; + } + + close(sockfd); + return 0; +} + +/* 执行用例前先执行ifconfig xxx up,xxx表示网卡名,比如eth0,wlan0 */ +int main(int argc, char **argv) +{ + int ret; + int32_t ifindex = 0; + const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 + uint8_t client_addr[1] = {0x50}; // 客户端1字节地址: 0x50 + uint8_t server_addr[2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 + uint8_t *dst_addr; + uint8_t dst_addr_len; + uint8_t *gateway_addr; + uint8_t gateway_addr_len; + + if (argc == 2) { + if (!strcmp(*(argv + 1), "server")) { + printf("server cfg route, dst-addr=0x%x02.\n", client_addr[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[0], server_addr[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(ifname, &ifindex); + if (ret != 0) { + printf("get %s ifindex fail, ret=%d.\n", ifname, 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", ifname, ret); + return -1; + } + + printf("%s %s(ifindex=%u) cfg route success.\n", *argv, ifname, ifindex); + return 0; +} + diff --git a/examples/nip_tcp_client_demo.c b/examples/nip_tcp_client_demo.c new file mode 100644 index 0000000..dece6d0 --- /dev/null +++ b/examples/nip_tcp_client_demo.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nip.h" +#include "newip_route.h" + +#define __USE_GNU +#include +#include + +#define BUFLEN 4096 + +int g_pktcnt = 10; // 发送报文个数 +int g_pktlen = 1024; // 发送报文长度 +int g_pktinterval = 500; // 发包间隔(ms) +int g_port = 5556; // 服务端端口 + +typedef struct { + int s; + struct sockaddr_nin si_server; +} thread_args; + +void *send_recv(void *args) +{ + char buf[BUFLEN]; + fd_set readfds; + struct timeval tv, stTime; + int sendtime_sec, sendtime_usec; + int success = 0; + int count = 0; + int no = 0; + thread_args *th_args = (thread_args *) args; + int s = th_args->s; + struct sockaddr_nin si_server = th_args->si_server; + + for (int i; i < g_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(s, buf, g_pktlen, 0) < 0) { + perror("send"); + } + + FD_ZERO(&readfds); + FD_SET(s, &readfds); + tv.tv_sec = 600; + tv.tv_usec = 0; + if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) { + perror("select"); + } + + if (FD_ISSET(s, &readfds)) { + memset(buf, 0, BUFLEN); + int ret = recv(s, buf, g_pktlen, MSG_WAITALL); + if (ret > 0) { + success += 1; + (void)gettimeofday(&stTime, NULL); + sscanf(buf, "%d %d NIP_TCP # %d", &sendtime_sec, &sendtime_usec, &no); + printf("Received --%s sock %d success:%6d/%6d/no=%6d\n", + buf, s, success, count + 1, no); + } else { + printf("recv fail, ret=%d\n", ret); + } + } + count += 1; + usleep(g_pktinterval * 1000); + } + close(s); +} + +int main(int argc, char **argv) +{ + int s; + pthread_t th; + thread_args th_args; + struct sockaddr_nin si_server; + + if ((s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + printf("errno=%d\n", errno); + return -1; + } + printf("creat newip socket, fd=%d\n", s); + + memset((char *)&si_server, 0, sizeof(si_server)); + si_server.sin_family = AF_NINET; + si_server.sin_port = htons(g_port); + // 服务端2字节地址: 0xDE00 + si_server.sin_addr.nip_addr_field8[0] = 0xDE; + si_server.sin_addr.nip_addr_field8[1] = 0x00; + si_server.sin_addr.bitlen = 16; // 2字节:16bit + if (connect(s, (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[0], si_server.sin_addr.nip_addr_field8[1], g_port); + + th_args.si_server = si_server; + th_args.si_server.sin_port = htons(g_port); + th_args.s = s; + pthread_create(&th, NULL, send_recv, &th_args); + pthread_join(th, NULL); + close(s); + return 0; +} + diff --git a/examples/nip_tcp_server_demo.c b/examples/nip_tcp_server_demo.c new file mode 100644 index 0000000..1154d29 --- /dev/null +++ b/examples/nip_tcp_server_demo.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip.h" +#include "newip_route.h" + +#define BUFLEN 4096 + +int g_pktcnt = 10; // 发送报文个数 +int g_pktlen = 1024; // 发送报文长度 +int g_port = 5556; // 服务端端口 + +void* recv_send(void* args){ + char buf[BUFLEN] = {0}; + int client, i, err; + + memcpy(&client, args, sizeof(int)); + for (i = 0; i < g_pktcnt * 2; i++) { + int recvNum = recv(client, buf, g_pktlen, MSG_WAITALL); + + if (recvNum < 0) { + perror("recv"); + } else if (recvNum == 0) { + break; + } else { + printf("Received -- %s --:%d\n", buf, recvNum); + err = send(client, buf, recvNum, 0); + if (err < 0) { + perror("send"); + break; + } + printf("Sending -- %s --:%d\n", buf, recvNum); + } + } + close(client); +} + +int main(int argc, char **argv) +{ + pthread_t th; + int s, fd, addr_len; + struct sockaddr_nin si_local; + struct sockaddr_nin si_remote; + + if ((s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("socket"); + return -1; + } + printf("creat newip socket, fd=%d\n", s); + + memset((char *)&si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_NINET; + si_local.sin_port = htons(g_port); + // 服务端2字节地址: 0xDE00 + si_local.sin_addr.nip_addr_field8[0] = 0xDE; + si_local.sin_addr.nip_addr_field8[1] = 0x00; + si_local.sin_addr.bitlen = 16; // 2字节:16bit + + if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { + perror("bind"); + return -1; + } + printf("bind success, addr=0x%02x%02x, port=%u\n", + si_local.sin_addr.nip_addr_field8[0], si_local.sin_addr.nip_addr_field8[1], g_port); + + if (listen(s, 3) < 0) { + perror("listen"); + return -1; + } + printf("listen success.\n"); + + addr_len = sizeof(si_remote); + memset(&si_remote, 0, sizeof(si_remote)); + fd = accept(s, (struct sockaddr*)&si_remote, (socklen_t*)&addr_len); + pthread_create(&th, NULL, recv_send, &fd); + pthread_join(th, NULL); // 等待线程结束, 线程间同步的操作 + close(s); + return 0; +} + diff --git a/examples/nip_udp_client_demo.c b/examples/nip_udp_client_demo.c new file mode 100644 index 0000000..b77db0f --- /dev/null +++ b/examples/nip_udp_client_demo.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip.h" +#include "newip_route.h" + +#define BUFLEN 1024 +#define PKT_NUM 10 // 收发包次数 + +typedef struct +{ + int s; + struct sockaddr_nin si_server; +} thread_args; + +void *send_recv(void *args) +{ + char buf[BUFLEN]; + fd_set readfds; + struct timeval tv; + int success = 0; + int count = 0; + int no = 0; + struct timeval stTime; + int sendtime_sec, sendtime_usec; + thread_args *th_args = (thread_args *)args; + int s = th_args->s; + struct sockaddr_nin si_server = th_args->si_server; + + while (count < PKT_NUM) { + memset(buf, 0, BUFLEN); + gettimeofday(&stTime, NULL); + sprintf(buf, "%ld %6ld NIP_UDP # %6d", stTime.tv_sec, stTime.tv_usec, count); + + socklen_t slen = sizeof(si_server); + if (sendto(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, slen) < 0) { + perror("sendto"); + } + + FD_ZERO(&readfds); + FD_SET(s, &readfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) { + perror("select"); + } + + if (FD_ISSET(s, &readfds)) { + memset(buf, 0, BUFLEN); + int ret = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, &slen); + if (ret > 0) { + success += 1; + (void)gettimeofday(&stTime, NULL); + sscanf(buf, "%d %d NIP_UDP # %d", &sendtime_sec, &sendtime_usec, &no); + printf("Received --%s sock %d success:%6d/%6d/no=%6d\n", + buf, s, success, count + 1, no); + } else { + printf("recv fail, ret=%d\n", ret); + } + } + count += 1; + usleep(500000); + } +} + +int main(int argc, char **argv) +{ + int s; + int port = 9090; + pthread_t th; + thread_args th_args; + struct sockaddr_nin si_server; + + if ((s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("socket"); + return -1; + } + + memset((char *)&si_server, 0, sizeof(si_server)); + si_server.sin_family = AF_NINET; + si_server.sin_port = htons(port); + // 服务端2字节地址: 0xDE00 + si_server.sin_addr.nip_addr_field8[0] = 0xDE; + si_server.sin_addr.nip_addr_field8[1] = 0x00; + si_server.sin_addr.bitlen = 16; // 2字节:16bit + + th_args.si_server = si_server; + th_args.si_server.sin_port = htons(port); + th_args.s = s; + pthread_create(&th, NULL, send_recv, &th_args); + pthread_join(th, NULL); + close(s); + return 0; +} + diff --git a/examples/nip_udp_server_demo.c b/examples/nip_udp_server_demo.c new file mode 100644 index 0000000..8edc159 --- /dev/null +++ b/examples/nip_udp_server_demo.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include + +#include "nip.h" +#include "newip_route.h" + +#define BUFLEN 1024 + +int main(int argc, char **argv) +{ + int s; + socklen_t slen; + int port = 9090; + char buf[BUFLEN]; + struct sockaddr_nin si_local, si_remote; + + if ((s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + perror("socket"); + return -1; + } + + memset((char *)&si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_NINET; + si_local.sin_port = htons(port); + // 服务端2字节地址: 0xDE00 + si_local.sin_addr.nip_addr_field8[0] = 0xDE; + si_local.sin_addr.nip_addr_field8[1] = 0x00; + si_local.sin_addr.bitlen = 16; // 2字节:16bit + + if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) == -1){ + perror("bind"); + close(s); + return -1; + } + + while (1) { + slen = sizeof(si_remote); + memset(buf, 0, sizeof(char) * BUFLEN); + memset(&si_remote, 0, sizeof(si_remote)); + + if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, &slen) == -1) { + perror("recvfrom"); + break; + } 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); + + if (sendto(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, slen) == -1) { + perror("sendto"); + break; + } + printf("Sending -- %s -- to 0x%0x:%d\n", buf, + si_remote.sin_addr.nip_addr_field8[0], ntohs(si_remote.sin_port)); + } + } + + close(s); + exit(EXIT_SUCCESS); +} + -- Gitee From 07dc0b7ab2a19e15541a94537b12b906fc6124e7 Mon Sep 17 00:00:00 2001 From: yangyanjun Date: Fri, 2 Sep 2022 11:39:23 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0newip=20demo=E6=A0=B7?= =?UTF-8?q?=E4=BE=8B=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangyanjun --- examples/Makefile | 4 +- examples/newip_route.h | 74 +++++----- examples/nip.h | 173 ++++++++++++++--------- examples/nip_addr_cfg_demo.c | 109 +++++++-------- examples/nip_api.c | 80 +++++------ examples/nip_api.h | 34 ++--- examples/nip_linux.h | 42 ++++++ examples/nip_route_cfg_demo.c | 126 ++++++++--------- examples/nip_tcp_client_demo.c | 241 +++++++++++++++++---------------- examples/nip_tcp_server_demo.c | 188 ++++++++++++------------- examples/nip_udp_client_demo.c | 222 +++++++++++++++--------------- examples/nip_udp_server_demo.c | 144 ++++++++++---------- 12 files changed, 762 insertions(+), 675 deletions(-) create mode 100644 examples/nip_linux.h diff --git a/examples/Makefile b/examples/Makefile index 8f90266..08e75c0 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# +# # Copyright (c) 2022 Huawei Device Co., Ltd. # # Makefile for the Linux newip layer @@ -13,7 +13,7 @@ UT_LIST = nip_addr_cfg_demo nip_route_cfg_demo nip_tcp_server_demo nip_tcp_clien all: $(UT_LIST) -clean: +clean: rm -f $(UT_LIST) rm -f nip_api.o rm -f libnip_api.a diff --git a/examples/newip_route.h b/examples/newip_route.h index d8b850a..e7b1654 100644 --- a/examples/newip_route.h +++ b/examples/newip_route.h @@ -1,37 +1,37 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * Linux NewIP INET implementation - * - * Based on include/uapi/linux/ipv6_route.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _NEWIP_ROUTE_H -#define _NEWIP_ROUTE_H - -#include "nip.h" - -struct nip_arpmsg { - struct nip_addr dst_addr; - char ifrn_name[10]; - __u8 lladdr[10]; -}; - -struct nip_rtmsg { - struct nip_addr rtmsg_dst; - struct nip_addr rtmsg_src; - struct nip_addr rtmsg_gateway; - char dev_name[10]; - __u32 rtmsg_type; - int rtmsg_ifindex; - __u32 rtmsg_metric; - unsigned long rtmsg_info; - __u32 rtmsg_flags; -}; - -#endif /* _NEWIP_ROUTE_H */ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * Based on include/uapi/linux/ipv6_route.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _NEWIP_ROUTE_H +#define _NEWIP_ROUTE_H + +#include "nip.h" + +struct nip_arpmsg { + struct nip_addr dst_addr; + char ifrn_name[10]; + __u8 lladdr[10]; +}; + +struct nip_rtmsg { + struct nip_addr rtmsg_dst; + struct nip_addr rtmsg_src; + struct nip_addr rtmsg_gateway; + char dev_name[10]; + __u32 rtmsg_type; + int rtmsg_ifindex; + __u32 rtmsg_metric; + unsigned long rtmsg_info; + __u32 rtmsg_flags; +}; + +#endif /* _NEWIP_ROUTE_H */ diff --git a/examples/nip.h b/examples/nip.h index e9ea37a..2c1c267 100644 --- a/examples/nip.h +++ b/examples/nip.h @@ -1,64 +1,109 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * Linux NewIP INET implementation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _NIP_H -#define _NIP_H - -#include - -// AF_NINET可通过读取 /sys/module/newip/parameters/af_ninet 文件来获取类型数值。 -#define PF_NINET 45 -#define AF_NINET PF_NINET - -#define NIP_BITLEN_MAX 64 - -#define nip_addr_field8 v.u.u8 -#define nip_addr_field16 v.u.u16 -#define nip_addr_field32 v.u.u32 - -/* New IP address field */ -#pragma pack(1) -struct nip_addr_field { - union { - __u8 u8[8]; - __be16 u16[4]; - __be32 u32[2]; - } u; -}; -#pragma pack() - -/* New IP topology address structure */ -#pragma pack(1) -struct nip_addr { - uint8_t bitlen; // address bitlength - struct nip_addr_field v; -}; -#pragma pack() - -/* 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; -}; - -#endif /*_NIP_H*/ +/* 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; + 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 index 7645f91..d47c58e 100644 --- a/examples/nip_addr_cfg_demo.c +++ b/examples/nip_addr_cfg_demo.c @@ -12,7 +12,7 @@ #include #include -#include "nip.h" +#include "nip_linux.h" #include "nip_api.h" /* 基于设备名字获取ifindex @@ -23,75 +23,68 @@ */ int32_t nip_add_addr(int32_t ifindex, const unsigned char *addr, uint8_t addr_len) { - int32_t sockfd, ret; - struct nip_ifreq ifrn; + int32_t sockfd, ret; + struct nip_ifreq ifrn; - sockfd = socket(AF_NINET, SOCK_DGRAM, 0); - if (sockfd < 0) { - return -1; - } + sockfd = socket(AF_NINET, SOCK_DGRAM, 0); + if (sockfd < 0) + return -1; - memset(&ifrn, 0, sizeof(ifrn)); - ifrn.ifrn_addr.bitlen = addr_len * 8; // 字节长度转换成bit长度 - memcpy(ifrn.ifrn_addr.nip_addr_field8, addr, addr_len); - ifrn.ifrn_ifindex = ifindex; + memset(&ifrn, 0, sizeof(ifrn)); + ifrn.ifrn_addr.bitlen = addr_len * 8; // 字节长度转换成bit长度 + memcpy(ifrn.ifrn_addr.nip_addr_field8, addr, addr_len); + ifrn.ifrn_ifindex = ifindex; - ret = ioctl(sockfd, SIOCSIFADDR, &ifrn); - if (ret < 0 && errno != EEXIST) { // ignore File Exists error - printf("cfg newip addr fail, ifindex=%d, ret=%d.\n", ifindex, ret); - close(sockfd); - return -1; - } + ret = ioctl(sockfd, SIOCSIFADDR, &ifrn); + if (ret < 0 && errno != EEXIST) { // ignore File Exists error + printf("cfg newip addr fail, ifindex=%d, ret=%d.\n", ifindex, ret); + close(sockfd); + return -1; + } - close(sockfd); - return 0; + close(sockfd); + return 0; } /* 执行用例前先执行ifconfig xxx up,xxx表示网卡名,比如eth0,wlan0 */ int main(int argc, char **argv) { - int ret; - int32_t ifindex = 0; - const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 - uint8_t client_addr[1] = {0x50}; // 客户端1字节地址: 0x50 - uint8_t server_addr[2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 - uint8_t *addr; - uint8_t addr_len; + int ret; + int32_t ifindex = 0; + const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 + uint8_t client_addr[INDEX_1] = {0x50}; // 客户端1字节地址: 0x50 + uint8_t server_addr[INDEX_2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 + uint8_t *addr; + uint8_t addr_len; - if (argc == 2) { - if (!strcmp(*(argv + 1), "server")) { - printf("server cfg addr=0x%02x%02x.\n", server_addr[0], server_addr[1]); - addr = server_addr; - addr_len = 2; - } else if (!strcmp(*(argv + 1), "client")) { - printf("client cfg addr=0x%x02x.\n", client_addr[0]); - addr = client_addr; - addr_len = 1; - } else { - printf("invalid addr cfg input.\n"); - return -1; - } - } else { - printf("unsupport addr cfg input.\n"); - return -1; - } + 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 = set_netcard_up(ifname); - if (ret != 0) { - return -1; - } + ret = nip_get_ifindex(ifname, &ifindex); + if (ret != 0) + return -1; - ret = nip_get_ifindex(ifname, &ifindex); - if (ret != 0) { - return -1; - } + ret = nip_add_addr(ifindex, addr, addr_len); + 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, ifname, ifindex); - return 0; + printf("%s %s(ifindex=%u) cfg addr success.\n", *argv, ifname, ifindex); + return 0; } diff --git a/examples/nip_api.c b/examples/nip_api.c index 7f2c5e9..5ac5706 100644 --- a/examples/nip_api.c +++ b/examples/nip_api.c @@ -11,59 +11,59 @@ #include #include -#include "nip.h" +#include "nip_linux.h" #include "nip_api.h" int32_t nip_get_ifindex(const char *ifname, int32_t *ifindex) { - struct ifreq ifr; + int fd; + struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, ifname); - int 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); + 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; + printf("%s ifindex=%u\n", ifname, ifr.ifr_ifindex); + *ifindex = ifr.ifr_ifindex; + return 0; } int32_t set_netcard_up(const char *ifname) { - int32_t fd; - struct ifreq ifr; + int32_t fd; + struct ifreq ifr; - fd = socket(AF_NINET, SOCK_DGRAM, 0); - if (fd < 0) { - return -1; - } + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) + return -1; - strcpy(ifr.ifr_name, ifname); - if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - printf("get %s flag fail.", ifname); - close(fd); - return -1; - } + strcpy(ifr.ifr_name, ifname); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + printf("get %s flag fail.", ifname); + close(fd); + return -1; + } - strcpy(ifr.ifr_name, ifname); - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { - printf("set %s up fail.", ifname); - close(fd); - return -1; - } + strcpy(ifr.ifr_name, ifname); + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + printf("set %s up fail.", ifname); + close(fd); + return -1; + } - printf("set %s up success.", ifname); - close(fd); - return 0; + printf("set %s up success.", ifname); + close(fd); + return 0; } diff --git a/examples/nip_api.h b/examples/nip_api.h index 2dab3f2..6c8921e 100644 --- a/examples/nip_api.h +++ b/examples/nip_api.h @@ -1,17 +1,17 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * Linux NewIP INET implementation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _NIP_API_H -#define _NIP_API_H - -int32_t nip_get_ifindex(const char *ifname, int32_t *ifindex); - -#endif /* _NIP_API_H */ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _NIP_API_H +#define _NIP_API_H + +int32_t nip_get_ifindex(const char *ifname, int32_t *ifindex); + +#endif /* _NIP_API_H */ diff --git a/examples/nip_linux.h b/examples/nip_linux.h new file mode 100644 index 0000000..2ca6bd5 --- /dev/null +++ b/examples/nip_linux.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _NIP_LINUX_H +#define _NIP_LINUX_H + +#include +#include "nip.h" + +// AF_NINET可通过读取 /sys/module/newip/parameters/af_ninet 文件来获取类型数值。 +#define PF_NINET 45 +#define AF_NINET PF_NINET + +#define DEMO_INPUT_1 2 // DEMO程序包含1个入参S + +/* 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; +}; + +#endif /*_NIP_LINUX_H*/ diff --git a/examples/nip_route_cfg_demo.c b/examples/nip_route_cfg_demo.c index 3dbebf7..c51f0e3 100644 --- a/examples/nip_route_cfg_demo.c +++ b/examples/nip_route_cfg_demo.c @@ -13,7 +13,7 @@ #include #include -#include "nip.h" +#include "nip_linux.h" #include "newip_route.h" #include "nip_api.h" @@ -24,82 +24,82 @@ * ifr.ifr_ifindex; ===> 函数入参 ifindex */ int32_t nip_route_add(int32_t ifindex, const unsigned char *dst_addr, uint8_t dst_addr_len, - const unsigned char *gateway_addr, uint8_t gateway_addr_len) + const unsigned char *gateway_addr, uint8_t gateway_addr_len) { - int32_t sockfd, ret; - struct nip_rtmsg rt; + int32_t sockfd, ret; + struct nip_rtmsg rt; - sockfd = socket(AF_NINET, SOCK_DGRAM, 0); - if (sockfd < 0) { - return -1; - } + sockfd = socket(AF_NINET, SOCK_DGRAM, 0); + if (sockfd < 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); + 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; - } + 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(sockfd, SIOCADDRT, &rt); - if (ret < 0 && errno != EEXIST) { // ignore File Exists error - close(sockfd); - return -1; - } + ret = ioctl(sockfd, SIOCADDRT, &rt); + if (ret < 0 && errno != EEXIST) { // ignore File Exists error + close(sockfd); + return -1; + } - close(sockfd); - return 0; + close(sockfd); + return 0; } /* 执行用例前先执行ifconfig xxx up,xxx表示网卡名,比如eth0,wlan0 */ int main(int argc, char **argv) { - int ret; - int32_t ifindex = 0; - const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 - uint8_t client_addr[1] = {0x50}; // 客户端1字节地址: 0x50 - uint8_t server_addr[2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 - uint8_t *dst_addr; - uint8_t dst_addr_len; - uint8_t *gateway_addr; - uint8_t gateway_addr_len; + int ret; + int32_t ifindex = 0; + const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 + uint8_t client_addr[INDEX_1] = {0x50}; // 客户端1字节地址: 0x50 + uint8_t server_addr[INDEX_2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 + uint8_t *dst_addr; + uint8_t dst_addr_len; + uint8_t *gateway_addr; + uint8_t gateway_addr_len; - if (argc == 2) { - if (!strcmp(*(argv + 1), "server")) { - printf("server cfg route, dst-addr=0x%x02.\n", client_addr[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[0], server_addr[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; - } + 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(ifname, &ifindex); - if (ret != 0) { - printf("get %s ifindex fail, ret=%d.\n", ifname, ret); - return -1; - } + ret = nip_get_ifindex(ifname, &ifindex); + if (ret != 0) { + printf("get %s ifindex fail, ret=%d.\n", ifname, 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", ifname, 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", ifname, ret); + return -1; + } - printf("%s %s(ifindex=%u) cfg route success.\n", *argv, ifname, ifindex); - return 0; + printf("%s %s(ifindex=%u) cfg route success.\n", *argv, ifname, ifindex); + return 0; } diff --git a/examples/nip_tcp_client_demo.c b/examples/nip_tcp_client_demo.c index dece6d0..f8b2c87 100644 --- a/examples/nip_tcp_client_demo.c +++ b/examples/nip_tcp_client_demo.c @@ -1,119 +1,122 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * NewIP INET socket protocol family - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nip.h" -#include "newip_route.h" - -#define __USE_GNU -#include -#include - -#define BUFLEN 4096 - -int g_pktcnt = 10; // 发送报文个数 -int g_pktlen = 1024; // 发送报文长度 -int g_pktinterval = 500; // 发包间隔(ms) -int g_port = 5556; // 服务端端口 - -typedef struct { - int s; - struct sockaddr_nin si_server; -} thread_args; - -void *send_recv(void *args) -{ - char buf[BUFLEN]; - fd_set readfds; - struct timeval tv, stTime; - int sendtime_sec, sendtime_usec; - int success = 0; - int count = 0; - int no = 0; - thread_args *th_args = (thread_args *) args; - int s = th_args->s; - struct sockaddr_nin si_server = th_args->si_server; - - for (int i; i < g_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(s, buf, g_pktlen, 0) < 0) { - perror("send"); - } - - FD_ZERO(&readfds); - FD_SET(s, &readfds); - tv.tv_sec = 600; - tv.tv_usec = 0; - if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) { - perror("select"); - } - - if (FD_ISSET(s, &readfds)) { - memset(buf, 0, BUFLEN); - int ret = recv(s, buf, g_pktlen, MSG_WAITALL); - if (ret > 0) { - success += 1; - (void)gettimeofday(&stTime, NULL); - sscanf(buf, "%d %d NIP_TCP # %d", &sendtime_sec, &sendtime_usec, &no); - printf("Received --%s sock %d success:%6d/%6d/no=%6d\n", - buf, s, success, count + 1, no); - } else { - printf("recv fail, ret=%d\n", ret); - } - } - count += 1; - usleep(g_pktinterval * 1000); - } - close(s); -} - -int main(int argc, char **argv) -{ - int s; - pthread_t th; - thread_args th_args; - struct sockaddr_nin si_server; - - if ((s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - printf("errno=%d\n", errno); - return -1; - } - printf("creat newip socket, fd=%d\n", s); - - memset((char *)&si_server, 0, sizeof(si_server)); - si_server.sin_family = AF_NINET; - si_server.sin_port = htons(g_port); - // 服务端2字节地址: 0xDE00 - si_server.sin_addr.nip_addr_field8[0] = 0xDE; - si_server.sin_addr.nip_addr_field8[1] = 0x00; - si_server.sin_addr.bitlen = 16; // 2字节:16bit - if (connect(s, (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[0], si_server.sin_addr.nip_addr_field8[1], g_port); - - th_args.si_server = si_server; - th_args.si_server.sin_port = htons(g_port); - th_args.s = s; - pthread_create(&th, NULL, send_recv, &th_args); - pthread_join(th, NULL); - close(s); - return 0; -} - +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nip_linux.h" +#include "newip_route.h" + +#define __USE_GNU +#include +#include + +#define BUFLEN 4096 +#define LISTEN_MAX 3 +#define PORT 5556 // 服务端端口 +#define PKTCNT 10 // 发送报文个数 +#define PKTLEN 1024 // 发送报文长度 +#define SLEEP_US 500000 // 发包间隔(ms) +#define SELECT_TIME 600 + +struct thread_args { + int s; + struct sockaddr_nin si_server; +}; + +void *send_recv(void *args) +{ + int ret; + char buf[BUFLEN]; + fd_set readfds; + struct timeval tv, stTime; + int sendtime_sec, sendtime_usec; + int success = 0; + int count = 0; + int no = 0; + struct thread_args *th_args = (struct thread_args *) args; + int s = th_args->s; + struct sockaddr_nin si_server = th_args->si_server; + + for (int i; 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(s, buf, PKTLEN, 0) < 0) + perror("send"); + + FD_ZERO(&readfds); + FD_SET(s, &readfds); + tv.tv_sec = SELECT_TIME; + tv.tv_usec = 0; + if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) + perror("select"); + + if (FD_ISSET(s, &readfds)) { + memset(buf, 0, BUFLEN); + ret = recv(s, 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, s, success, count + 1, no); + } else { + printf("recv fail, ret=%d\n", ret); + } + } + count += 1; + usleep(SLEEP_US); + } + close(s); +} + +int main(int argc, char **argv) +{ + int s; + pthread_t th; + struct thread_args th_args; + struct sockaddr_nin si_server; + + s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); + if (s < 0) { + perror("socket"); + return -1; + } + printf("creat newip socket, fd=%d\n", s); + + memset((char *)&si_server, 0, sizeof(si_server)); + si_server.sin_family = AF_NINET; + si_server.sin_port = htons(PORT); + // 服务端2字节地址: 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字节:16bit + if (connect(s, (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], PORT); + + th_args.si_server = si_server; + th_args.si_server.sin_port = htons(PORT); + th_args.s = s; + pthread_create(&th, NULL, send_recv, &th_args); + pthread_join(th, NULL); + close(s); + return 0; +} + diff --git a/examples/nip_tcp_server_demo.c b/examples/nip_tcp_server_demo.c index 1154d29..6f7ad11 100644 --- a/examples/nip_tcp_server_demo.c +++ b/examples/nip_tcp_server_demo.c @@ -1,93 +1,95 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * NewIP INET socket protocol family - */ -#include -#include -#include -#include -#include - -#define __USE_GNU -#include -#include - -#include "nip.h" -#include "newip_route.h" - -#define BUFLEN 4096 - -int g_pktcnt = 10; // 发送报文个数 -int g_pktlen = 1024; // 发送报文长度 -int g_port = 5556; // 服务端端口 - -void* recv_send(void* args){ - char buf[BUFLEN] = {0}; - int client, i, err; - - memcpy(&client, args, sizeof(int)); - for (i = 0; i < g_pktcnt * 2; i++) { - int recvNum = recv(client, buf, g_pktlen, MSG_WAITALL); - - if (recvNum < 0) { - perror("recv"); - } else if (recvNum == 0) { - break; - } else { - printf("Received -- %s --:%d\n", buf, recvNum); - err = send(client, buf, recvNum, 0); - if (err < 0) { - perror("send"); - break; - } - printf("Sending -- %s --:%d\n", buf, recvNum); - } - } - close(client); -} - -int main(int argc, char **argv) -{ - pthread_t th; - int s, fd, addr_len; - struct sockaddr_nin si_local; - struct sockaddr_nin si_remote; - - if ((s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - perror("socket"); - return -1; - } - printf("creat newip socket, fd=%d\n", s); - - memset((char *)&si_local, 0, sizeof(si_local)); - si_local.sin_family = AF_NINET; - si_local.sin_port = htons(g_port); - // 服务端2字节地址: 0xDE00 - si_local.sin_addr.nip_addr_field8[0] = 0xDE; - si_local.sin_addr.nip_addr_field8[1] = 0x00; - si_local.sin_addr.bitlen = 16; // 2字节:16bit - - if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { - perror("bind"); - return -1; - } - printf("bind success, addr=0x%02x%02x, port=%u\n", - si_local.sin_addr.nip_addr_field8[0], si_local.sin_addr.nip_addr_field8[1], g_port); - - if (listen(s, 3) < 0) { - perror("listen"); - return -1; - } - printf("listen success.\n"); - - addr_len = sizeof(si_remote); - memset(&si_remote, 0, sizeof(si_remote)); - fd = accept(s, (struct sockaddr*)&si_remote, (socklen_t*)&addr_len); - pthread_create(&th, NULL, recv_send, &fd); - pthread_join(th, NULL); // 等待线程结束, 线程间同步的操作 - close(s); - return 0; -} - +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip_linux.h" +#include "newip_route.h" + +#define BUFLEN 4096 +#define PKTCNT_SCALE 2 +#define LISTEN_MAX 3 +#define PORT 5556 // 服务端端口 +#define PKTCNT 10 // 发送报文个数 +#define PKTLEN 1024 // 发送报文长度 + +void *recv_send(void *args) +{ + char buf[BUFLEN] = {0}; + int client, i, err; + + memcpy(&client, args, sizeof(int)); + for (i = 0; i < PKTCNT * PKTCNT_SCALE; i++) { + int recvNum = recv(client, buf, PKTLEN, MSG_WAITALL); + + if (recvNum <= 0) { + perror("recv"); + } else { + printf("Received -- %s --:%d\n", buf, recvNum); + err = send(client, buf, recvNum, 0); + if (err < 0) { + perror("send"); + break; + } + printf("Sending -- %s --:%d\n", buf, recvNum); + } + } + close(client); +} + +int main(int argc, char **argv) +{ + pthread_t th; + int s, fd, addr_len; + struct sockaddr_nin si_local; + struct sockaddr_nin si_remote; + + s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); + if (s < 0) { + perror("socket"); + return -1; + } + printf("creat newip socket, fd=%d\n", s); + + memset((char *)&si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_NINET; + si_local.sin_port = htons(PORT); + // 服务端2字节地址: 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字节:16bit + + if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { + perror("bind"); + return -1; + } + 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], PORT); + + if (listen(s, LISTEN_MAX) < 0) { + perror("listen"); + return -1; + } + printf("listen success.\n"); + + addr_len = sizeof(si_remote); + memset(&si_remote, 0, sizeof(si_remote)); + fd = accept(s, (struct sockaddr *)&si_remote, (socklen_t *)&addr_len); + pthread_create(&th, NULL, recv_send, &fd); + pthread_join(th, NULL); // 等待线程结束, 线程间同步的操作 + close(s); + return 0; +} + diff --git a/examples/nip_udp_client_demo.c b/examples/nip_udp_client_demo.c index b77db0f..0e81c7c 100644 --- a/examples/nip_udp_client_demo.c +++ b/examples/nip_udp_client_demo.c @@ -1,110 +1,112 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * NewIP INET socket protocol family - */ -#include -#include -#include -#include -#include -#include -#include - -#define __USE_GNU -#include -#include - -#include "nip.h" -#include "newip_route.h" - -#define BUFLEN 1024 -#define PKT_NUM 10 // 收发包次数 - -typedef struct -{ - int s; - struct sockaddr_nin si_server; -} thread_args; - -void *send_recv(void *args) -{ - char buf[BUFLEN]; - fd_set readfds; - struct timeval tv; - int success = 0; - int count = 0; - int no = 0; - struct timeval stTime; - int sendtime_sec, sendtime_usec; - thread_args *th_args = (thread_args *)args; - int s = th_args->s; - struct sockaddr_nin si_server = th_args->si_server; - - while (count < PKT_NUM) { - memset(buf, 0, BUFLEN); - gettimeofday(&stTime, NULL); - sprintf(buf, "%ld %6ld NIP_UDP # %6d", stTime.tv_sec, stTime.tv_usec, count); - - socklen_t slen = sizeof(si_server); - if (sendto(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, slen) < 0) { - perror("sendto"); - } - - FD_ZERO(&readfds); - FD_SET(s, &readfds); - tv.tv_sec = 2; - tv.tv_usec = 0; - if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) { - perror("select"); - } - - if (FD_ISSET(s, &readfds)) { - memset(buf, 0, BUFLEN); - int ret = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, &slen); - if (ret > 0) { - success += 1; - (void)gettimeofday(&stTime, NULL); - sscanf(buf, "%d %d NIP_UDP # %d", &sendtime_sec, &sendtime_usec, &no); - printf("Received --%s sock %d success:%6d/%6d/no=%6d\n", - buf, s, success, count + 1, no); - } else { - printf("recv fail, ret=%d\n", ret); - } - } - count += 1; - usleep(500000); - } -} - -int main(int argc, char **argv) -{ - int s; - int port = 9090; - pthread_t th; - thread_args th_args; - struct sockaddr_nin si_server; - - if ((s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - perror("socket"); - return -1; - } - - memset((char *)&si_server, 0, sizeof(si_server)); - si_server.sin_family = AF_NINET; - si_server.sin_port = htons(port); - // 服务端2字节地址: 0xDE00 - si_server.sin_addr.nip_addr_field8[0] = 0xDE; - si_server.sin_addr.nip_addr_field8[1] = 0x00; - si_server.sin_addr.bitlen = 16; // 2字节:16bit - - th_args.si_server = si_server; - th_args.si_server.sin_port = htons(port); - th_args.s = s; - pthread_create(&th, NULL, send_recv, &th_args); - pthread_join(th, NULL); - close(s); - return 0; -} - +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include + +#define __USE_GNU +#include +#include + +#include "nip_linux.h" +#include "newip_route.h" + +#define BUFLEN 4096 +#define PKT_NUM 10 // 收发包次数 +#define SLEEP_US 500000 // 发包间隔(ms) +#define PORT 9090 + +struct thread_args { + int s; + struct sockaddr_nin si_server; +}; + +void *send_recv(void *args) +{ + int ret; + char buf[BUFLEN]; + fd_set readfds; + struct timeval tv; + int success = 0; + int count = 0; + int no = 0; + struct timeval stTime; + int sendtime_sec, sendtime_usec; + struct thread_args *th_args = (struct thread_args *)args; + int s = th_args->s; + struct sockaddr_nin si_server = th_args->si_server; + + while (count < PKT_NUM) { + 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(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, slen) < 0) + perror("sendto"); + + FD_ZERO(&readfds); + FD_SET(s, &readfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) + perror("select"); + + if (FD_ISSET(s, &readfds)) { + memset(buf, 0, BUFLEN); + ret = recvfrom(s, 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, s, success, count + 1, no); + } else { + printf("recv fail, ret=%d\n", ret); + } + } + count += 1; + usleep(SLEEP_US); + } +} + +int main(int argc, char **argv) +{ + int s; + pthread_t th; + struct thread_args th_args; + struct sockaddr_nin si_server; + + s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP); + if (s < 0) { + perror("socket"); + return -1; + } + + memset((char *)&si_server, 0, sizeof(si_server)); + si_server.sin_family = AF_NINET; + si_server.sin_port = htons(PORT); + // 服务端2字节地址: 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字节:16bit + + th_args.si_server = si_server; + th_args.si_server.sin_port = htons(PORT); + th_args.s = s; + pthread_create(&th, NULL, send_recv, &th_args); + pthread_join(th, NULL); + close(s); + return 0; +} + diff --git a/examples/nip_udp_server_demo.c b/examples/nip_udp_server_demo.c index 8edc159..2c3dffe 100644 --- a/examples/nip_udp_server_demo.c +++ b/examples/nip_udp_server_demo.c @@ -1,72 +1,72 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * NewIP INET socket protocol family - */ -#include -#include -#include -#include -#include -#include -#include - -#include "nip.h" -#include "newip_route.h" - -#define BUFLEN 1024 - -int main(int argc, char **argv) -{ - int s; - socklen_t slen; - int port = 9090; - char buf[BUFLEN]; - struct sockaddr_nin si_local, si_remote; - - if ((s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { - perror("socket"); - return -1; - } - - memset((char *)&si_local, 0, sizeof(si_local)); - si_local.sin_family = AF_NINET; - si_local.sin_port = htons(port); - // 服务端2字节地址: 0xDE00 - si_local.sin_addr.nip_addr_field8[0] = 0xDE; - si_local.sin_addr.nip_addr_field8[1] = 0x00; - si_local.sin_addr.bitlen = 16; // 2字节:16bit - - if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) == -1){ - perror("bind"); - close(s); - return -1; - } - - while (1) { - slen = sizeof(si_remote); - memset(buf, 0, sizeof(char) * BUFLEN); - memset(&si_remote, 0, sizeof(si_remote)); - - if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, &slen) == -1) { - perror("recvfrom"); - break; - } 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); - - if (sendto(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, slen) == -1) { - perror("sendto"); - break; - } - printf("Sending -- %s -- to 0x%0x:%d\n", buf, - si_remote.sin_addr.nip_addr_field8[0], ntohs(si_remote.sin_port)); - } - } - - close(s); - exit(EXIT_SUCCESS); -} - +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET socket protocol family + */ +#include +#include +#include +#include +#include +#include +#include + +#include "nip_linux.h" +#include "newip_route.h" + +#define BUFLEN 1024 +#define PORT 9090 + +int main(int argc, char **argv) +{ + int s; + socklen_t slen; + char buf[BUFLEN]; + int recvNum; + struct sockaddr_nin si_local, si_remote; + + s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP); + if (s == -1) { + perror("socket"); + return -1; + } + + memset((char *)&si_local, 0, sizeof(si_local)); + si_local.sin_family = AF_NINET; + si_local.sin_port = htons(PORT); + // 服务端2字节地址: 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字节:16bit + + if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) == -1) { + perror("bind"); + close(s); + return -1; + } + + while (1) { + slen = sizeof(si_remote); + memset(buf, 0, sizeof(char) * BUFLEN); + memset(&si_remote, 0, sizeof(si_remote)); + recvNum = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, &slen); + if (recvNum <= 0) { + perror("recvfrom"); + } 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); + if (sendto(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, slen) == -1) { + perror("sendto"); + break; + } + printf("Sending -- %s -- to 0x%0x:%d\n", buf, + si_remote.sin_addr.nip_addr_field8[0], ntohs(si_remote.sin_port)); + } + } + + close(s); + return 0; +} + -- Gitee From 740f519257dcd503cf4c819c78d0f4b3a55f767f Mon Sep 17 00:00:00 2001 From: yangyanjun Date: Mon, 5 Sep 2022 10:04:19 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=9C=B0=E5=9D=80=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E8=B7=AF=E7=94=B1=E9=85=8D=E7=BD=AE=EF=BC=8Ctcp?= =?UTF-8?q?=E6=94=B6=E5=8F=91=E5=8C=85demo=E5=BD=92=E6=A1=A3(=E6=A3=80?= =?UTF-8?q?=E8=A7=86=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9=EF=BC=8C=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E7=B1=BB=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangyanjun --- examples/Makefile | 19 +++-- examples/newip_route.h | 39 ++++++---- examples/nip_addr_cfg_demo.c | 61 ++++++++++----- examples/nip_api.c | 69 ----------------- examples/nip_api.h | 17 ----- examples/nip_lib.c | 61 +++++++++++++++ examples/nip_lib.h | 44 +++++++++++ examples/nip_route_cfg_demo.c | 62 +++++++++------ examples/nip_tcp_client_demo.c | 95 +++++++++++++---------- examples/nip_tcp_server_demo.c | 93 +++++++++++++--------- examples/{nip_linux.h => nip_uapi.h} | 43 ++++++++--- examples/nip_udp_client_demo.c | 85 +++++++++++++-------- examples/nip_udp_server_demo.c | 110 ++++++++++++++++++--------- 13 files changed, 485 insertions(+), 313 deletions(-) delete mode 100644 examples/nip_api.c delete mode 100644 examples/nip_api.h create mode 100644 examples/nip_lib.c create mode 100644 examples/nip_lib.h rename examples/{nip_linux.h => nip_uapi.h} (30%) diff --git a/examples/Makefile b/examples/Makefile index 08e75c0..3952330 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,8 +1,7 @@ -# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2022 Huawei Device Co., Ltd. # -# Makefile for the Linux newip layer # CC=gcc # CC = aarch64-linux-gnu-gcc @@ -15,19 +14,19 @@ all: $(UT_LIST) clean: rm -f $(UT_LIST) - rm -f nip_api.o - rm -f libnip_api.a + rm -f nip_lib.o + rm -f libnip_lib.a #lib -NIP_LIB = libnip_api.a -NIP_DEF_LIB = -L. -lnip_api +NIP_LIB = libnip_lib.a +NIP_DEF_LIB = -L. -lnip_lib -nip_api.o: nip_api.c - $(CC) -c nip_api.c -o nip_api.o +nip_lib.o: nip_lib.c + $(CC) -c nip_lib.c -o nip_lib.o -libnip_api.a: nip_api.o - ar -rv libnip_api.a nip_api.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) diff --git a/examples/newip_route.h b/examples/newip_route.h index e7b1654..b1f6118 100644 --- a/examples/newip_route.h +++ b/examples/newip_route.h @@ -1,37 +1,44 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * Linux NewIP INET implementation + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: * - * Based on include/uapi/linux/ipv6_route.h + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * 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_arpmsg { - struct nip_addr dst_addr; - char ifrn_name[10]; - __u8 lladdr[10]; -}; - struct nip_rtmsg { struct nip_addr rtmsg_dst; struct nip_addr rtmsg_src; struct nip_addr rtmsg_gateway; char dev_name[10]; - __u32 rtmsg_type; + unsigned int rtmsg_type; int rtmsg_ifindex; - __u32 rtmsg_metric; + unsigned int rtmsg_metric; unsigned long rtmsg_info; - __u32 rtmsg_flags; + unsigned int rtmsg_flags; }; #endif /* _NEWIP_ROUTE_H */ diff --git a/examples/nip_addr_cfg_demo.c b/examples/nip_addr_cfg_demo.c index d47c58e..7d2c310 100644 --- a/examples/nip_addr_cfg_demo.c +++ b/examples/nip_addr_cfg_demo.c @@ -1,8 +1,28 @@ -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * NewIP INET socket protocol family + * 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 @@ -12,48 +32,49 @@ #include #include -#include "nip_linux.h" -#include "nip_api.h" +#include "nip_uapi.h" +#include "nip_lib.h" -/* 基于设备名字获取ifindex +/* get ifindex based on the device name * struct ifreq ifr; * struct nip_ifreq ifrn; * ioctl(fd, SIOGIFINDEX, &ifr); - * ifr.ifr_ifindex; ===> 函数入参 ifindex + * ifr.ifr_ifindex; ===> ifindex */ int32_t nip_add_addr(int32_t ifindex, const unsigned char *addr, uint8_t addr_len) { - int32_t sockfd, ret; + int fd, ret; struct nip_ifreq ifrn; - sockfd = socket(AF_NINET, SOCK_DGRAM, 0); - if (sockfd < 0) + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) return -1; memset(&ifrn, 0, sizeof(ifrn)); - ifrn.ifrn_addr.bitlen = addr_len * 8; // 字节长度转换成bit长度 + 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(sockfd, SIOCSIFADDR, &ifrn); + 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(sockfd); + close(fd); return -1; } - close(sockfd); + close(fd); return 0; } -/* 执行用例前先执行ifconfig xxx up,xxx表示网卡名,比如eth0,wlan0 */ +/* 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; - int32_t ifindex = 0; - const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 - uint8_t client_addr[INDEX_1] = {0x50}; // 客户端1字节地址: 0x50 - uint8_t server_addr[INDEX_2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 + 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; @@ -76,7 +97,7 @@ int main(int argc, char **argv) return -1; } - ret = nip_get_ifindex(ifname, &ifindex); + ret = nip_get_ifindex(NIC_NAME, &ifindex); if (ret != 0) return -1; @@ -84,7 +105,7 @@ int main(int argc, char **argv) if (ret != 0) return -1; - printf("%s %s(ifindex=%u) cfg addr success.\n", *argv, ifname, ifindex); + printf("%s %s(ifindex=%u) cfg addr success.\n", *argv, NIC_NAME, ifindex); return 0; } diff --git a/examples/nip_api.c b/examples/nip_api.c deleted file mode 100644 index 5ac5706..0000000 --- a/examples/nip_api.c +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * NewIP INET socket protocol family - */ -#include -#include -#include -#include -#include -#include - -#include "nip_linux.h" -#include "nip_api.h" - -int32_t nip_get_ifindex(const char *ifname, int32_t *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; -} - -int32_t set_netcard_up(const char *ifname) -{ - int32_t fd; - struct ifreq ifr; - - fd = socket(AF_NINET, SOCK_DGRAM, 0); - if (fd < 0) - return -1; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - printf("get %s flag fail.", ifname); - close(fd); - return -1; - } - - strcpy(ifr.ifr_name, ifname); - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { - printf("set %s up fail.", ifname); - close(fd); - return -1; - } - - printf("set %s up success.", ifname); - close(fd); - return 0; -} - diff --git a/examples/nip_api.h b/examples/nip_api.h deleted file mode 100644 index 6c8921e..0000000 --- a/examples/nip_api.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * - * Linux NewIP INET implementation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _NIP_API_H -#define _NIP_API_H - -int32_t nip_get_ifindex(const char *ifname, int32_t *ifindex); - -#endif /* _NIP_API_H */ diff --git a/examples/nip_lib.c b/examples/nip_lib.c new file mode 100644 index 0000000..b6a8c7d --- /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 0000000..d52e5f8 --- /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 index c51f0e3..5ed1bd1 100644 --- a/examples/nip_route_cfg_demo.c +++ b/examples/nip_route_cfg_demo.c @@ -1,8 +1,28 @@ -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * NewIP INET socket protocol family + * 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 @@ -13,24 +33,24 @@ #include #include -#include "nip_linux.h" +#include "nip_uapi.h" +#include "nip_lib.h" #include "newip_route.h" -#include "nip_api.h" -/* 基于设备名字获取ifindex +/* get ifindex based on the device name * struct ifreq ifr; * struct nip_ifreq ifrn; * ioctl(fd, SIOGIFINDEX, &ifr); - * ifr.ifr_ifindex; ===> 函数入参 ifindex + * ifr.ifr_ifindex; ===> ifindex */ -int32_t nip_route_add(int32_t ifindex, const unsigned char *dst_addr, uint8_t dst_addr_len, +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) { - int32_t sockfd, ret; + int fd, ret; struct nip_rtmsg rt; - sockfd = socket(AF_NINET, SOCK_DGRAM, 0); - if (sockfd < 0) + fd = socket(AF_NINET, SOCK_DGRAM, 0); + if (fd < 0) return -1; memset(&rt, 0, sizeof(rt)); @@ -45,24 +65,22 @@ int32_t nip_route_add(int32_t ifindex, const unsigned char *dst_addr, uint8_t ds rt.rtmsg_flags |= RTF_GATEWAY; } - ret = ioctl(sockfd, SIOCADDRT, &rt); + ret = ioctl(fd, SIOCADDRT, &rt); if (ret < 0 && errno != EEXIST) { // ignore File Exists error - close(sockfd); + close(fd); return -1; } - close(sockfd); + close(fd); return 0; } -/* 执行用例前先执行ifconfig xxx up,xxx表示网卡名,比如eth0,wlan0 */ int main(int argc, char **argv) { int ret; - int32_t ifindex = 0; - const char ifname[] = {"eth0"}; // eth0, wlan0可选,根据实际接口修改 - uint8_t client_addr[INDEX_1] = {0x50}; // 客户端1字节地址: 0x50 - uint8_t server_addr[INDEX_2] = {0xDE, 0x00}; // 服务端2字节地址: 0xDE00 + 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; @@ -87,19 +105,19 @@ int main(int argc, char **argv) return -1; } - ret = nip_get_ifindex(ifname, &ifindex); + ret = nip_get_ifindex(NIC_NAME, &ifindex); if (ret != 0) { - printf("get %s ifindex fail, ret=%d.\n", ifname, ret); + 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", ifname, ret); + printf("get %s ifindex fail, ret=%d.\n", NIC_NAME, ret); return -1; } - printf("%s %s(ifindex=%u) cfg route success.\n", *argv, ifname, ifindex); + 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 index f8b2c87..5344e2b 100644 --- a/examples/nip_tcp_client_demo.c +++ b/examples/nip_tcp_client_demo.c @@ -1,8 +1,28 @@ -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * NewIP INET socket protocol family + * 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 @@ -14,109 +34,104 @@ #include #include -#include "nip_linux.h" +#include "nip_uapi.h" +#include "nip_lib.h" #include "newip_route.h" #define __USE_GNU #include #include -#define BUFLEN 4096 -#define LISTEN_MAX 3 -#define PORT 5556 // 服务端端口 -#define PKTCNT 10 // 发送报文个数 -#define PKTLEN 1024 // 发送报文长度 -#define SLEEP_US 500000 // 发包间隔(ms) -#define SELECT_TIME 600 - -struct thread_args { - int s; - struct sockaddr_nin si_server; -}; - void *send_recv(void *args) { - int ret; char buf[BUFLEN]; - fd_set readfds; - struct timeval tv, stTime; + 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; - int s = th_args->s; struct sockaddr_nin si_server = th_args->si_server; - for (int i; i < PKTCNT; i++) { + 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(s, buf, PKTLEN, 0) < 0) + if (send(cfd, buf, PKTLEN, 0) < 0) { perror("send"); + goto END; + } FD_ZERO(&readfds); - FD_SET(s, &readfds); + FD_SET(cfd, &readfds); tv.tv_sec = SELECT_TIME; tv.tv_usec = 0; - if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) + if (select(cfd + 1, &readfds, NULL, NULL, &tv) < 0) { perror("select"); + goto END; + } - if (FD_ISSET(s, &readfds)) { + if (FD_ISSET(cfd, &readfds)) { memset(buf, 0, BUFLEN); - ret = recv(s, buf, PKTLEN, MSG_WAITALL); + 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, s, success, count + 1, no); + buf, cfd, success, count + 1, no); } else { printf("recv fail, ret=%d\n", ret); + goto END; } } count += 1; usleep(SLEEP_US); } - close(s); + +END: return NULL; } int main(int argc, char **argv) { - int s; + int cfd; pthread_t th; struct thread_args th_args; struct sockaddr_nin si_server; - s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); - if (s < 0) { + cfd = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); + if (cfd < 0) { perror("socket"); return -1; } - printf("creat newip socket, fd=%d\n", s); + 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(PORT); - // 服务端2字节地址: 0xDE00 + 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字节:16bit - if (connect(s, (struct sockaddr *)&si_server, sizeof(si_server)) < 0) { + 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], PORT); + 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(PORT); - th_args.s = s; + 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(s); + close(cfd); return 0; } diff --git a/examples/nip_tcp_server_demo.c b/examples/nip_tcp_server_demo.c index 6f7ad11..f0ef196 100644 --- a/examples/nip_tcp_server_demo.c +++ b/examples/nip_tcp_server_demo.c @@ -1,8 +1,28 @@ -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * NewIP INET socket protocol family + * 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 @@ -14,82 +34,79 @@ #include #include -#include "nip_linux.h" +#include "nip_uapi.h" +#include "nip_lib.h" #include "newip_route.h" -#define BUFLEN 4096 -#define PKTCNT_SCALE 2 -#define LISTEN_MAX 3 -#define PORT 5556 // 服务端端口 -#define PKTCNT 10 // 发送报文个数 -#define PKTLEN 1024 // 发送报文长度 - void *recv_send(void *args) { char buf[BUFLEN] = {0}; - int client, i, err; + int cfd, ret; - memcpy(&client, args, sizeof(int)); - for (i = 0; i < PKTCNT * PKTCNT_SCALE; i++) { - int recvNum = recv(client, buf, PKTLEN, MSG_WAITALL); + memcpy(&cfd, args, sizeof(int)); + for (int i = 0; i < PKTCNT; i++) { + int recv_num = recv(cfd, buf, PKTLEN, MSG_WAITALL); - if (recvNum <= 0) { + if (recv_num < 0) { perror("recv"); + goto END; + } else if (recv_num == 0) { /* no data */ + ; } else { - printf("Received -- %s --:%d\n", buf, recvNum); - err = send(client, buf, recvNum, 0); - if (err < 0) { + printf("Received -- %s --:%d\n", buf, recv_num); + ret = send(cfd, buf, recv_num, 0); + if (ret < 0) { perror("send"); - break; + goto END; } - printf("Sending -- %s --:%d\n", buf, recvNum); + printf("Sending -- %s --:%d\n", buf, recv_num); } } - close(client); +END: close(cfd); + return NULL; } int main(int argc, char **argv) { pthread_t th; - int s, fd, addr_len; + int fd, cfd, addr_len; struct sockaddr_nin si_local; struct sockaddr_nin si_remote; - s = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); - if (s < 0) { + fd = socket(AF_NINET, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) { perror("socket"); return -1; } - printf("creat newip socket, fd=%d\n", s); memset((char *)&si_local, 0, sizeof(si_local)); si_local.sin_family = AF_NINET; - si_local.sin_port = htons(PORT); - // 服务端2字节地址: 0xDE00 + 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字节:16bit + si_local.sin_addr.bitlen = NIP_ADDR_BIT_LEN_16; // 2-byte: 16bit - if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { + if (bind(fd, (const struct sockaddr *)&si_local, sizeof(si_local)) < 0) { perror("bind"); - return -1; + 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], PORT); + si_local.sin_addr.nip_addr_field8[INDEX_1], TCP_SERVER_PORT); - if (listen(s, LISTEN_MAX) < 0) { + if (listen(fd, LISTEN_MAX) < 0) { perror("listen"); - return -1; + goto END; } - printf("listen success.\n"); addr_len = sizeof(si_remote); memset(&si_remote, 0, sizeof(si_remote)); - fd = accept(s, (struct sockaddr *)&si_remote, (socklen_t *)&addr_len); - pthread_create(&th, NULL, recv_send, &fd); - pthread_join(th, NULL); // 等待线程结束, 线程间同步的操作 - close(s); + 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_linux.h b/examples/nip_uapi.h similarity index 30% rename from examples/nip_linux.h rename to examples/nip_uapi.h index 2ca6bd5..6475ff3 100644 --- a/examples/nip_linux.h +++ b/examples/nip_uapi.h @@ -1,25 +1,39 @@ -/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * Linux NewIP INET implementation + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * 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_LINUX_H -#define _NIP_LINUX_H +#ifndef _NIP_UAPI_H +#define _NIP_UAPI_H -#include #include "nip.h" -// AF_NINET可通过读取 /sys/module/newip/parameters/af_ninet 文件来获取类型数值。 +/* 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 // DEMO程序包含1个入参S +#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 @@ -39,4 +53,9 @@ struct nip_ifreq { int ifrn_ifindex; }; -#endif /*_NIP_LINUX_H*/ +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 index 0e81c7c..7bd6d30 100644 --- a/examples/nip_udp_client_demo.c +++ b/examples/nip_udp_client_demo.c @@ -1,8 +1,28 @@ -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * NewIP INET socket protocol family + * 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 @@ -16,97 +36,96 @@ #include #include -#include "nip_linux.h" +#include "nip_uapi.h" +#include "nip_lib.h" #include "newip_route.h" -#define BUFLEN 4096 -#define PKT_NUM 10 // 收发包次数 -#define SLEEP_US 500000 // 发包间隔(ms) -#define PORT 9090 - -struct thread_args { - int s; - struct sockaddr_nin si_server; -}; - void *send_recv(void *args) { - int ret; char buf[BUFLEN]; + int cfd, ret; fd_set readfds; - struct timeval tv; int success = 0; int count = 0; int no = 0; - struct timeval stTime; int sendtime_sec, sendtime_usec; + struct timeval tv; + struct timeval stTime; struct thread_args *th_args = (struct thread_args *)args; - int s = th_args->s; struct sockaddr_nin si_server = th_args->si_server; - while (count < PKT_NUM) { + 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(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, slen) < 0) + if (sendto(cfd, buf, BUFLEN, 0, (struct sockaddr *)&si_server, slen) < 0) { perror("sendto"); + goto END; + } FD_ZERO(&readfds); - FD_SET(s, &readfds); + FD_SET(cfd, &readfds); tv.tv_sec = 2; tv.tv_usec = 0; - if (select(s + 1, &readfds, NULL, NULL, &tv) < 0) + if (select(cfd + 1, &readfds, NULL, NULL, &tv) < 0) { perror("select"); + goto END; + } - if (FD_ISSET(s, &readfds)) { + if (FD_ISSET(cfd, &readfds)) { memset(buf, 0, BUFLEN); - ret = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_server, &slen); + 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, s, success, count + 1, no); + 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 s; + int cfd; pthread_t th; struct thread_args th_args; struct sockaddr_nin si_server; - s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP); - if (s < 0) { + 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(PORT); - // 服务端2字节地址: 0xDE00 + 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字节:16bit + 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(PORT); - th_args.s = s; + 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(s); + close(cfd); return 0; } diff --git a/examples/nip_udp_server_demo.c b/examples/nip_udp_server_demo.c index 2c3dffe..c1268f3 100644 --- a/examples/nip_udp_server_demo.c +++ b/examples/nip_udp_server_demo.c @@ -1,8 +1,28 @@ -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2022 Huawei Device Co., Ltd. * - * NewIP INET socket protocol family + * 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 @@ -12,61 +32,79 @@ #include #include -#include "nip_linux.h" +#include "nip_uapi.h" +#include "nip_lib.h" #include "newip_route.h" -#define BUFLEN 1024 -#define PORT 9090 - -int main(int argc, char **argv) +void *recv_send(void *args) { - int s; + char buf[BUFLEN] = {0}; + int fd, ret, recv_num; + int count = 0; socklen_t slen; - char buf[BUFLEN]; - int recvNum; struct sockaddr_nin si_local, si_remote; - s = socket(AF_NINET, SOCK_DGRAM, IPPROTO_UDP); - if (s == -1) { - perror("socket"); - return -1; - } - - memset((char *)&si_local, 0, sizeof(si_local)); - si_local.sin_family = AF_NINET; - si_local.sin_port = htons(PORT); - // 服务端2字节地址: 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字节:16bit - - if (bind(s, (const struct sockaddr *)&si_local, sizeof(si_local)) == -1) { - perror("bind"); - close(s); - return -1; - } - - while (1) { + 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)); - recvNum = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, &slen); - if (recvNum <= 0) { + 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); - if (sendto(s, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, slen) == -1) { + ret = sendto(fd, buf, BUFLEN, 0, (struct sockaddr *)&si_remote, slen); + if (ret < 0) { perror("sendto"); - break; + 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; + 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); - close(s); +END: close(fd); return 0; } -- Gitee From e318a163b44fd80948260a8d69da90d3732081f9 Mon Sep 17 00:00:00 2001 From: yangyanjun Date: Mon, 5 Sep 2022 10:17:16 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=9C=B0=E5=9D=80=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E8=B7=AF=E7=94=B1=E9=85=8D=E7=BD=AE=EF=BC=8Ctcp?= =?UTF-8?q?=E6=94=B6=E5=8F=91=E5=8C=85demo=E5=BD=92=E6=A1=A3(=E6=A3=80?= =?UTF-8?q?=E8=A7=86=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9=EF=BC=8C=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E7=B1=BB=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangyanjun --- examples/nip_udp_server_demo.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/nip_udp_server_demo.c b/examples/nip_udp_server_demo.c index c1268f3..612b3e8 100644 --- a/examples/nip_udp_server_demo.c +++ b/examples/nip_udp_server_demo.c @@ -32,6 +32,10 @@ #include #include +#define __USE_GNU +#include +#include + #include "nip_uapi.h" #include "nip_lib.h" #include "newip_route.h" @@ -75,6 +79,7 @@ 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); -- Gitee From 80ec2ed75609ff17d35e6a167c9d0eeb88c69311 Mon Sep 17 00:00:00 2001 From: yangyanjun Date: Mon, 5 Sep 2022 11:52:01 +0800 Subject: [PATCH 5/5] =?UTF-8?q?demo=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E9=85=8D=E5=A5=97=E5=8A=9F=E8=83=BD=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A3=80=E8=A7=86=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9=EF=BC=8C?= =?UTF-8?q?debug=E4=BF=A1=E6=81=AF=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangyanjun --- code/common/nip_addr.h | 15 +++++++-------- code/linux/net/newip/nip_output.c | 4 ++-- code/linux/net/newip/route.c | 20 ++++++++++++-------- examples/nip.h | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/code/common/nip_addr.h b/code/common/nip_addr.h index 552fd4c..68f8de9 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 a108419..d394937 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 6fe8365..33af9c1 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/nip.h b/examples/nip.h index 2c1c267..2dff039 100644 --- a/examples/nip.h +++ b/examples/nip.h @@ -81,7 +81,7 @@ struct nip_addr_field { }; struct nip_addr { - unsigned char bitlen; + unsigned char bitlen; /* The address length is in bit (not byte) */ struct nip_addr_field v; }; #pragma pack() -- Gitee