├── .gitignore ├── Kconfig ├── LICENSE ├── README.en.md ├── README.md ├── SConscript ├── TcpServerForStackTesting ├── .gitignore ├── ReadMe.txt ├── TcpServerForStackTesting.vcxproj ├── main.cpp ├── stdafx.cpp ├── stdafx.h ├── targetver.h ├── tcp_helper.cpp └── tcp_helper.h ├── alipayn.jpg ├── bsd └── socket.c ├── ethernet ├── arp.c ├── dhcp_client.c ├── dhcp_client_by_timer.c ├── dhcpv6.c └── ethernet.c ├── include ├── bsd │ └── socket.h ├── ethernet │ ├── arp.h │ ├── arp_frame.h │ ├── dhcp_client.h │ ├── dhcp_client_by_timer.h │ ├── dhcp_frame.h │ ├── dhcpv6.h │ ├── dhcpv6_frame.h │ ├── ethernet.h │ ├── ethernet_frame.h │ └── ethernet_protocols.h ├── ip │ ├── icmp.h │ ├── icmp_frame.h │ ├── icmpv6.h │ ├── icmpv6_frame.h │ ├── ip.h │ ├── ip_frame.h │ ├── ipv6_configure.h │ ├── tcp.h │ ├── tcp_frame.h │ ├── tcp_link.h │ ├── tcp_options.h │ ├── udp.h │ ├── udp_frame.h │ └── udp_link.h ├── mmu │ ├── buddy.h │ └── buf_list.h ├── net_tools │ ├── dns.h │ ├── net_virtual_terminal.h │ ├── ping.h │ ├── sntp.h │ ├── telnet.h │ ├── telnet_client.h │ └── telnet_srv.h ├── netif │ ├── netif.h │ └── route.h ├── one_shot_timer.h ├── onps.h ├── onps_errors.h ├── onps_input.h ├── onps_md5.h ├── onps_utils.h ├── ppp │ ├── chap.h │ ├── chat.h │ ├── ipcp.h │ ├── lcp.h │ ├── negotiation.h │ ├── negotiation_storage.h │ ├── pap.h │ ├── ppp.h │ ├── ppp_frame.h │ ├── ppp_protocols.h │ ├── ppp_utils.h │ ├── tty.h │ └── wait_ack_list.h └── protocols.h ├── ip ├── icmp.c ├── icmpv6.c ├── ip.c ├── ipv6_configure.c ├── tcp.c ├── tcp_link.c ├── tcp_options.c ├── udp.c └── udp_link.c ├── mmu ├── buddy.c └── buf_list.c ├── net_tools ├── dns.c ├── net_virtual_terminal.c ├── ping.c ├── sntp.c ├── telnet.c ├── telnet_client.c └── telnet_srv.c ├── netif ├── netif.c └── route.c ├── one_shot_timer.c ├── onps_entry.c ├── onps_errors.c ├── onps_input.c ├── onps_md5.c ├── onps_utils.c ├── onps栈API接口手册.pdf ├── onps栈架构图.jpg ├── onps栈用户使用手册.pdf ├── onps栈移植手册.pdf ├── onps网络协议栈技术交流群群二维码.png ├── onps网络协议栈移植及使用说明.pdf ├── package.json ├── port ├── include │ ├── port │ │ ├── datatype.h │ │ ├── os_adapter.h │ │ ├── os_datatype.h │ │ └── sys_config.h │ └── telnet │ │ ├── nvt_cmd.h │ │ └── os_nvt.h ├── os_adapter.c └── telnet │ ├── nvt_cmd.c │ └── os_nvt.c ├── ppp ├── .gitignore ├── chap.c ├── chat.c ├── ipcp.c ├── lcp.c ├── negotiation.c ├── pap.c ├── ppp.c ├── ppp_utils.c ├── tty.c └── wait_ack_list.c ├── tencentpay.jpg └── test_code └── pppd.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | .codelite/ 54 | open-npstack.workspace 55 | Makefile 56 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | 2 | # Kconfig file for package onps 3 | menuconfig PKG_USING_ONPS 4 | bool "Onps: An open-source network protocol stack." 5 | default n 6 | 7 | if PKG_USING_ONPS 8 | 9 | config PKG_ONPS_PATH 10 | string 11 | default "/packages/system/onps" 12 | 13 | choice 14 | prompt "Onps Version" 15 | default PKG_USING_ONPS_LATEST_VERSION 16 | help 17 | Select the package version 18 | 19 | config PKG_USING_ONPS_V110 20 | bool "v1.1.0" 21 | 22 | config PKG_USING_ONPS_LATEST_VERSION 23 | bool "latest" 24 | endchoice 25 | 26 | config PKG_ONPS_VER 27 | string 28 | default "v1.1.0" if PKG_USING_ONPS_V110 29 | default "latest" if PKG_USING_ONPS_LATEST_VERSION 30 | 31 | endif 32 | 33 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | # Open-NPStack 2 | 3 | #### Description 4 | 开源的网络协议栈(/IP/TCP/UDP/PPP等),适用于资源受限的嵌入式系统,使用ANSI C/C++开发 5 | 6 | #### Software Architecture 7 | Software architecture description 8 | 9 | #### Installation 10 | 11 | 1. xxxx 12 | 2. xxxx 13 | 3. xxxx 14 | 15 | #### Instructions 16 | 17 | 1. xxxx 18 | 2. xxxx 19 | 3. xxxx 20 | 21 | #### Contribution 22 | 23 | 1. Fork the repository 24 | 2. Create Feat_xxx branch 25 | 3. Commit your code 26 | 4. Create Pull Request 27 | 28 | 29 | #### Gitee Feature 30 | 31 | 1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md 32 | 2. Gitee blog [blog.gitee.com](https://blog.gitee.com) 33 | 3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) 34 | 4. The most valuable open source project [GVP](https://gitee.com/gvp) 35 | 5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) 36 | 6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # onps网络协议栈 2 | 3 | #### 背景 4 | 大约是06年,因项目之需我开始接触应用于单片机系统的国外开源tcp/ip协议栈——LwIP,并借此顺势创作了我的第一本印成铅字的书——《嵌入式网络系统设计——基于Atmel ARM7系列》。这本书的反响还不错,好多人给我发msn(可惜这么好的一个即时通讯工具就这么被微软放弃了,好多联系人就此失联, :persevere: )或邮件咨询相关问题。在我原来的写作计划中,这本书的出版只是一个开始,接下来还要写第二本——系统介绍LwIP包含的ppp协议栈的移植、应用及设计实现等相关内容。但,事与愿违,这本书跳票了,且这一跳就是十二年…… 5 | 6 | 细细想来,当初跳票的主因有二:其一,因家庭、工作等致可支配时间太少;其二,缺乏足够的ppp协议相关知识及技术储备致信心不足,畏首畏尾,裹足不前。但,这件事始终是我的一个遗憾。十二年的时间,不长亦不短,但足够让心底的遗憾变成一粒小小的种子并茁壮成长为一棵梦想的参天大树。 7 | 8 | 如今,世界来到了疫情肆虐的二零年代。我的可支配时间多了起来,技术能力亦远非当年可比。梦想之树到了开花结果的时候了。遥想当初,入行还没几年,技术能力有限,我只能站在大神的肩膀上研究如何移植、使用LwIP,ppp栈碰都没敢碰。现在,如果还只是延续十几年前的工作,那这件事做起来就无甚意义。基于对自身技术实力的准确认识,我决定自己从零开始搭建一个完整的网络协议栈。终,历6个月余,onps协议栈(onps,open net protocol stack)完成初版开发,并内部测试通过。十余年的遗憾今日得偿。另,从业20余年,内心终有一个做核心基础软件的梦。今,这二之梦想亦借此得偿。 9 | 10 | 新莺初啼,总免不了会有诸多不尽如人意的地方。开源,则可与志趣相投者共享、共用、共研,历诸位严苛手段使之快速迭代,快速成熟,比肩LwIP可期 :blush: 。 11 | 12 | 13 | #### 简介 14 | onps是一个开源且完全自主开发的国产网络协议栈,适用于资源受限的单片机系统,提供完整地ethernet/ppp/tcp/ip协议族实现,同时提供sntp、dns、ping等网络工具,支持以太网环境下dhcp动态ip地址申请,也支持动态及静态路由表。协议栈还封装实现了一个伯克利套接字(Berkeley sockets)层。该层并没有完全按照Berkeley sockets标准设计实现,而是我根据以往socket编程经验,以方便用户使用、简化用户编码为设计目标,重新声明并定义了一组常见socket接口函数: 15 | - socket:创建一个socket,目前仅支持udp和tcp两种类型 16 | - close:关闭一个socket,释放当前占用的协议栈资源 17 | - connect:与目标tcp服务器建立连接(阻塞型)或绑定一个固定的udp服务器地址 18 | - connect_nb:与目标tcp服务器建立连接(非阻塞型) 19 | - is_tcp_connected:获取当前tcp链路的连接状态 20 | - send:数据发送函数,tcp链路下为阻塞型 21 | - send_nb:数据发送函数,非阻塞型 22 | - is_tcp_send_ok:数据是否已成功送达tcp链路的对端(收到tcp ack报文) 23 | - sendto:udp数据发送函数,发送数据到指定目标地址 24 | - recv:数据接收函数,udp/tcp链路通用 25 | - recvfrom:数据接收函数,用于udp链路,接收数据的同时函数会返回数据源的地址信息 26 | - socket_set_rcv_timeout:设定recv()函数接收等待的时长,单位:秒 27 | - bind:绑定一个固定端口、地址 28 | - listen:tcp服务器进入监听状态 29 | - accept:接受一个到达的tcp连接请求 30 | - tcpsrv_recv_poll:tcp服务器专用函数,等待任意一个或多个tcp客户端数据到达信号 31 | - socket_get_last_error:获取socket最近一次发生的错误信息 32 | - socket_get_last_error_code:获取socket最近一次发生的错误编码 33 | 34 | 协议栈简化了传统BSD socket编程需要的一些繁琐操作,将一些不必要的操作细节改为底层实现,比如select/poll模型、阻塞及非阻塞读写操作等。简化并不意味着推翻,socket接口函数的基本定义、主要参数、使用方法并没有改变,你完全可以根据以往经验及编程习惯快速上手并熟练使用onps栈sockets。 **无须过多关注协议栈底层,利用socket api编程即可完全满足复杂通讯应用的需求,而不像LwIp一样需要使用它自定义的一组接口函数才能达成同样的目标。** 35 | 36 | 为了适应单片机系统对内存使用极度变态的苛刻要求,onps协议栈在设计之初即考虑采用写时零复制(zero copy)技术。用户层数据在向下层协议传递过程中,协议栈采用buf list链表技术将它们链接到一起,直至将其发送出去,均无须任何内存复制操作。另外,协议栈采用buddy算法提供安全、可靠的动态内存管理功能,以期最大限度地提高协议栈运行过程中的内存利用率并尽可能地减少内存碎片。 37 | 38 | 不同于本世纪00到10年代初,单片机的应用场景中ucosii等rtos尚未大规模普及,前后台系统还大行其道的时代,现如今大部分的应用场景下开发人员选择使用rtos已成为主流。因此,协议栈在设计之初即不支持前后台模式,其架构设计建立在时下流行的rtos(RT-Thread、ucosii/iii等)之上。协议栈移植的主要工作也就自然是针对不同rtos编写相关os适配层功能函数了。当然,如果你有着极其特定的应用场景,需要将onps栈移植到采用前后台模式的单片机上,我的建议是保留tcp/udp之下协议层的通讯处理逻辑,调整上层的系统架构使其适应目标系统运行模式。 39 | 40 | #### 软件架构 41 | onps栈设计实现了一套完整的tcp/ip协议模型。从数据链路层到ip层,再到tcp/udp层以及之上的伯克利socket层,最后是用户自己的通讯应用层,onps栈实现了全栈覆盖,能够满足绝大部分的网络编程需求。其架构如下: 42 | ![onps栈架构](onps%E6%A0%88%E6%9E%B6%E6%9E%84%E5%9B%BE.jpg) 43 | 44 | 可以看出,其与传统的网络编程模型并没有什么不同,用户仍然是继续利用socket api编写常见的tcp及udp网络应用。同时你还可以利用协议栈提供的几个网络工具进行网络校时、dns查询等操作。 45 | 46 | #### 目录结构 47 | 48 | | 名称 | 描述 | 49 | |---|---| 50 | | bsd | 伯克利sockets层的相关接口函数实现源文件 | 51 | | ethernet | 以太网协议族如ethernet-ii/arp及emac层、dhcp客户端等的相关实现源文件 | 52 | | include | 协议栈的头文件 | 53 | | ip | ip及其上层icmp/tcp/udp协议族的相关实现源文件 | 54 | | mmu | 协议栈内存管理模块的相关实现源文件 | 55 | | net_tools | 网络工具实现源文件,如dns查询、网络校时、ping、telnet等 | 56 | | netif | 网卡及路由管理等相关接口实现源文件 | 57 | | port | 协议栈移植相关的源文件 | 58 | | ppp | ppp链路层相关实现源文件,包括lcp/ipcp/chap/pap等协议族的实现源文件 | 59 | | TcpServerForStackTesting | 用于协议栈测试的tcp服务器,IDE为vs2015开发,目标系统为win7及以上 | 60 | | test_code | linux下的ppp拨号原理验证文件 | 61 | 62 | 63 | #### 移植及使用说明 64 | 65 | 协议栈支持主流的ARM Cortex系列MCU,支持Keil MDK、IAR等常见IDE。移植的核心工作就是完成RTOS模拟层的编写及适配,详细的移植说明请参考《onps网络协议栈移植及使用说明v1.0》一文,点此[下载](https://gitee.com/Neo-T/open-npstack/releases/download/v1.0.0.221017/onps%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE%E6%A0%88%E7%A7%BB%E6%A4%8D%E5%8F%8A%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8Ev1.0.7z)。本说明提供了STM32F103RCT6及STM32F407VET6两种硬件平台的移植样例,每种样例分别针对RT-Thread和ucosii两种RTOS。样例工程经过了严格的内部测试,可以直接使用。 66 | 67 | 如果你没有太多时间,或者样例工程与你的目标平台并不匹配,你可以直接参考协议栈移植的一般性指导文件[《onps栈移植手册》](https://gitee.com/Neo-T/open-npstack/raw/master/onps%E6%A0%88%E7%A7%BB%E6%A4%8D%E6%89%8B%E5%86%8C.pdf)。 68 | 69 | 协议栈开发的一般性指导文件请参考[《onps栈API接口手册》](https://gitee.com/Neo-T/open-npstack/raw/master/onps%E6%A0%88API%E6%8E%A5%E5%8F%A3%E6%89%8B%E5%86%8C.pdf)及[《onps栈用户使用手册》](https://gitee.com/Neo-T/open-npstack/raw/master/onps%E6%A0%88%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C.pdf)。 70 | 71 | #### 移植样例 72 | **STM32F407VET6平台** : 73 | [RT-Thread移植样例](https://gitee.com/Neo-T/onps-rtthread) [ucos-ii移植样例](https://gitee.com/Neo-T/onps-ucosii) 74 | 75 | **[沁恒CH32V307平台](https://gitee.com/Neo-T/Onps-WCH-CH32V307)** : 76 | [鸿蒙LiteOS-M移植样例](https://gitee.com/Neo-T/Onps-WCH-CH32V307/tree/master/HarmonyOS/LiteOS_m) [Free-rtos移植样例](https://gitee.com/Neo-T/Onps-WCH-CH32V307/tree/master/FreeRTOS) [RT-Thread移植样例](https://gitee.com/Neo-T/Onps-WCH-CH32V307/tree/master/rt-thread) 77 | 78 | #### 社区支持 79 | 80 | 您可以随时访问[ **onps栈官方网站** ](http://www.onps.org.cn),获取协议栈研发进度、后续计划、最新版本等相关信息。
如您在使用过程中遇到任何问题或建议,您可以到 **[onps栈交流社区](http://neo.onps.org.cn)** 提出您的建议或问题,新版本发布也会在交流社区第一时间通知。
您也可以加入QQ群进行在线技术交流:
81 | ![qq交流群](onps%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE%E6%A0%88%E6%8A%80%E6%9C%AF%E4%BA%A4%E6%B5%81%E7%BE%A4%E7%BE%A4%E4%BA%8C%E7%BB%B4%E7%A0%81.png) 82 | 83 | #### 许可协议 84 | 85 | Apache License 2.0开源许可协议 86 | 87 | #### 通过OSCS安全认证 88 | [![Security Status](https://www.murphysec.com/platform3/v3/badge/1615596818625232896.svg?t=1)](https://www.murphysec.com/accept?code=64bea0edfe145ac454cc464b23659406&type=1&from=2&t=2) 89 | 90 | #### 后续计划 91 | - 更多目标平台的适配工作, 提供相应移植样例 92 | - 重构部分代码, 进一步降低代码尺寸及内存消耗 93 | - 支持ftp客户端/服务器 94 | - 支持http客户端/服务器 95 | 96 | #### 捐赠 97 | 98 | 为了项目能够持续下去,期望得到您的支持,您可以扫描下面的二维码通过支付宝/微信向本项目捐款: 99 | 100 | ![支付宝](alipayn.jpg) ![微信](tencentpay.jpg) -------------------------------------------------------------------------------- /SConscript: -------------------------------------------------------------------------------- 1 | from building import * 2 | 3 | cwd = GetCurrentDir() 4 | path = [cwd + '/include'] 5 | path += [cwd + '/port/include'] 6 | src = ['one_shot_timer.c', 'onps_entry.c', 'onps_errors.c', 'onps_input.c', 'onps_utils.c'] 7 | 8 | src += ['bsd/socket.c', 'ethernet/arp.c', 'ethernet/ethernet.c', 'ip/icmp.c', 'ip/ip.c', 'ip/tcp.c', 'ip/tcp_link.c', 'ip/tcp_options.c', 'ip/udp.c', 'ip/udp_link.c'] 9 | src += ['mmu/buddy.c', 'mmu/buf_list.c', 'netif/netif.c', 'netif/route.c'] 10 | src += ['port/os_adapter.c'] 11 | src += ['port/include/port/datatype.h', 'port/include/port/os_datatype.h', 'port/include/port/os_adapter.h', 'port/include/port/sys_config.h'] 12 | 13 | group = DefineGroup('onps', src, depend = ['PKG_USING_ONPS'], CPPPATH = path) 14 | 15 | Return('group') 16 | -------------------------------------------------------------------------------- /TcpServerForStackTesting/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | *.filters 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush 296 | .cr/ 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | -------------------------------------------------------------------------------- /TcpServerForStackTesting/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | 控制台应用程序:TcpServerForStackTesting 项目概述 3 | ======================================================================== 4 | 5 | 应用程序向导已为您创建了此 TcpServerForStackTesting 应用程序。 6 | 7 | 本文件概要介绍组成 TcpServerForStackTesting 应用程序的每个文件的内容。 8 | 9 | 10 | TcpServerForStackTesting.vcxproj 11 | 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 12 | 13 | TcpServerForStackTesting.vcxproj.filters 14 | 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 15 | 16 | TcpServerForStackTesting.cpp 17 | 这是主应用程序源文件。 18 | 19 | ///////////////////////////////////////////////////////////////////////////// 20 | 其他标准文件: 21 | 22 | StdAfx.h, StdAfx.cpp 23 | 这些文件用于生成名为 TcpServerForStackTesting.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 24 | 25 | ///////////////////////////////////////////////////////////////////////////// 26 | 其他注释: 27 | 28 | 应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 29 | 30 | ///////////////////////////////////////////////////////////////////////////// 31 | -------------------------------------------------------------------------------- /TcpServerForStackTesting/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : 只包括标准包含文件的源文件 2 | // TcpServerForStackTesting.pch 将作为预编译头 3 | // stdafx.obj 将包含预编译类型信息 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: 在 STDAFX.H 中引用任何所需的附加头文件, 8 | //而不是在此文件中引用 9 | -------------------------------------------------------------------------------- /TcpServerForStackTesting/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : 标准系统包含文件的包含文件, 2 | // 或是经常使用但不常更改的 3 | // 特定于项目的包含文件 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料 11 | #include 12 | #include 13 | 14 | 15 | 16 | // TODO: 在此处引用程序需要的其他头文件 17 | -------------------------------------------------------------------------------- /TcpServerForStackTesting/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 4 | 5 | // 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将 6 | // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /TcpServerForStackTesting/tcp_helper.h: -------------------------------------------------------------------------------- 1 | /* tcp_helper.h 2 | * 3 | * tcp协议相关的功能函数库,基于windows平台 4 | * 5 | * Neo-T, 创建于2022.05.18 09:19 6 | * 7 | */ 8 | #ifndef TCPHELPER_H 9 | #define TCPHELPER_H 10 | 11 | #ifdef SYMBOL_GLOBALS 12 | #define TCPHELPER_EXT 13 | #else 14 | #define TCPHELPER_EXT extern 15 | #endif //* SYMBOL_GLOBALS 16 | 17 | typedef CRITICAL_SECTION THMUTEX; 18 | #define WSALIB_VER MAKEWORD(2, 2) //* 要加载的WSA库的版本 19 | 20 | #define SUPPORT_IPv6 0 //* 如果选择ipv6协议,则置位,否则使用ipv4 21 | 22 | #pragma pack(push) 23 | #pragma pack(1) //* 设置为1字节对齐 24 | #define PKT_FLAG 0xEE 25 | typedef struct _ST_COMMUPKT_HDR_ { 26 | CHAR bFlag; 27 | CHAR bCmd; 28 | CHAR bLinkIdx; 29 | UINT unSeqNum; 30 | UINT unTimestamp; 31 | USHORT usDataLen; 32 | USHORT usChechsum; 33 | } ST_COMMUPKT_HDR, *PST_COMMUPKT_HDR; 34 | 35 | typedef struct _ST_COMMUPKT_ACK_ { 36 | ST_COMMUPKT_HDR stHdr; 37 | UINT unTimestamp; 38 | CHAR bLinkIdx; 39 | CHAR bTail; 40 | } ST_COMMUPKT_ACK, *PST_COMMUPKT_ACK; 41 | #pragma pack(pop) 42 | 43 | TCPHELPER_EXT INT load_socket_lib(USHORT usVer, CHAR *pbLoadNum); 44 | TCPHELPER_EXT BOOL load_socket_lib(void); 45 | TCPHELPER_EXT void unload_socket_lib(void); 46 | TCPHELPER_EXT SOCKET start_tcp_server(USHORT usPort, UINT unListenNum); 47 | TCPHELPER_EXT void stop_tcp_server(SOCKET hSocket); 48 | TCPHELPER_EXT SOCKET accept_client(SOCKET hSocket); 49 | TCPHELPER_EXT USHORT crc16(const UCHAR *pubCheckData, UINT unCheckLen, USHORT usInitVal); 50 | TCPHELPER_EXT void thread_lock_init(THMUTEX *pthMutex); 51 | TCPHELPER_EXT void thread_lock_uninit(THMUTEX *pthMutex); 52 | TCPHELPER_EXT void thread_lock_enter(THMUTEX *pthMutex); 53 | TCPHELPER_EXT void thread_lock_leave(THMUTEX *pthMutex); 54 | TCPHELPER_EXT void unix_time_to_local(time_t tUnixTimestamp, CHAR *pszDatetime, UINT unDatetimeBufSize); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /alipayn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/alipayn.jpg -------------------------------------------------------------------------------- /include/bsd/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.26 10:26 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 伯克利套接字(Berkeley sockets)非标准且不完全实现,按照传统socket编程思想并结合实际应用经验实现的用户层TCP、UDP通讯接口函数,简化了 12 | * 传统BSD socket需要的一些繁琐的操作,将一些不必要的操作细节改为底层实现,比如select模型、阻塞及非阻塞读写操作等 13 | * 14 | */ 15 | #ifndef SOCKET_H 16 | #define SOCKET_H 17 | 18 | #ifdef SYMBOL_GLOBALS 19 | #define SOCKET_EXT 20 | #else 21 | #define SOCKET_EXT extern 22 | #endif //* SYMBOL_GLOBALS 23 | #include "onps_input.h" 24 | 25 | typedef INT SOCKET; //* socket句柄 26 | #define INVALID_SOCKET -1 //* 无效的SOCKET 27 | 28 | //* tcp链路标志位相关定义 29 | //* ================================================= 30 | #define TLF_NO_DELAY_ACK 0x0001 //* 立即回馈应答而不是等一小段时间或有数据需要发送时(200毫秒)再回馈 31 | //* ================================================= 32 | 33 | //* 参数family仅支持AF_INET,其它不支持,type仅支持SOCK_STREAM、SOCK_DGRAM两种协议,protocol固定为0 34 | SOCKET_EXT SOCKET socket(INT family, INT type, INT protocol, EN_ONPSERR *penErr); 35 | SOCKET_EXT void close(SOCKET socket); 36 | 37 | //* 连接函数,阻塞型,直至连接成功或超时,返回0意味着连接成功,-1则意味着连接失败,具体的错误信息通过onps_get_last_error()函数 38 | //* 获得,注意,nConnTimeout参数必须大于0,小于等于0则函数直接返回,相当于调用connect_nb()函数 39 | SOCKET_EXT INT connect(SOCKET socket, const CHAR *srv_ip, USHORT srv_port, INT nConnTimeout); 40 | 41 | //* 功能同上,入口参数与之稍微有些区别,connect()函数的srv_ip参数指向可读的ip地址字符串,connect_ext()函数的srv_ip参数指向的则是 42 | //* inet_addr()/inet6_aton()函数转换后的16进制的实际地址 43 | SOCKET_EXT INT connect_ext(SOCKET socket, void *srv_ip, USHORT srv_port, INT nConnTimeout); 44 | 45 | //* 非阻塞连接函数,连接成功返回0,连接中会一直返回1,返回-1则意味着连接失败,具体的错误信息通过onps_get_last_error()函数获得 46 | SOCKET_EXT INT connect_nb(SOCKET socket, const CHAR *srv_ip, USHORT srv_port); 47 | 48 | //* 功能同上,入口参数与connect_nb()函数的区别同同connect_ext()函数 49 | SOCKET_EXT INT connect_nb_ext(SOCKET socket, void *srv_ip, USHORT srv_port); 50 | 51 | 52 | //* 发送函数(tcp链路下阻塞型),直至收到tcp层的ack报文或者超时才会返回,返回值大于0为实际发送的字节数,小于0则发送失败,具体错误信息通过onps_get_last_error()函数获得 53 | //* 对于udp协议来说参数nWaitAckTimeout将被忽略,其将作为非阻塞型函数使用; 54 | //* 当使能tcp的SUPPORT_SACK选项支持时,tcp链路下参数nWaitAckTimeout无效,可以是任意值,此时该函数为非阻塞型,其仅仅是把数据写入tcp链路的发送缓冲区,返回值为实际写入 55 | //* 的数据长度,返回值为0代表缓冲区已满,小于0则发生错误,具体的错误信息通过onps_get_last_error()函数获得 56 | SOCKET_EXT INT send(SOCKET socket, UCHAR *pubData, INT nDataLen, INT nWaitAckTimeout); 57 | 58 | //* 发送函数(tcp链路下非阻塞型),udp链路该函数与send()函数功能及实现逻辑完全相同 59 | SOCKET_EXT INT send_nb(SOCKET socket, UCHAR *pubData, INT nDataLen); 60 | 61 | //* 检查当前tcp链路发送的数据是否已成功送达对端,返回值为1则成功送达对端(收到tcp ack报文);等于0为发送中,尚未收到对端的应答;小于0则发送失败,具体错误信息通过onps_get_last_error()函数获得 62 | SOCKET_EXT INT is_tcp_send_ok(SOCKET socket); 63 | 64 | //* 仅用于udp发送,发送时指定目标地址 65 | SOCKET_EXT INT sendto(SOCKET socket, const CHAR *dest_ip, USHORT dest_port, UCHAR *pubData, INT nDataLen); 66 | 67 | //* 设定recv()函数等待接收的时长(单位:秒),大于0指定数据到达的最长等待时间;0,则不等待;-1,则一直等待直至数据到达或报错 68 | SOCKET_EXT BOOL socket_set_rcv_timeout(SOCKET socket, CHAR bRcvTimeout, EN_ONPSERR *penErr); 69 | 70 | //* 修改tcp链路相关控制标志 71 | SOCKET_EXT BOOL socket_set_tcp_link_flags(SOCKET socket, USHORT usNewFlags, EN_ONPSERR *penErr); 72 | 73 | //* 修改tcp链路相关控制标志 74 | SOCKET_EXT BOOL socket_set_tcp_link_flags_safe(SOCKET socket, USHORT usNewFlags, EN_OPTTYPE enOptType, EN_ONPSERR *penErr); 75 | 76 | //* 接收函数(阻塞型/非阻塞型),依赖于socket_set_rcv_timeout()函数设定的接收等待时长,缺省为一直等待直至收到数据或报错,阻塞型返回值为实际收到的数据长度,-1则代 77 | //* 表出错;非阻塞型返回值为实际收到的数据长度(大于等于0),-1同样代表接收失败 78 | SOCKET_EXT INT recv(SOCKET socket, UCHAR *pubDataBuf, INT nDataBufSize); 79 | 80 | //* 接收函数,仅用于udp协议接收 81 | SOCKET_EXT INT recvfrom(SOCKET socket, UCHAR *pubDataBuf, INT nDataBufSize, void *pvFromIP, USHORT *pusFromPort); 82 | 83 | //* 获取当前tcp连接状态,0:未连接;1:已连接;-1:读取状态失败,具体错误信息由参数penErr返回 84 | SOCKET_EXT INT is_tcp_connected(SOCKET socket, EN_ONPSERR *penErr); 85 | 86 | //* 为socket绑定指定的网络地址和端口,如果想绑定任意网络接口地址,参数pszNetifIp为NULL即可 87 | SOCKET_EXT INT bind(SOCKET socket, const CHAR *pszNetifIp, USHORT usPort); 88 | 89 | #if SUPPORT_ETHERNET 90 | //* tcp服务器进入被动监听状态,入口参数与函数功能与伯克利sockets完全相同 91 | SOCKET_EXT INT listen(SOCKET socket, USHORT backlog); 92 | 93 | //* 接受一个到达的tcp连接请求,参数punFromIP及pusFromPort为发起连接请求的客户端的ip地址及端口,参数nWaitSecs指定等待时长(单位秒): 94 | //* 0: 不等待,立即返回 95 | //* 大于0: 等待指定时间直至超时或收到一个到达的连接请求 96 | //* 小于0: 一直等待,直至收到一个到达的连接请求 97 | SOCKET_EXT SOCKET accept(SOCKET socket, void *pvCltIP, USHORT *pusCltPort, INT nWaitSecs, EN_ONPSERR *penErr); 98 | 99 | //* 轮询等待tcp服务器数据到达,入口参数hSocketSrv为tcp服务器的socket,不是客户端的socket,nWaitSecs指定等待的秒数: 100 | //* 0: 不等待,立即返回 101 | //* 大于0: 等待指定时间直至超时或某个客户端链路收到数据 102 | //* 小于0: 一直等待,直至某个或多个客户端链路收到数据 103 | //* 返回值为收到数据的客户端socket 104 | SOCKET_EXT SOCKET tcpsrv_recv_poll(SOCKET hSocketSrv, INT nWaitSecs, EN_ONPSERR *penErr); 105 | 106 | //* 设置服务器的接收模式 107 | //* TCPSRVRCVMODE_ACTIVE 主动读取方式,需要用户通过recv()函数主动遍历读取每个客户端到达的数据 108 | //* TCPSRVRCVMODE_POLL 109 | SOCKET_EXT BOOL tcpsrv_set_recv_mode(SOCKET hSocketSrv, CHAR bRcvMode, EN_ONPSERR *penErr); 110 | 111 | //* 启动tcp服务器 112 | SOCKET_EXT SOCKET tcpsrv_start(INT family, USHORT usSrvPort, USHORT usBacklog, CHAR bRcvMode, EN_ONPSERR *penErr); 113 | #endif 114 | 115 | //* 连接tcp服务器 116 | SOCKET_EXT SOCKET tcp_srv_connect(INT family, void *srv_ip, USHORT srv_port, INT nRcvTimeout, INT nConnTimeout, EN_ONPSERR *penErr); 117 | 118 | //* tcp数据发送函数,相对于传统send()函数该函数增加了容错处理逻辑 119 | SOCKET_EXT BOOL tcp_send(SOCKET hSocket, UCHAR *pubData, INT nDataLen); 120 | 121 | //* 获取最近一次发生的错误信息 122 | SOCKET_EXT const CHAR *socket_get_last_error(SOCKET socket, EN_ONPSERR *penErr); 123 | 124 | //* 获取最近一次发生的错误码 125 | SOCKET_EXT EN_ONPSERR socket_get_last_error_code(SOCKET socket); 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /include/ethernet/arp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.16 13:43 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成arp模块相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef ARP_H 15 | #define ARP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ARP_EXT 19 | #else 20 | #define ARP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if SUPPORT_ETHERNET 24 | //* arp条目表 25 | typedef struct _ST_ENTRY_ETHIIIPV4_ { 26 | UINT unUpdateTime; //* 条目更新(读取/缓存)时间 27 | UINT unIPAddr; //* IP地址 28 | UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN]; //* 对应的ip地址 29 | } ST_ENTRY_ETHIIIPV4, *PST_ENTRY_ETHIIIPV4; 30 | 31 | //* arp条目控制块 32 | #define ARP_WAIT_QUEUE_NUM 12 33 | typedef struct _STCB_ETHARP_ { 34 | CHAR bIsUsed; 35 | CHAR bLastReadEntryIdx; //* 最近读取的arp条目索引 36 | ST_ENTRY_ETHIIIPV4 staEntry[ARPENTRY_NUM]; //* arp条目缓存表(Ipv4地址到以太网mac地址映射表) 37 | 38 | ST_SLINKEDLIST_NODE staSListWaitQueue[ARP_WAIT_QUEUE_NUM]; //* 等待arp查询结果的待发送报文队列 39 | PST_SLINKEDLIST pstSListWaitQueueFreed; 40 | PST_SLINKEDLIST pstSListWaitQueue; 41 | } STCB_ETHARP, *PSTCB_ETHARP; 42 | 43 | //* 等待arp查询结束后重新发送ip报文的控制块 44 | typedef struct _STCB_ETH_ARP_WAIT_ { 45 | //PST_ONESHOTTIMER pstTimer; 46 | PST_NETIF pstNetif; 47 | PST_SLINKEDLIST_NODE pstNode; 48 | UINT unIpv4; 49 | USHORT usIpPacketLen; 50 | UCHAR ubCount; 51 | UCHAR ubSndStatus; 52 | } STCB_ETH_ARP_WAIT, *PSTCB_ETH_ARP_WAIT; 53 | 54 | ARP_EXT void arp_init(void); 55 | ARP_EXT PSTCB_ETHARP arp_ctl_block_new(void); 56 | ARP_EXT void arp_ctl_block_free(PSTCB_ETHARP pstcbArp); 57 | ARP_EXT void arp_add_ethii_ipv4(PST_NETIF pstNetif/*PST_ENTRY_ETHIIIPV4 pstArpIPv4Tbl*/, UINT unIPAddr, UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN]); 58 | ARP_EXT void arp_add_ethii_ipv4_ext(PST_ENTRY_ETHIIIPV4 pstArpIPv4Tbl, UINT unIPAddr, UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN]); 59 | ARP_EXT INT arp_get_mac(PST_NETIF pstNetif, UINT unSrcIPAddr, UINT unDstArpIPAddr, UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], EN_ONPSERR *penErr); 60 | ARP_EXT INT arp_get_mac_ext(PST_NETIF pstNetif, UINT unSrcIPAddr, UINT unDstArpIPAddr, UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], SHORT sBufListHead, BOOL *pblNetifFreedEn, EN_ONPSERR *penErr); 61 | ARP_EXT INT arp_send_request_ethii_ipv4(PST_NETIF pstNetif, UINT unSrcIPAddr, UINT unDstArpIPAddr, EN_ONPSERR *penErr); 62 | ARP_EXT void arp_recv_from_ethii(PST_NETIF pstNetif, UCHAR *pubPacket, INT nPacketLen); 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /include/ethernet/arp_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.16 13:46 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * arp(Address Resolution Protocol)协议帧结构定义 12 | * 13 | */ 14 | #ifndef ARP_FRAME_H 15 | #define ARP_FRAME_H 16 | 17 | /* 18 | FF FF FF FF FF FF 4e 65 6f 22 06 01 08 06 19 | 00 01 08 00 06 04 00 02 02 00 00 00 00 00 20 | c0 a8 00 fc 2c fd a1 ae 27 3e c0 a8 00 03 21 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 | 00 00 00 00 23 | */ 24 | 25 | #define ARP_HARDWARE_ETH 0x0001 //* 硬件类型为ethernet 26 | #define ARP_HARDWARE_ADDR_LEN 6 //* 硬件地址长度 27 | 28 | #define ARP_PROTO_IPv4 0x0800 //* 协议类型为IPv4 29 | #define ARP_PROTO_IPv4_ADDR_LEN 4 //* IPv4协议的地址长度 30 | 31 | //* ARP操作码定义 32 | typedef enum { 33 | ARPOPCODE_REQUEST = 1, 34 | ARPOPCODE_REPLY = 2, 35 | } EN_ARPOPCODE; 36 | 37 | //* arp协议帧头部结构体 38 | PACKED_BEGIN 39 | typedef struct _ST_ARP_HDR_ { 40 | USHORT usHardwareType; //* 硬件类型 41 | USHORT usProtoType; //* 协议类型 42 | UCHAR ubHardwareAddrLen; //* 硬件地址长度 43 | UCHAR ubProtoAddrLen; //* 协议地址长度 44 | USHORT usOptCode; //* 操作码 45 | } PACKED ST_ARP_HDR, *PST_ARP_HDR; 46 | PACKED_END 47 | 48 | PACKED_BEGIN 49 | typedef struct _ST_ETHIIARP_IPV4_ { 50 | ST_ARP_HDR stHdr; 51 | UCHAR ubaSrcMacAddr[ETH_MAC_ADDR_LEN]; 52 | UINT unSrcIPAddr; 53 | UCHAR ubaDstMacAddr[ETH_MAC_ADDR_LEN]; 54 | UINT unDstIPAddr; 55 | UCHAR ubaPadding[18]; //* 填充字符,以满足ethernet帧数据域最小长度为46字节的要求 56 | } PACKED ST_ETHIIARP_IPV4, *PST_ETHIIARP_IPV4; 57 | PACKED_END 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/ethernet/dhcp_client.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.07.14 10:13 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成dhcp客户端模块相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef DHCP_CLIENT_H 15 | #define DHCP_CLIENT_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define DHCP_CLIENT_EXT 19 | #else 20 | #define DHCP_CLIENT_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if SUPPORT_ETHERNET 24 | typedef struct _STCB_RENEWAL_INFO_ STCB_RENEWAL_INFO, *PSTCB_RENEWAL_INFO; 25 | DHCP_CLIENT_EXT UCHAR *dhcp_get_option(UCHAR *pubOptions, USHORT usOptionsLen, UCHAR ubOptionCode); 26 | DHCP_CLIENT_EXT INT dhcp_send_packet(INT nInput, PST_NETIF pstNetif, UCHAR ubOptCode, UCHAR *pubOptions, UCHAR ubOptionsLen, UINT unTransId, in_addr_t unClientIp, in_addr_t unDstIP, in_addr_t unSrcIp, EN_ONPSERR *penErr); 27 | DHCP_CLIENT_EXT void dhcp_renewal_timeout_handler(void *pvParam); 28 | DHCP_CLIENT_EXT void dhcp_decline(INT nInput, PST_NETIF pstNetif, UINT unTransId, in_addr_t unDeclineIp, in_addr_t unSrvIp); 29 | DHCP_CLIENT_EXT void dhcp_timer_new(PFUN_ONESHOTTIMEOUT_HANDLER pfunTimeoutHandler, PSTCB_RENEWAL_INFO pstcbRenewalInfo, INT nTimeout); 30 | DHCP_CLIENT_EXT BOOL dhcp_req_addr(PST_NETIF pstNetif, EN_ONPSERR *penErr); 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/ethernet/dhcp_client_by_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.07.26 14:03 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 使用one-shot-timer完成dhcp客户端模块相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef DHCP_CLIENT_BY_TIMER_H 15 | #define DHCP_CLIENT_BY_TIMER_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define DHCP_CLIENT_BY_TIMER_EXT 19 | #else 20 | #define DHCP_CLIENT_BY_TIMER_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if SUPPORT_ETHERNET 24 | DHCP_CLIENT_BY_TIMER_EXT void dhcp_req_addr_timeout_handler(void *pvParam); 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/ethernet/dhcp_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.07.14 10:11 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * dhcp(Dynamic Host Configuration Protocol)协议帧结构定义 12 | * 13 | * 14 | */ 15 | #ifndef DHCP_FRAME_H 16 | #define DHCP_FRAME_H 17 | 18 | //* dhcp报文类型定义,具体定义参见相关rfc 2132第9.6节“DHCP Message Type”(http://mirrors.nju.edu.cn/rfc/beta/errata/rfc2132.html) 19 | typedef enum { 20 | DHCPMSGTP_DISCOVER = 1, 21 | DHCPMSGTP_OFFER = 2, 22 | DHCPMSGTP_REQUEST = 3, 23 | DHCPMSGTP_DECLINE = 4, 24 | DHCPMSGTP_ACK = 5, 25 | DHCPMSGTP_NAK = 6, 26 | DHCPMSGTP_RELEASE = 7, 27 | DHCPMSGTP_INFORM = 8, 28 | } EN_DHCPMSGTYPE; 29 | 30 | #define DHCP_OPT_REQUEST 1 //* dhcp操作码:请求 31 | #define DHCP_OPT_REPLY 2 //* dhcp操作码:应答 32 | 33 | #define DHCP_SRV_PORT 67 //* dhcp服务器端口 34 | #define DHCP_CLT_PORT 68 //* dhcp客户端端口 35 | 36 | #define DHCP_MAGIC_COOKIE 0x63825363 //* dhcp magic cookie字段值 37 | #define DHCP_OPTIONS_LEN_MIN 60 //* dhcp选项域最小长度,选项低于该长度需要填充字符至最小长度,超过则需要确保选项字段能够16位字对齐,填充字符为00 38 | 39 | //* dhcp协议帧头部结构体 40 | PACKED_BEGIN 41 | typedef struct _ST_DHCP_HDR_ { 42 | UCHAR ubOptCode; //* 操作码,1: request; 2: reply 43 | UCHAR ubHardwareType; //* 硬件地址类型,即mac地址类型,1代表这是这是常见 44 | UCHAR ubHardwareAddrLen; //* 硬件地址长度 45 | UCHAR ubHops; //* dhcp中继跳数,初始值为0,报文每经过一个dhcp中继,该字段值加1,未经过任何中继该值为0 46 | UINT unTransId; //* 唯一标识本次dhcp请求的标识符,注意,本次请求所有报文标识符均一致 47 | USHORT usElapsedSecs; //* 从发起请求到获取到ip地址共花费了多少秒,目前尚未使用,固定为0 48 | USHORT usFlags; //* 广播应答标识位(第0位,仅该位被使用),标识dhcp服务器应答报文是采用单薄还是广播方式发送,0表示采用单薄发送方式,1表示采用广播发送方式, 49 | //* 当该位置1,则客户端只接受服务器的广播应答报文,丢弃来自服务器的单播应答报文 50 | 51 | UINT unClientIp; //* 客户端ip地址,如果客户机已有IP地址的话,客户机在发送请求时将自己的IP地址放在此处,反之则填0; 52 | UINT unYourIp; //* 服务器分配给客户端的ip地址,由服务器把想要分配给客户端的地址填充到该字段; 53 | UINT unSrvIp; //* 下一个dhcp服务器地址(用于bootstrap过程),协议栈不支持dhcp服务器中继,故这里不处理该字段,发送报文时固定填充0 54 | UINT unGatewayIp; //* 网关地址,固定填0,协议栈不支持跨网段dhcp分配 55 | UCHAR ubaClientMacAddr[16]; //* 客户端mac地址 56 | CHAR szSrvName[64]; //* 服务器名称,是可选字段,由服务器在应答报文填入服务器主机名称,包含空字符结尾字符串,服务器可以选择不填(全0即可),在这里协议栈不处理也不理会该字段,发送报文时固定填充全0 57 | CHAR szBootFileName[128]; //* 引导文件名,协议栈不处理该字段,固定填充全0 58 | UINT unMagicCookie; //* 固定为99.130.83.99(即0x63825363),网络字节序填充此字段,其作用显式地指示这是dhcp报文而不是bootp报文(dhcp基于bootp协议设计实现) 59 | } PACKED ST_DHCP_HDR, *PST_DHCP_HDR; 60 | PACKED_END 61 | 62 | //* dhcp选项结构体 63 | //* ===================================================================================== 64 | //* 协议栈支持的dhcp选项定义,详见[RFC1533]:https://www.rfc-editor.org/rfc/rfc1533 65 | typedef enum { 66 | DHCPOPT_SUBNETMASK = 1, 67 | DHCPOPT_ROUTER = 3, 68 | DHCPOPT_DNS = 6, 69 | DHCPOPT_HOSTNAME = 12, 70 | DHCPOPT_REQIP = 50, 71 | DHCPOPT_LEASETIME = 51, 72 | DHCPOPT_MSGTYPE = 53, 73 | DHCPOPT_SRVID = 54, 74 | DHCPOPT_REQLIST = 55, 75 | DHCPOPT_RENEWALTIME = 58, 76 | DHCPOPT_REBINDINGTIME = 59, 77 | DHCPOPT_VENDORID = 60, 78 | DHCPOPT_CLIENTID = 61, 79 | DHCPOPT_END = 255, 80 | } EN_DHCPOPTION; 81 | 82 | PACKED_BEGIN 83 | typedef struct _ST_DHCPOPT_HDR_ { 84 | UCHAR ubOption; 85 | UCHAR ubLen; 86 | } PACKED ST_DHCPOPT_HDR, *PST_DHCPOPT_HDR; 87 | PACKED_END 88 | 89 | //* dhcp报文类型,具体报文类型定义参见EN_DHCPMSGTYPE宏定义 90 | PACKED_BEGIN 91 | typedef struct _ST_DHCPOPT_MSGTYPE_ { 92 | ST_DHCPOPT_HDR stHdr; 93 | UCHAR ubTpVal; //* 报文类型值 94 | } PACKED ST_DHCPOPT_MSGTYPE, *PST_DHCPOPT_MSGTYPE; 95 | PACKED_END 96 | 97 | //* dhcp客户端标识,该选项携带客户端硬件地址类型及mac地址 98 | PACKED_BEGIN 99 | typedef struct _ST_DHCPOPT_CLTID_ { 100 | ST_DHCPOPT_HDR stHdr; 101 | UCHAR ubHardwareType; 102 | UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN]; 103 | } PACKED ST_DHCPOPT_CLTID, *PST_DHCPOPT_CLTID; 104 | PACKED_END 105 | 106 | //* dhcp服务器标识,该选项携带dhcp服务器的ip地址 107 | PACKED_BEGIN 108 | typedef struct _ST_DHCPOPT_SRVID_ { 109 | ST_DHCPOPT_HDR stHdr; 110 | UINT unSrvIp; 111 | } PACKED ST_DHCPOPT_SRVID, *PST_DHCPOPT_SRVID; 112 | PACKED_END 113 | 114 | //* dhcp客户端请求的ip地址 115 | PACKED_BEGIN 116 | typedef struct _ST_DHCPOPT_REQIP_ { 117 | ST_DHCPOPT_HDR stHdr; 118 | UINT unVal; 119 | } PACKED ST_DHCPOPT_REQIP, *PST_DHCPOPT_REQIP; 120 | PACKED_END 121 | 122 | //* dhcp客户端提供者信息 123 | PACKED_BEGIN 124 | typedef struct _ST_DHCPOPT_VENDORID_ { 125 | ST_DHCPOPT_HDR stHdr; 126 | UCHAR ubaTag[8]; 127 | } PACKED ST_DHCPOPT_VENDORID, *PST_DHCPOPT_VENDORID; 128 | PACKED_END 129 | 130 | //* dhcp服务器分配的ip地址对应的子网掩码 131 | PACKED_BEGIN 132 | typedef struct _ST_DHCPOPT_SUBNETMASK_ { 133 | ST_DHCPOPT_HDR stHdr; 134 | UINT unVal; 135 | } PACKED ST_DHCPOPT_SUBNETMASK, *PST_DHCPOPT_SUBNETMASK; 136 | PACKED_END 137 | 138 | //* dhcp服务器指定的网关地址 139 | PACKED_BEGIN 140 | typedef struct _ST_DHCPOPT_ROUTER_ { 141 | ST_DHCPOPT_HDR stHdr; 142 | UINT unVal; 143 | } PACKED ST_DHCPOPT_ROUTER, *PST_DHCPOPT_ROUTER; 144 | PACKED_END 145 | 146 | //* dhcp服务器指定的dns服务器地址 147 | PACKED_BEGIN 148 | typedef struct _ST_DHCPOPT_DNS_ { 149 | ST_DHCPOPT_HDR stHdr; 150 | UINT unPrimary; 151 | UINT unSecondary; 152 | } PACKED ST_DHCPOPT_DNS, *PST_DHCPOPT_DNS; 153 | PACKED_END 154 | 155 | //* dhcp分配的ip地址的租期信息 156 | PACKED_BEGIN 157 | typedef struct _ST_DHCPOPT_LEASETIME_ { 158 | ST_DHCPOPT_HDR stHdr; 159 | UINT unVal; 160 | } PACKED ST_DHCPOPT_LEASETIME, *PST_DHCPOPT_LEASETIME; 161 | PACKED_END 162 | //* ===================================================================================== 163 | 164 | //* 租约信息控制块 165 | typedef struct _STCB_RENEWAL_INFO_ { 166 | INT nInput; 167 | PST_NETIF pstNetif; 168 | UINT unDhcpSrvIp; 169 | UINT unLeaseTime; 170 | UINT unTransId; 171 | CHAR bState; 172 | CHAR bWaitAckSecs; 173 | 174 | struct { //* 续租不成功时,启用定时器序列重新请求ip地址时保存服务器新分配地址的结构体 175 | UINT unOfferIp; 176 | ST_IPV4 stIPv4; 177 | CHAR bSndNum; 178 | } stReqAddr; 179 | } STCB_RENEWAL_INFO, *PSTCB_RENEWAL_INFO; 180 | 181 | #endif 182 | -------------------------------------------------------------------------------- /include/ethernet/dhcpv6.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2023.04.14 20:34 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * DHCPv6协议相关功能函数 12 | * 13 | */ 14 | #ifndef DHCPv6_H 15 | #define DHCPv6_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define DHCPv6_EXT 19 | #else 20 | #define DHCPv6_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "dhcpv6_frame.h" 23 | 24 | #define Dv6CFGADDR_PREFIX_LEN 124 //* DHCPv6服务器分配地地址无法获得前缀长度,所以为了路由选择及标识这是DHCPv6分配地地址,将其前缀长度设为最大 25 | 26 | #if SUPPORT_IPV6 && SUPPORT_ETHERNET 27 | //* 最大值取决于STCB_DHCPv6_CLIENT::bitState字段的位宽 28 | typedef enum { 29 | Dv6CLT_SOLICIT = 0, 30 | Dv6CLT_REQUEST, 31 | Dv6CLT_DAD, 32 | Dv6CLT_DECLINE, 33 | Dv6CLT_RENEW, 34 | Dv6CLT_REBIND, 35 | Dv6CLT_RELEASE, 36 | Dv6CLT_RESTART, 37 | } EN_DHCPv6CLTSTATE; 38 | 39 | #define DUID_SRVID_LEN_MAX 15 //* Server Identifier Option携带的Server Id为DUID_EN类型时允许的最大企业标识长度 40 | 41 | PACKED_BEGIN 42 | typedef struct _STCB_DHCPv6_CLIENT_ { 43 | INT nInput; //* DHCPv6客户端句柄 44 | UINT unStartTimingCounts; //* 时间计数 45 | UINT bitTransId : 24; //* Transaction ID,唯一标识本次dhcp请求的标识符,注意,本次请求所有报文标识符均一致 46 | UINT bitIsRunning : 1; //* 是否运行 47 | UINT bitReserved : 7; //* 保留 48 | UINT unT1; //* 参见ST_DHCPv6OPT_IANA_HDR结构体针对该字段的定义 49 | UINT unT2; //* 同上 50 | PST_ONESHOTTIMER pstTimer; 51 | struct { 52 | UCHAR ubSrvIdLen; //* Server Identifier长度 53 | UCHAR ubaVal[DUID_SRVID_LEN_MAX]; //* 服务器Id 54 | } PACKED stSrvId; 55 | USHORT usStatusCode; //* 状态码 56 | //UCHAR ubaSrvAddr[16]; //* 单播通讯时DHCPv6服务器地址 57 | UCHAR ubaIAAddr[16]; //* 服务器分配的地址 58 | UCHAR bitState : 3; //* 客户端当前工作状态,具体状态定义参见EN_DHCPv6CLTSTATE 59 | UCHAR bitUnicast : 1; //* 单播标记,置位则意味着收到服务器的DHCPv6OPT_UNICAST选项,此后的通讯均直接点对点发送而不是继续发送组播 60 | UCHAR bitRcvReply : 1; //* 收到回复 61 | UCHAR bitOptCnt : 3; //* 操作计数 62 | CHAR bDynAddr; //* 配置的地址节点,如果其小于0,则意味着这个路由器仅支持获取除地址之外的其它配置参数(如DNS服务器等) 63 | CHAR bRouter; //* 发起dhcp配置的路由器 64 | CHAR bNext; //* 指向下一个客户端 65 | } PACKED STCB_DHCPv6_CLIENT, *PSTCB_DHCPv6_CLIENT; 66 | PACKED_END 67 | 68 | DHCPv6_EXT void dhcpv6_client_ctl_block_init(void); 69 | DHCPv6_EXT PSTCB_DHCPv6_CLIENT dhcpv6_client_node_get(CHAR *pbNodeIdx, EN_ONPSERR *penErr); 70 | DHCPv6_EXT void dhcpv6_client_node_free(PSTCB_DHCPv6_CLIENT pstClientNode); 71 | DHCPv6_EXT PSTCB_DHCPv6_CLIENT dhcpv6_client_get(CHAR bClient); 72 | DHCPv6_EXT CHAR dhcpv6_client_get_index(PSTCB_DHCPv6_CLIENT pstClient); 73 | DHCPv6_EXT PSTCB_DHCPv6_CLIENT dhcpv6_client_find_by_ipv6(PST_NETIF pstNetif, UCHAR ubaRouterAddr[16], PST_IPv6_ROUTER *ppstRouter); 74 | 75 | DHCPv6_EXT INT dhcpv6_client_start(PST_IPv6_ROUTER pstRouter, EN_ONPSERR *penErr); 76 | DHCPv6_EXT void dhcpv6_client_stop(PSTCB_DHCPv6_CLIENT pstClient); 77 | DHCPv6_EXT void dhcpv6_client_stop_safe(CHAR bClient); 78 | DHCPv6_EXT INT dhcpv6_send_solicit(PSTCB_DHCPv6_CLIENT pstClient, PST_IPv6_ROUTER pstRouter, EN_ONPSERR *penErr); 79 | DHCPv6_EXT INT dhcpv6_send_request(PSTCB_DHCPv6_CLIENT pstClient, PST_IPv6_ROUTER pstRouter, USHORT usMsgType); 80 | DHCPv6_EXT void dhcpv6_recv(PST_NETIF pstNetif, UCHAR ubaSrcAddr[16], UCHAR ubaDstAddr[16], UCHAR *pubDHCPv6, USHORT usDHCPv6Len); 81 | #endif 82 | #endif 83 | -------------------------------------------------------------------------------- /include/ethernet/ethernet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.14 17:04 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ethernet模块相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef ETHERNET_H 15 | #define ETHERNET_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ETHERNET_EXT 19 | #else 20 | #define ETHERNET_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #define LPPROTO_IP 0x00000002 //* 协议栈环回模块支持的协议:Ipv4 24 | #define LPPROTO_IPv6 0x00000018 //* 协议栈环回模块支持的协议:Ipv6 25 | 26 | #if SUPPORT_ETHERNET 27 | ETHERNET_EXT void ethernet_init(void); 28 | ETHERNET_EXT PST_NETIF ethernet_add(const CHAR *pszIfName, const UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], PST_IPV4 pstIPv4, PFUN_EMAC_SEND pfunEmacSend, void (*pfunStartTHEmacRecv)(void *pvParam), PST_NETIF *ppstNetif, EN_ONPSERR *penErr); 29 | ETHERNET_EXT void ethernet_del(PST_NETIF *ppstNetif); 30 | ETHERNET_EXT INT ethernet_ii_send(PST_NETIF pstNetif, UCHAR ubProtocol, SHORT sBufListHead, void *pvExtraParam, EN_ONPSERR *penErr); 31 | ETHERNET_EXT void ethernet_ii_recv(PST_NETIF pstNetif, UCHAR *pubPacket, INT nPacketLen); 32 | ETHERNET_EXT void thread_ethernet_ii_recv(void *pvParam); 33 | ETHERNET_EXT BOOL ethernet_ipv4_addr_matched(PST_NETIF pstNetif, in_addr_t unTargetIpAddr); 34 | #if SUPPORT_IPV6 35 | ETHERNET_EXT BOOL ethernet_ipv6_addr_matched(PST_NETIF pstNetif, UCHAR ubaTargetIpv6[16]); 36 | #endif 37 | ETHERNET_EXT void ethernet_put_packet(PST_NETIF pstNetif, PST_SLINKEDLIST_NODE pstNode); 38 | ETHERNET_EXT INT ethernet_loopback_put_packet(PST_NETIF pstNetif, SHORT sBufListHead, UINT unLoopProtocol); 39 | 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/ethernet/ethernet_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.14 16:23 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * ethernet帧结构定义 12 | * 13 | */ 14 | #ifndef ETHERNET_FRAME_H 15 | #define ETHERNET_FRAME_H 16 | #include "ethernet_protocols.h" 17 | 18 | //* ethernet ii协议帧头部结构体 19 | PACKED_BEGIN 20 | typedef struct _ST_ETHERNET_II_HDR_ { 21 | UCHAR ubaDstMacAddr[ETH_MAC_ADDR_LEN]; 22 | UCHAR ubaSrcMacAddr[ETH_MAC_ADDR_LEN]; 23 | USHORT usProtoType; 24 | } PACKED ST_ETHERNET_II_HDR, *PST_ETHERNET_II_HDR; 25 | PACKED_END 26 | 27 | PACKED_BEGIN 28 | typedef struct _ST_LOOPBACK_HDR_ { 29 | UINT unProtoType; 30 | } PACKED ST_LOOPBACK_HDR, *PST_LOOPBACK_HDR; 31 | PACKED_END 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/ethernet/ethernet_protocols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.14 16:39 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * ethernet协议解析相关的宏定义 12 | * 13 | */ 14 | #ifndef ETHERNET_PROTOCOLS_H 15 | #define ETHERNET_PROTOCOLS_H 16 | #include "protocols.h" 17 | 18 | //* ethernet ii协议支持的上层协议值定义 19 | #define ETHII_IP 0x0800 //* Internet Protocol Version 4 20 | #define ETHII_ARP 0x0806 //* Address Resolution Protocol 21 | #define ETHII_RARP 0x0835 //* Reserver Address Resolution Protocol 22 | #define ETHII_IPV6 0x86DD //* Internet Protocol Version 6 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/ip/icmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.12 14:10 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * icmp协议相关功能函数 12 | * 13 | */ 14 | #ifndef ICMP_H 15 | #define ICMP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ICMP_EXT 19 | #else 20 | #define ICMP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "icmp_frame.h" 23 | 24 | typedef struct _ST_ICMP_REPORT_RESULT_ { //* 对端通过icmp报文送达的相关发送结果 25 | UCHAR ubType; 26 | UCHAR ubCode; 27 | UCHAR ubProtocol; 28 | UINT unSrcAddr; 29 | UINT unDstAddr; 30 | } ST_ICMP_REPORT_RESULT, *PST_ICMP_REPORT_RESULT; 31 | 32 | typedef struct _ST_NETIF_ ST_NETIF, *PST_NETIF; 33 | #if SUPPORT_ETHERNET 34 | ICMP_EXT void icmp_send_dst_unreachable(PST_NETIF pstNetif, in_addr_t unDstAddr, UCHAR *pubIpPacket, USHORT usIpPacketLen); 35 | #endif 36 | ICMP_EXT INT icmp_send_echo_reqest(INT nInput, USHORT usIdentifier, USHORT usSeqNum, UCHAR ubTTL, in_addr_t unDstAddr, const UCHAR *pubData, UINT unDataSize, EN_ONPSERR *penErr); 37 | ICMP_EXT void icmp_recv(PST_NETIF pstNetif, UCHAR *pubDstMacAddr, UCHAR *pubPacket, INT nPacketLen); //* 接收函数 38 | ICMP_EXT void icmp_get_last_report(PST_ICMP_REPORT_RESULT pstResult); 39 | ICMP_EXT const CHAR *icmp_get_description(UCHAR ubType, UCHAR ubCode); 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/ip/icmp_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.15 10:09 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * icmp帧结构定义 12 | * 13 | */ 14 | #ifndef ICMP_FRAME_H 15 | #define ICMP_FRAME_H 16 | 17 | typedef enum { 18 | ICMP_ECHOREPLY = 0, //* 回显应答 19 | ICMP_ERRDST = 3, //* 目标网络/主机访问错误 20 | ICMP_ERRSRC = 4, //* 源主机/网络错误 21 | ICMP_ERRREDIRECT = 5, //* 重定向错误 22 | ICMP_ECHOREQ = 8, //* 回显请求 23 | ICMP_ROUTEADVERT = 9, //* 路由器通告 24 | ICMP_ROUTESOLIC = 10, //* 路由器请求 25 | ICMP_ERRTTL = 11, //* TTL错误 26 | ICMP_ERRIP = 12, //* IP帧错误 27 | ICMP_MAX = 255 28 | } EN_ICMPTYPE; 29 | 30 | //* ICMP_ERRDST,目标网络/主机访问错误报文携带的具体错误值定义 31 | typedef enum { 32 | NET_UNREACHABLE = 0, //* Network unreachable,网络不可达 33 | HOST_UNREACHABLE = 1, //* Host unreachable,主机不可达 34 | PROTO_UNREACHABLE = 2, //* Protocol unreachable, 协议不可达 35 | PORT_UNREACHABLE = 3, //* Port unreachable, 端口不可达 36 | NO_FRAGMENT = 4, //* Fragmentation needed but no frag. bit set, 需要进行分片但设置不分片比特 37 | SRCROUTE_FAILED = 5, //* Source routing failed,源站选路失败 38 | DSTNET_UNKNOWN = 6, //* Destination network unknown,目的网络未知 39 | DSTHOST_UNKNOWN = 7, //* Destination host unknown,目的主机未知 40 | SRCHOST_ISOLATED = 8, //* Source host isolated (obsolete),源主机被隔离 41 | DSTNET_PROHIBITED = 9, //* Destination network administratively prohibited,目的网络被强行禁止 42 | DSTHOST_PROHIBITED = 10, //* Destination host administratively prohibited,目的主机被强行禁止 43 | TOS_NETUNREACHABLE = 11, //* Network unreachable for TOS,因TOS问题导致网络不可达 44 | TOS_HOST_UNREACHABLE = 12, //* Host unreachable for TOS,因TOS问题导致主机不可达 45 | COMMU_PROHIBITED = 13, //* Communication administratively prohibited by filtering,由于过滤通讯被强行禁止 46 | HOST_PRECE_VIOLATION = 14, //* Host precedence violation,主机越权 47 | PRECE_CUTOFF_EFFECT = 15 //* Precedence cutoff in effect,优先中止生效 48 | } EN_ERRDST; 49 | 50 | //* ICMP_ERRSRC,源主机/网络错误报文携带的具体错误值定义 51 | typedef enum { 52 | SRC_QUENCH = 0//* Source quench,源端被关闭(基本流控制) 53 | } EN_ERRSRC; 54 | 55 | //* ICMP_ERRREDIRECT,重定向错误报文携带的具体错误值定义 56 | typedef enum { 57 | NET_REDIRECT = 0, //* Redirect for network,对网络重定向 58 | HOST_REDIRECT = 1, //* Redirect for host,对主机重定向 59 | TOSNET_REDIRECT = 2, //* Redirect for TOS and network,对服务类型和网络重定向 60 | TOSHOST_REDIRECT = 3, //* Redirect for TOS and host,对服务类型和主机重定向 61 | } EN_ERRREDIRECT; 62 | 63 | //* ICMP_ERRTTL,TTL错误报文携带的具体错误值定义 64 | typedef enum { 65 | TRAN_TTL_ZERO = 0, //* TTL equals 0 during transit,传输期间生存时间为0 66 | REASSEMB_TTL_ZERO = 1, //* TTL equals 0 during reassembly,在数据报组装期间生存时间为0 67 | } EN_ERRTTL; 68 | 69 | //* ICMP_ERRIP,IP帧错误报文携带的错误值定义 70 | typedef enum { 71 | HDR_BAD = 0, //* IP header bad (catch all error),坏的IP首部(包括各种差错) 72 | OPTIONS_MISS = 1, //* Required options missing,缺少必需的选项 73 | } EN_ERRIP; 74 | 75 | //* icmp帧头部结构体 76 | PACKED_BEGIN 77 | typedef struct _ST_ICMP_HDR_ { 78 | UCHAR ubType; 79 | UCHAR ubCode; 80 | USHORT usChecksum; 81 | } PACKED ST_ICMP_HDR, *PST_ICMP_HDR; 82 | PACKED_END 83 | 84 | PACKED_BEGIN 85 | typedef struct _ST_ICMP_ECHO_HDR_ { 86 | USHORT usIdentifier; 87 | USHORT usSeqNum; 88 | } PACKED ST_ICMP_ECHO_HDR, *PST_ICMP_ECHO_HDR; 89 | PACKED_END 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /include/ip/icmpv6.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2023.03.12 09:33 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * ICMPv6协议相关功能函数 12 | * 13 | */ 14 | #ifndef ICMPv6_H 15 | #define ICMPv6_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ICMPv6_EXT 19 | #else 20 | #define ICMPv6_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "icmpv6_frame.h" 23 | 24 | #if SUPPORT_IPV6 25 | //#define IPv6LLA_PREFIXBITLEN 64 //* 链路本地地址前缀位长度 26 | #define IPv6MCA_SOLPREFIXBITLEN 104 //* FF02::1:FF00:0/104,链路本地范围内的邻居节点请求组播地址前缀长度,单位;数据位 27 | 28 | //* 协议栈支持的组播地址类型,其直接决定了icmpv6.c中l_pubaMcAddr数组单元的数据存储顺序 29 | typedef enum { 30 | IPv6MCA_NETIFNODES = 0, //* FF01::1,接口本地范围内所有节点组播地址 31 | IPv6MCA_ALLNODES = 1, //* FF02::1,链路本地范围内所有节点组播地址 32 | IPv6MCA_SOLNODE = 2, //* FF02::1:FF00:0/104,链路本地范围内的邻居节点请求组播地址前缀 33 | IPv6MCA_ALLROUTERS = 3, //* FF02::2,链路本地范围内所有路由器组播地址 34 | IPv6MCA_ALLMLDv2ROUTERS = 4, //* FF02::16,所有支持MLDv2路由器的组播地址 35 | } EN_IPv6MCADDR_TYPE; 36 | 37 | typedef struct _ST_NETIF_ ST_NETIF, *PST_NETIF; 38 | typedef struct _ST_ONESHOTTIMER_ ST_ONESHOTTIMER, *PST_ONESHOTTIMER; 39 | 40 | #if SUPPORT_ETHERNET 41 | //* IPv6地址到以太网Mac地址映射表存储结构体 42 | typedef struct _ST_ENTRY_ETHIPv6MAC_ { 43 | UINT unUpdateTime; //* 条目更新(读取/缓存)时间 44 | UCHAR ubaIpv6[16]; //* IPv6地址 45 | UCHAR ubaMac[ETH_MAC_ADDR_LEN]; //* 对应的ip地址 46 | } ST_ENTRY_ETHIPv6MAC, *PST_ENTRY_ETHIPv6MAC; 47 | 48 | //* Ipv6到以太网Mac地址映射表控制块 49 | #define IPV6MAC_WAIT_QUEUE_NUM 12 50 | typedef struct _STCB_ETHIPv6MAC__ { 51 | CHAR bIsUsed; 52 | CHAR bLastReadEntryIdx; //* 最近读取的映射条目 53 | CHAR bEntriesNum; //* 已经缓存的条目数量 54 | ST_ENTRY_ETHIPv6MAC staEntry[IPV6TOMAC_ENTRY_NUM]; //* IPv6地址到以太网Mac地址映射表 55 | 56 | ST_SLINKEDLIST_NODE staSListWaitQueue[IPV6MAC_WAIT_QUEUE_NUM]; //* 等待icmpv6查询结果的待发送报文队列 57 | PST_SLINKEDLIST pstSListWaitQueueFreed; 58 | PST_SLINKEDLIST pstSListWaitQueue; 59 | } STCB_ETHIPv6MAC, *PSTCB_ETHIPv6MAC; 60 | 61 | //* ipv6报文待发送队列控制块(触发发送的依据是收到邻居节点地址请求(Neighbor Solicitation)报文的应答报文) 62 | typedef struct _STCB_ETHIPv6MAC_WAIT_ { 63 | PST_ONESHOTTIMER pstTimer; 64 | PST_NETIF pstNetif; 65 | PST_SLINKEDLIST_NODE pstNode; 66 | UCHAR ubaIpv6[16]; 67 | USHORT usIpPacketLen; 68 | UCHAR ubCount; 69 | UCHAR ubSndStatus; 70 | } STCB_ETHIPv6MAC_WAIT, *PSTCB_ETHIPv6MAC_WAIT; 71 | #endif 72 | 73 | #if SUPPORT_ETHERNET 74 | ICMPv6_EXT void ipv6_mac_mapping_tbl_init(void); 75 | ICMPv6_EXT PSTCB_ETHIPv6MAC ipv6_mac_ctl_block_new(void); 76 | ICMPv6_EXT void ipv6_mac_ctl_block_free(PSTCB_ETHIPv6MAC pstcbIpv6Mac); 77 | ICMPv6_EXT void ipv6_mac_add_entry(PST_NETIF pstNetif, UCHAR ubaIpv6[16], UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], BOOL blIsOverride); 78 | ICMPv6_EXT void ipv6_mac_add_entry_ext(PSTCB_ETHIPv6MAC pstcbIpv6Mac, UCHAR ubaIpv6[16], UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], BOOL blIsOverride); 79 | ICMPv6_EXT INT ipv6_mac_get(PST_NETIF pstNetif, UCHAR ubaSrcIpv6[16], UCHAR ubaDstIpv6[16], UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], EN_ONPSERR *penErr); 80 | ICMPv6_EXT INT ipv6_mac_get_ext(PST_NETIF pstNetif, UCHAR ubaSrcIpv6[16], UCHAR ubaDstIpv6[16], UCHAR ubaMacAddr[ETH_MAC_ADDR_LEN], SHORT sBufListHead, BOOL *pblNetifFreedEn, EN_ONPSERR *penErr); 81 | ICMPv6_EXT const UCHAR *ipv6_lnk_addr(PST_NETIF pstNetif, UCHAR ubaLnkAddr[16]); 82 | ICMPv6_EXT const UCHAR *ipv6_dyn_addr(PST_NETIF pstNetif, UCHAR ubaDynAddr[16], UCHAR *pubPrefix, UCHAR ubPrefixBitLen); 83 | ICMPv6_EXT void icmpv6_send_dst_unreachable(PST_NETIF pstNetif, UCHAR ubaDstIpv6[16], UCHAR *pubIpPacket, USHORT usIpPacketLen); 84 | #endif 85 | 86 | ICMPv6_EXT const CHAR *icmpv6_get_description(UCHAR ubType, UCHAR ubCode); 87 | 88 | ICMPv6_EXT const UCHAR *ipv6_mc_addr(EN_IPv6MCADDR_TYPE enType); 89 | ICMPv6_EXT UCHAR *ipv6_sol_mc_addr(UCHAR ubaUniIpv6[16], UCHAR ubaSolMcAddr[16]); 90 | 91 | ICMPv6_EXT INT icmpv6_send_echo_request(INT nInput, UCHAR ubaDstIpv6[16], USHORT usIdentifier, USHORT usSeqNum, const UCHAR *pubEchoData, USHORT usEchoDataLen, EN_ONPSERR *penErr); 92 | ICMPv6_EXT INT icmpv6_send_ns(PST_NETIF pstNetif, UCHAR ubaSrcIpv6[16], UCHAR ubaDstIpv6[16], EN_ONPSERR *penErr); 93 | ICMPv6_EXT INT icmpv6_send_rs(PST_NETIF pstNetif, UCHAR ubaSrcIpv6[16], EN_ONPSERR *penErr); 94 | ICMPv6_EXT UCHAR *icmpv6_recv(PST_NETIF pstNetif, UCHAR *pubDstMacAddr, UCHAR *pubPacket, INT nPacketLen, UCHAR *pubIcmpv6); 95 | #endif 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /include/ip/ip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.12 10:20 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ip协议层业务逻辑实现相关的接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef IP_H 15 | #define IP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define IP_EXT 19 | #else 20 | #define IP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "protocols.h" 23 | #include "ip_frame.h" 24 | 25 | typedef struct _ST_NETIF_ ST_NETIF, *PST_NETIF; 26 | IP_EXT INT ip_send(PST_NETIF pstNetif, UCHAR *pubDstMacAddr, in_addr_t unSrcAddr, in_addr_t unDstAddr, EN_NPSPROTOCOL enProtocol, UCHAR ubTTL, SHORT sBufListHead, EN_ONPSERR *penErr); 27 | IP_EXT INT ip_send_ext(in_addr_t unSrcAddr, in_addr_t unDstAddr, EN_NPSPROTOCOL enProtocol, UCHAR ubTTL, SHORT sBufListHead, EN_ONPSERR *penErr); 28 | IP_EXT void ip_recv(PST_NETIF pstNetif, UCHAR *pubDstMacAddr, UCHAR *pubPacket, INT nPacketLen); 29 | 30 | #if SUPPORT_IPV6 31 | IP_EXT INT ipv6_send(PST_NETIF pstNetif, UCHAR *pubDstMacAddr, UCHAR ubaSrcIpv6[16], UCHAR ubaDstIpv6[16], UCHAR ubNextHeader, SHORT sBufListHead, UINT unFlowLabel, EN_ONPSERR *penErr); 32 | IP_EXT INT ipv6_send_ext(UCHAR ubaSrcIpv6[16], UCHAR ubaDstIpv6[16], UCHAR ubNextHeader, SHORT sBufListHead, UINT unFlowLabel, EN_ONPSERR *penErr); 33 | IP_EXT void ipv6_recv(PST_NETIF pstNetif, UCHAR *pubDstMacAddr, UCHAR *pubPacket, INT nPacketLen); 34 | IP_EXT UINT ipv6_flow_label_cal(UCHAR ubaDstAddr[16], UCHAR ubaSrcAddr[16], UCHAR ubNextHeader, USHORT usDstPort, USHORT usSrcPort); 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/ip/ip_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.12 10:24 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * ip帧结构定义 12 | * 13 | */ 14 | #ifndef IP_FRAME_H 15 | #define IP_FRAME_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define IP_FRAME_EXT 19 | #else 20 | #define IP_FRAME_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | typedef enum { 24 | IPPROTO_ICMP = 1, //* Internet Control Message Protocol 25 | IPPROTO_IGMP = 2, //* Internet Gateway Management Protocol 26 | IPPROTO_TCP = 6, //* Transmission Control Protocol 27 | IPPROTO_UDP = 17, //* User Datagram Protocol 28 | IPPROTO_ICMPv6 = 58, //* Internet Control Message Protocol v6 29 | IPPROTO_RAW = 255, //* Raw IP packets 30 | IPPROTO_MAX 31 | } EN_IPPROTO; 32 | 33 | //* Ipv6支持的扩展选项头定义 34 | #if SUPPORT_IPV6 35 | #define IPv6HDREXT_HOP 0 //* Hop-by-hop Options Header,逐跳头,其为链路上唯一一个所有节点都需要处理的扩展头部选项,故其必须排在扩展头部第一位 36 | #define IPv6HDREXT_DST 60 //* Destination Options Header,目的头 37 | #define IPv6OHDREXT_ROUTE 43 //* Routing Header,路由头 38 | #define IPv6OHDREXT_FRAGG 44 //* Fragment Header,分片头 39 | #define IPv6OHDREXT_ESP 50 //* EncapsuIating Security PayIoad,负载封装安全头,为封装在其中的负载提供数据机密性、完整性和重传保护等服务,同时对数据进行认证 40 | #define IPv6OHDREXT_AUTH 51 //* Authentication Header,认证头 41 | #define IPv6OHDREXT_END 59 //* End,无操作,没有下一个头部了,扩展头部结束,ip上层协议均与此扩展选项作用相同,亦代表扩展头结束 42 | #endif 43 | 44 | //* ip帧头部结构体 45 | PACKED_BEGIN 46 | typedef struct _ST_IP_HDR_ { 47 | UCHAR bitHdrLen : 4; //* Length of the header,长度单位为4字节UINT型,不是单字节UCHAR型 48 | UCHAR bitVer : 4; //* version of IP 49 | UCHAR bitMustBeZero : 1; //* Must be zero 50 | UCHAR bitTOS : 4; //* Type of service:(占4位从左至右为:最小时延、最大吞吐量、最高可靠性、最小费用,同时只能对1位置位,如4位均位0则表示一般服务) 51 | UCHAR bitPrior : 3; //* Ignore now 52 | USHORT usPacketLen; //* Total length of the packet 53 | USHORT usID; //* Unique identifier 54 | UCHAR bitFragOffset0 : 5; //* Frag offset0 55 | UCHAR bitFlag : 3; //* Flag 56 | UCHAR bitFragOffset1 : 8; //* Frag offset1 57 | UCHAR ubTTL; //* Time to live 58 | UCHAR ubProto; //* Protocol(TCP, UDP, etc) 59 | USHORT usChecksum; //* IP checksum 60 | 61 | UINT unSrcIP; 62 | UINT unDstIP; 63 | } PACKED ST_IP_HDR, *PST_IP_HDR; 64 | PACKED_END 65 | 66 | //* 用于校验和计算的ip伪包头 67 | PACKED_BEGIN 68 | typedef struct _ST_IP_PSEUDOHDR_ { 69 | UINT unSrcAddr; 70 | UINT unDstAddr; 71 | UCHAR ubMustBeZero; 72 | UCHAR ubProto; 73 | USHORT usPacketLen; 74 | } PACKED ST_IP_PSEUDOHDR, *PST_IP_PSEUDOHDR; 75 | PACKED_END 76 | 77 | #if SUPPORT_IPV6 78 | PACKED_BEGIN 79 | typedef struct _ST_IPv6_HDR_ { 80 | union { 81 | struct { 82 | UINT bitFlowLabel : 20; //* Flow Label,标识源和目的地址之间的通讯数据流,即表示当前传输的报文属于这个数据流中的一个,以显式地通知Ipv6路由器对其特 83 | //* 殊处理。其用于实现对数据包按照优先级顺序进行发送,比如优先发送实时数据(如音、视频) 84 | 85 | UINT bitEcn : 2; //* Explicit Congestion Notification,显式拥塞通知-0:非ECN能力传输,即不支持拥塞通知;1、2:支持ECN传输;3:遇到拥塞 86 | UINT bitDscp : 6; //* Differentiated Services Code Point,差分服务编码点,用于优先级指定,当网络出现拥塞时,低优先级的报文最先被丢弃 87 | UINT bitVer : 4; //* Ip版本号 88 | } PACKED stb32; 89 | UINT unVal; 90 | } PACKED uniFlag; 91 | 92 | USHORT usPayloadLen; //* Payload Length,负载长度,Ipv6包携带的负载长度,即其携带的扩展头部和Icmpv6、Tcp、Udp等上层协议报文的长度 93 | UCHAR ubNextHdr; //* Next Header,首个扩展头部或上层协议类型 94 | UCHAR ubHopLimit; //* Hop Limit,跳数限制,表示Ipv6包能经过的最大链路数,超过的包则直接丢弃,路由器会发送Icmpv6超时消息到源主机(类似于Ipv4的ttl字段) 95 | 96 | UCHAR ubaSrcIpv6[16]; //* 源Ipv6地址 97 | UCHAR ubaDstIpv6[16]; //* 目标Ipv6地址 98 | } PACKED ST_IPv6_HDR, *PST_IPv6_HDR; 99 | PACKED_END 100 | 101 | #define ipv6_ver uniFlag.stb32.bitVer 102 | #define ipv6_dscp uniFlag.stb32.bitDscp 103 | #define ipv6_ecn uniFlag.stb32.bitEcn 104 | #define ipv6_flow_label uniFlag.stb32.bitFlowLabel 105 | #define ipv6_flag uniFlag.unVal 106 | 107 | //* IPv6版本的用于校验和计算的伪报头 108 | PACKED_BEGIN 109 | typedef struct _ST_IPv6_PSEUDOHDR_ { 110 | UCHAR ubaSrcIpv6[16]; 111 | UCHAR ubaDstIpv6[16]; 112 | UINT unIpv6PayloadLen; //* 其携带的上册协议报文的长度,比如unUpperPktLen = tcp头 + tcp选项 + 用户数据长度 113 | UCHAR ubaMustBeZero[3]; 114 | UCHAR ubProto; //* Ipv6支持的上层协议类型,参见ip_frame.h文件之EN_IPPROTO 115 | } PACKED ST_IPv6_PSEUDOHDR, *PST_IPv6_PSEUDOHDR; 116 | PACKED_END 117 | 118 | PACKED_BEGIN 119 | typedef struct _ST_IPv6_EXTOPT_HDR_ { 120 | UCHAR ubNextHdr; 121 | UCHAR ubLen; //* 长度单位:8字节,且第一个8字节不被包括,所以计算实际长度时应为:[(ubLen + 1) * 8]字节,注意长度覆盖头部字段ST_IPv6_HOPBYHOP_HDR 122 | } PACKED ST_IPv6_EXTOPT_HDR, *PST_IPv6_EXTOPT_HDR; 123 | PACKED_END 124 | #endif 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /include/ip/ipv6_configure.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2023.03.29 09:40 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ipv6地址自动配置(stateless/stateful, icmpv6 + dhcpv6) 12 | * 13 | */ 14 | #ifndef IPv6CFG_H 15 | #define IPv6CFG_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define IPv6CFG_EXT 19 | #else 20 | #define IPv6CFG_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if SUPPORT_IPV6 24 | #if SUPPORT_ETHERNET 25 | #define IPv6_DAD_TIMEOUT 6 //* 等待多少秒即可确定当前试探地址没有任何节点在使用 26 | #define IPv6LNKADDR_FLAG 0x52 //* 链路本地标志,用于dad检测时区分是链路本地地址还是从路由器得到的具有生存时间的动态地址 27 | #define IPv6ADDR_INVALID_TIME 10 //* 地址变为无效后的静止时间确保这个地址不会被立即释放,避免地址资源被回收后导致的协议栈崩溃问题的发生 28 | 29 | //* 其最大定义范围不能超过ST_IPv6::bitCfgState字段指定的位宽限制 30 | typedef enum { 31 | IPv6CFG_INIT = 0, //* 初始 32 | IPv6CFG_LNKADDR = 1, //* 生成链路本地地址 33 | IPv6CFG_RS = 2, //* 路由请求 34 | IPv6CFG_WAIT_DYNADDRCFG_END = 3, //* 等待无状态(stateless)地址自动配置结束 35 | IPv6CFG_WAIT_Dv6CFG_END = 4, //* 等待有状态和无状态Dhcpv6配置结束,如果存在Dhcpv6主机的话 36 | IPv6CFG_END = 5, 37 | } EN_IPv6CFGSTATE; 38 | 39 | typedef enum { 40 | IPv6SVVTMR_INVALID = 0, //* 无效,未启动 41 | IPv6SVVTMR_RUN = 1, //* 运行 42 | IPv6SVVTMR_STOP = 2, //* 结束运行,这个由ethernet_del()函数发出,通知定时器结束运行,释放相关资源,另外两个状态定时器改变 43 | IPv6SVVTMR_RELEASED = 3 44 | } EN_IPv6SVVTIMERSTATE; 45 | 46 | //* stateful/stateless DHCPv6配置状态定义,其定义值最大范围受ST_IPv6_ROUTER::bitDv6CfgState位宽的限制(参见netif.h文件中ST_IPv6_ROUTER结构体定义) 47 | typedef enum { 48 | Dv6CFG_START = 0, 49 | Dv6CFG_END = 1 50 | } EN_DHCPv6CFGSTATE; 51 | 52 | IPv6CFG_EXT void ipv6_cfg_init(void); 53 | IPv6CFG_EXT PST_IPv6_DYNADDR ipv6_dyn_addr_node_get(CHAR *pbNodeIdx, EN_ONPSERR *penErr); 54 | IPv6CFG_EXT void ipv6_dyn_addr_node_free(PST_IPv6_DYNADDR pstDynAddrNode); 55 | IPv6CFG_EXT PST_IPv6_ROUTER ipv6_router_node_get(CHAR *pbNodeIdx, EN_ONPSERR *penErr); 56 | IPv6CFG_EXT void ipv6_router_node_free(PST_IPv6_ROUTER pstRouterNode); 57 | IPv6CFG_EXT PST_IPv6_DYNADDR ipv6_dyn_addr_get(CHAR bDynAddr); 58 | IPv6CFG_EXT PST_IPv6_ROUTER ipv6_router_get(CHAR bRouter); 59 | IPv6CFG_EXT const UCHAR *ipv6_router_get_addr(CHAR bRouter); 60 | IPv6CFG_EXT UCHAR ipv6_router_get_hop_limit(CHAR bRouter); 61 | IPv6CFG_EXT CHAR ipv6_router_get_index(PST_IPv6_ROUTER pstRouter); 62 | IPv6CFG_EXT void netif_ipv6_dyn_addr_add(PST_NETIF pstNetif, PST_IPv6_DYNADDR pstDynAddr); 63 | IPv6CFG_EXT void netif_ipv6_dyn_addr_del(PST_NETIF pstNetif, PST_IPv6_DYNADDR pstDynAddr); 64 | IPv6CFG_EXT void netif_ipv6_router_add(PST_NETIF pstNetif, PST_IPv6_ROUTER pstRouter); 65 | IPv6CFG_EXT void netif_ipv6_router_del(PST_NETIF pstNetif, PST_IPv6_ROUTER pstRouter); 66 | IPv6CFG_EXT PST_IPv6_DYNADDR netif_ipv6_dyn_addr_next(PST_NETIF pstNetif, CHAR *pbNextAddr); 67 | IPv6CFG_EXT PST_IPv6_DYNADDR netif_ipv6_dyn_addr_next_safe(PST_NETIF pstNetif, PST_IPv6_DYNADDR pstPrevDynAddr, BOOL blIsRefCnt); 68 | IPv6CFG_EXT void netif_ipv6_dyn_addr_release(PST_IPv6_DYNADDR pstDynAddr); 69 | IPv6CFG_EXT PST_IPv6_ROUTER netif_ipv6_router_next(PST_NETIF pstNetif, CHAR *pbNextRouter, CHAR *pbRouterIdx); 70 | IPv6CFG_EXT PST_IPv6_ROUTER netif_ipv6_router_next_safe(PST_NETIF pstNetif, PST_IPv6_ROUTER pstPrevRouter, BOOL blIsRefCnt); 71 | IPv6CFG_EXT void netif_ipv6_router_release(PST_IPv6_ROUTER pstRouter); 72 | IPv6CFG_EXT PST_IPv6_DYNADDR netif_ipv6_dyn_addr_get(PST_NETIF pstNetif, UCHAR ubaIpv6Addr[16], BOOL blIsReleased); 73 | IPv6CFG_EXT PST_IPv6_ROUTER netif_ipv6_router_get_by_addr(PST_NETIF pstNetif, UCHAR ubaRouterIpv6Addr[16]); 74 | 75 | IPv6CFG_EXT BOOL ipv6_cfg_start(PST_NETIF pstNetif, EN_ONPSERR *penErr); 76 | IPv6CFG_EXT BOOL ipv6_cfg_dad(PST_NETIF pstNetif, void *pstTentAddr, EN_ONPSERR *penErr); 77 | #endif 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /include/ip/tcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.25 15:13 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * tcp协议相关功能函数 12 | * 13 | */ 14 | #ifndef TCP_H 15 | #define TCP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define TCP_EXT 19 | #else 20 | #define TCP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "ip/tcp_link.h" 23 | 24 | TCP_EXT INT tcp_send_syn(INT nInput, in_addr_t unSrvAddr, USHORT usSrvPort, int nConnTimeout); 25 | TCP_EXT INT tcp_send_data(INT nInput, UCHAR *pubData, INT nDataLen, int nWaitAckTimeout); 26 | #if SUPPORT_SACK 27 | TCP_EXT INT tcp_send_data_ext(INT nInput, UCHAR *pubData, INT nDataLen, UINT unSeqNum); 28 | #endif 29 | TCP_EXT void tcp_send_ack(PST_TCPLINK pstLink, in_addr_t unSrcAddr, USHORT usSrcPort, in_addr_t unDstAddr, USHORT usDstPort); 30 | TCP_EXT void tcp_disconnect(INT nInput); 31 | TCP_EXT void tcp_recv(void *pvSrcAddr, void *pvDstAddr, UCHAR *pubPacket, INT nPacketLen, EN_NPSPROTOCOL enProtocol); 32 | TCP_EXT INT tcp_recv_upper(INT nInput, UCHAR *pubDataBuf, UINT unDataBufSize, CHAR bRcvTimeout); 33 | 34 | #if SUPPORT_SACK 35 | TCP_EXT void thread_tcp_handler(void *pvParam); 36 | #endif 37 | 38 | #if SUPPORT_IPV6 39 | TCP_EXT INT tcpv6_send_syn(INT nInput, UCHAR ubaSrvAddr[16], USHORT usSrvPort, int nConnTimeout); 40 | TCP_EXT void tcpv6_send_ack(PST_TCPLINK pstLink, UCHAR ubaSrcAddr[16], USHORT usSrcPort, UCHAR ubaDstAddr[16], USHORT usDstPort); 41 | #endif 42 | 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/ip/tcp_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.25 15:14 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * tcp帧结构定义 12 | * 13 | */ 14 | #ifndef TCP_FRAME_H 15 | #define TCP_FRAME_H 16 | 17 | typedef union _UNI_TCP_FLAG_ { 18 | struct { 19 | USHORT resrved1 : 3; 20 | USHORT nonce : 1; 21 | USHORT hdr_len : 4; 22 | USHORT fin : 1; 23 | USHORT syn : 1; 24 | USHORT reset : 1; 25 | USHORT push : 1; 26 | USHORT ack : 1; 27 | USHORT urgent : 1; 28 | USHORT resrved2 : 2; 29 | } stb16; 30 | USHORT usVal; 31 | } UNI_TCP_FLAG, *PUNI_TCP_FLAG; 32 | 33 | //* TCP帧头部结构体 34 | PACKED_BEGIN 35 | typedef struct _ST_TCP_HDR_ { 36 | USHORT usSrcPort; 37 | USHORT usDstPort; 38 | UINT unSeqNum; 39 | UINT unAckNum; 40 | 41 | //* 以下位字段适用于小端 42 | /* 43 | USHORT 44 | bitResrved1 : 3, 45 | bitNonce : 1, 46 | bitHdrLen : 4, 47 | bitFin : 1, 48 | bitSyn : 1, 49 | bitReset : 1, 50 | bitPush : 1, 51 | bitAck : 1, 52 | bitUrgent : 1, 53 | bitResrved2 : 2; 54 | */ 55 | USHORT usFlag; 56 | 57 | USHORT usWinSize; 58 | USHORT usChecksum; 59 | USHORT usUrgentPointer; 60 | } PACKED ST_TCP_HDR, *PST_TCP_HDR; 61 | PACKED_END 62 | 63 | //* TCP选项头部结构 64 | PACKED_BEGIN 65 | typedef struct _ST_TCPOPT_HDR_ { 66 | UCHAR ubKind; 67 | UCHAR ubLen; 68 | } PACKED ST_TCPOPT_HDR, *PST_TCPOPT_HDR; 69 | PACKED_END 70 | 71 | //* TCP头部选项之MSS,其实际指的是tcp报文携带的数据段的大小 72 | PACKED_BEGIN 73 | typedef struct _ST_TCPOPT_MSS_ { 74 | ST_TCPOPT_HDR stHdr; 75 | USHORT usValue; 76 | } PACKED ST_TCPOPT_MSS, *PST_TCPOPT_MSS; 77 | PACKED_END 78 | 79 | //* TCP头部选项之时间戳 80 | PACKED_BEGIN 81 | typedef struct _ST_TCPOPT_TIMESTAMP_ { 82 | ST_TCPOPT_HDR stHdr; 83 | UINT unTS; 84 | UINT unTSEcho; 85 | } PACKED ST_TCPOPT_TIMESTAMP, *PST_TCPOPT_TIMESTAMP; 86 | PACKED_END 87 | 88 | //* TCP头部选项之窗口扩大因子 89 | PACKED_BEGIN 90 | typedef struct _ST_TCPOPT_WNDSCALE_ { 91 | ST_TCPOPT_HDR stHdr; 92 | CHAR bScale; //* 取值范围0~14,即最大扩到65535 * 2^14 93 | } PACKED ST_TCPOPT_WNDSCALE, *PST_TCPOPT_WNDSCALE; 94 | PACKED_END 95 | 96 | //* TCP SACK选项携带的数据条目 97 | PACKED_BEGIN 98 | typedef struct _ST_TCPOPT_SACKINFO_ITEM_ { 99 | UINT unLeft; 100 | UINT unRight; 101 | } ST_TCPOPT_SACKINFO_ITEM, *PST_TCPOPT_SACKINFO_ITEM; 102 | PACKED_END 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /include/ip/tcp_options.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.29 10:41 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * tcp头部选项相关的功能函数实现 12 | * 13 | */ 14 | #ifndef TCP_OPTIONS_H 15 | #define TCP_OPTIONS_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define TCP_OPTIONS_EXT 19 | #else 20 | #define TCP_OPTIONS_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #define TCP_OPTIONS_SIZE_MAX 40 //* 最长40字节的tcp选项 24 | 25 | typedef enum { 26 | TCPOPT_END = 0, //* 选项表结束 27 | TCPOPT_NOP = 1, //* 无操作 28 | TCPOPT_MSS = 2, //* 最大报文长度(MSS) 29 | TCPOPT_WNDSCALE = 3, //* 窗口扩大因子 30 | TCPOPT_SACK = 4, //* sack permitted 31 | TCPOPT_SACKINFO = 5, //* sack information,携带具体的不连续的块信息 32 | TCPOPT_TIMESTAMP = 8, //* 时间戳 33 | } EN_TCPOPTTYPE; 34 | 35 | typedef struct _ST_TCPLINK_ ST_TCPLINK, *PST_TCPLINK; 36 | TCP_OPTIONS_EXT INT tcp_options_attach(UCHAR *pubAttachAddr, INT nAttachBufSize); 37 | TCP_OPTIONS_EXT void tcp_options_get(PST_TCPLINK pstLink, UCHAR *pubOptions, INT nOptionsLen); 38 | 39 | #if SUPPORT_SACK 40 | TCP_OPTIONS_EXT CHAR tcp_options_get_sack(PST_TCPLINK pstLink, UCHAR *pubOptions, INT nOptionsLen); 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/ip/udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.01 15:29 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * udp协议相关功能函数 12 | * 13 | */ 14 | #ifndef UDP_H 15 | #define UDP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define UDP_EXT 19 | #else 20 | #define UDP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "ip/udp_link.h" 23 | 24 | //* 实现udp发送,使用该函数之前用户应该已经通过connect()函数绑定了目标服务器地址 25 | UDP_EXT INT udp_send(INT nInput, UCHAR *pubData, INT nDataLen); 26 | UDP_EXT INT udp_send_ext(INT nInput, SHORT sBufListHead, in_addr_t unDstIp, USHORT usDstPort, in_addr_t unSrcIp, PST_NETIF pstNetif, EN_ONPSERR *penErr); 27 | UDP_EXT INT udp_sendto(INT nInput, in_addr_t unDstIP, USHORT usDstPort, UCHAR *pubData, INT nDataLen); 28 | UDP_EXT void udp_recv(in_addr_t unSrcAddr, in_addr_t unDstAddr, UCHAR *pubPacket, INT nPacketLen); 29 | UDP_EXT INT udp_recv_upper(INT nInput, UCHAR *pubDataBuf, UINT unDataBufSize, void *pvFromIP, USHORT *pusFromPort, CHAR bRcvTimeout); 30 | 31 | #if SUPPORT_IPV6 32 | UDP_EXT INT ipv6_udp_send_ext(INT nInput, SHORT sBufListHead, UCHAR ubaDstAddr[16], USHORT usDstPort, UCHAR ubaSrcAddr[16], PST_NETIF pstNetif, EN_ONPSERR *penErr); 33 | UDP_EXT INT ipv6_udp_sendto(INT nInput, const UCHAR ubaDstAddr[16], USHORT usDstPort, UCHAR *pubData, INT nDataLen); 34 | UDP_EXT void ipv6_udp_recv(PST_NETIF pstNetif, UCHAR ubaSrcAddr[16], UCHAR ubaDstAddr[16], UCHAR *pubPacket, INT nPacketLen); 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/ip/udp_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.02 15:11 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * udp帧结构定义 12 | * 13 | */ 14 | #ifndef UDP_FRAME_H 15 | #define UDP_FRAME_H 16 | 17 | //* UDP帧头部结构体 18 | PACKED_BEGIN 19 | typedef struct _ST_UDP_HDR_ { 20 | USHORT usSrcPort; 21 | USHORT usDstPort; 22 | USHORT usPacketLen; 23 | USHORT usChecksum; 24 | } PACKED ST_UDP_HDR, *PST_UDP_HDR; 25 | PACKED_END 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/ip/udp_link.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.06.01 16:59 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 保存udp链路相关信息的辅助功能函数 12 | * 13 | */ 14 | #ifndef UDP_LINK_H 15 | #define UDP_LINK_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define UDP_LINK_EXT 19 | #else 20 | #define UDP_LINK_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | typedef struct _ST_UDPLINK_ { 24 | CHAR bIdx; 25 | CHAR bNext; 26 | 27 | #if SUPPORT_IPV6 28 | ST_SOCKADDR stPeerAddr; 29 | //UINT unIpv6FlowLbl; //* //* ipv6流标签(Flow Label),其与源地址/端口、目的地址/端口一起唯一的标识一个通讯数据流 30 | #else 31 | struct { 32 | USHORT usPort; //* 端口 33 | in_addr_t unIp; //* 地址 34 | } stPeerAddr; 35 | #endif 36 | } ST_UDPLINK, *PST_UDPLINK; 37 | #if SUPPORT_IPV6 38 | #ifndef saddr_ipv4 39 | #define saddr_ipv4 uniIp.unVal 40 | #endif 41 | #ifndef saddr_ipv6 42 | #define saddr_ipv6 uniIp.ubaVal 43 | #endif 44 | #else 45 | #ifndef saddr_ipv4 46 | #define saddr_ipv4 unIp 47 | #endif 48 | #endif 49 | 50 | //* 到达的udp报文控制结构 51 | typedef struct _ST_RCVED_UDP_PACKET_ ST_RCVED_UDP_PACKET, *PST_RCVED_UDP_PACKET; 52 | typedef struct _ST_RCVED_UDP_PACKET_ { 53 | USHORT usLen; 54 | 55 | #if SUPPORT_IPV6 56 | struct { 57 | USHORT usPort; 58 | union 59 | { 60 | UINT unVal; 61 | UCHAR ubaVal[16]; 62 | } uniIp; 63 | } stSockAddr; 64 | #else 65 | struct { 66 | USHORT usPort; //* 端口 67 | in_addr_t unIp; //* 地址 68 | } stSockAddr; 69 | #endif 70 | PST_RCVED_UDP_PACKET pstNext; 71 | } ST_RCVED_UDP_PACKET, *PST_RCVED_UDP_PACKET; 72 | 73 | UDP_LINK_EXT BOOL udp_link_init(EN_ONPSERR *penErr); 74 | UDP_LINK_EXT void udp_link_uninit(void); 75 | UDP_LINK_EXT PST_UDPLINK udp_link_get(EN_ONPSERR *penErr); 76 | UDP_LINK_EXT void udp_link_free(PST_UDPLINK pstUdpLink); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /include/mmu/buddy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.11 14:28 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 采用Buddy算法实现的内存管理单元模块用到的相关数据结构及宏定义文件 12 | * 13 | */ 14 | #ifndef BUDDY_H 15 | #define BUDDY_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define BUDDY_EXT 19 | #else 20 | #define BUDDY_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | PACKED_BEGIN 24 | typedef struct _ST_BUDDY_PAGE_ { //* 具有相同页面大小的页面链表节点的基本数据结构 25 | struct _ST_BUDDY_PAGE_ *pstNext; 26 | UCHAR *pubStart; 27 | //CHAR blIsUsed; 28 | } PACKED ST_BUDDY_PAGE, *PST_BUDDY_PAGE; 29 | PACKED_END 30 | 31 | #if 0 32 | PACKED_BEGIN 33 | typedef struct _STCB_BUDDY_PAGE_NODE_ { //* 页面控制块链表节点 34 | struct _STCB_BUDDY_PAGE_NODE_ *pstNext; 35 | PST_BUDDY_PAGE pstPage; 36 | } PACKED STCB_BUDDY_PAGE_NODE, *PSTCB_BUDDY_PAGE_NODE; 37 | PACKED_END 38 | #endif 39 | 40 | PACKED_BEGIN 41 | typedef struct _ST_BUDDY_AREA_ { //* 具有相同页面大小的页块数组单元的基本数据结构 42 | PST_BUDDY_PAGE pstFreed; 43 | PST_BUDDY_PAGE pstUsed; 44 | UINT unPageSize; //* 该内存块单个页面大小 45 | } PACKED ST_BUDDY_AREA, *PST_BUDDY_AREA; 46 | PACKED_END 47 | 48 | BUDDY_EXT BOOL buddy_init(EN_ONPSERR *penErr); //* buddy模块初始化函数 49 | BUDDY_EXT void buddy_uninit(void); //* buddy模块去初始化函数 50 | BUDDY_EXT void *buddy_alloc(UINT unSize, EN_ONPSERR *penErr); //* 只有没有可用的内存块了才会返回NULL,其它情况都会返回一个合适大小的内存块 51 | BUDDY_EXT BOOL buddy_free(void *pvStart); //* 释放由buddy_alloc分配的内存 52 | BUDDY_EXT FLOAT buddy_usage(void); 53 | BUDDY_EXT FLOAT buddy_usage_details(UINT *punTotalBytes, UINT *punUsedBytes, UINT *punMaxFreedPageSize, UINT *punMinFreedPageSize); 54 | #endif 55 | -------------------------------------------------------------------------------- /include/mmu/buf_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.16 13:50 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 缓冲区链表,这是一个单向链表,由协议栈使用,用于实现发送时零拷贝设计 12 | * 13 | */ 14 | #ifndef BUF_LIST_H 15 | #define BUF_LIST_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define BUF_LIST_EXT 19 | #else 20 | #define BUF_LIST_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | BUF_LIST_EXT BOOL buf_list_init(EN_ONPSERR *penErr); 24 | BUF_LIST_EXT void buf_list_uninit(void); 25 | BUF_LIST_EXT SHORT buf_list_get(EN_ONPSERR *penErr); 26 | BUF_LIST_EXT SHORT buf_list_get_ext(void *pvData, UINT unDataSize, EN_ONPSERR *penErr); 27 | BUF_LIST_EXT void buf_list_attach_data(SHORT sNode, void *pvData, UINT unDataSize); 28 | BUF_LIST_EXT void buf_list_free(SHORT sNode); 29 | BUF_LIST_EXT void buf_list_free_head(SHORT *psHead, SHORT sNode); 30 | BUF_LIST_EXT void buf_list_put_head(SHORT *psHead, SHORT sNode); 31 | BUF_LIST_EXT void buf_list_put_tail(SHORT sHead, SHORT sNode); 32 | BUF_LIST_EXT void *buf_list_get_next_node(SHORT *psNextNode, USHORT *pusDataLen); 33 | BUF_LIST_EXT UINT buf_list_get_len(SHORT sBufListHead); 34 | BUF_LIST_EXT void buf_list_merge_packet(SHORT sBufListHead, UCHAR *pubPacket); 35 | BUF_LIST_EXT SHORT buf_list_free_nodes_num(void); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/net_tools/dns.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.08.23 09:15 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 提供dns功能实现相关的操作函数 12 | * 13 | */ 14 | #ifndef DNS_H 15 | #define DNS_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define DNS_EXT 19 | #else 20 | #define DNS_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if NETTOOLS_DNS_CLIENT 24 | 25 | #define DNS_SRV_PORT 53 //* dns服务器端口,这是一个固定值 26 | #define DNS_RCV_BUF_SIZE 384 //* 注意如果要查比较长的域名时请把该值调整为最大值512即可 27 | 28 | //* dns查询报文标志字段 29 | typedef union _UNI_DNS_FLAG_ { 30 | struct { 31 | USHORT reply_code : 4; //* 响应码,表示响应的差错状态。0,无差错;1,格式错误;2,服务器自身原因无法处理这个请求;3,域名不存在;4,查询类型不支持;5,服务器拒绝;6~15,保留 32 | USHORT resrved : 3; 33 | USHORT recur_avail : 1; //* 可用递归,响应报文有效。为 1 时,表示服务器支持递归查询,反之则不支持 34 | USHORT recur_desired : 1; //* 期望递归,查询报文设置,响应报文返回。为1,告诉名称服务器必须处理这个查询得到结果,这被称作递归查;0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表,这种方式被称为迭代查询 35 | USHORT truncated : 1; //* 表示是否被截断。值为 1 时,表示响应已超过 512 字节并已被截断,只返回前 512 个字节。 36 | USHORT auth : 1; //* 授权应答,响应报文有效。值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器 37 | USHORT opcode : 4; //* 操作码,查询及响应报文均有效。0,标准查询;1,反向查询;2,服务器状态查询;其它值保留 38 | USHORT qr : 1; //* 查询/响应标识。0,查询;1,响应 39 | } stb16; 40 | USHORT usVal; 41 | } UNI_DNS_FLAG, *PUNI_DNS_FLAG; 42 | 43 | //* dns报文头部结构体 44 | PACKED_BEGIN 45 | typedef struct _ST_DNS_HDR_ { 46 | USHORT usTransId; 47 | USHORT usFlag; 48 | USHORT usQuestions; 49 | USHORT usAnswerRRs; 50 | USHORT usAuthorityRRs; 51 | USHORT usAdditionalRRs; 52 | } PACKED ST_DNS_HDR, *PST_DNS_HDR; 53 | PACKED_END 54 | 55 | //* dns应答报文携带的Answers字段头部结构 56 | PACKED_BEGIN 57 | typedef struct _ST_DNS_ANSWER_HDR_ { 58 | USHORT usOffset; 59 | USHORT usType; 60 | USHORT usClass; 61 | UINT unTTL; 62 | USHORT usDataLen; 63 | } PACKED ST_DNS_ANSWER_HDR, *PST_DNS_ANSWER_HDR; 64 | PACKED_END 65 | 66 | //* dns应答报文携带的Answers字段头部结构 67 | PACKED_BEGIN 68 | typedef struct _ST_DNS_ANSWER_HDR_NONAME_ { 69 | USHORT usType; 70 | USHORT usClass; 71 | UINT unTTL; 72 | USHORT usDataLen; 73 | } PACKED ST_DNS_ANSWER_HDR_NONAME, *PST_DNS_ANSWER_HDR_NONAME; 74 | PACKED_END 75 | 76 | //* 开启dns查询,返回值为dns客户端句柄,利用该句柄可以实现多次不同域名的dns查询 77 | DNS_EXT INT dns_client_start(in_addr_t *punPrimaryDNS, in_addr_t *punSecondaryDNS, CHAR bRcvTimeout, EN_ONPSERR *penErr); 78 | DNS_EXT void dns_client_end(INT nClient); 79 | 80 | //* 实现dns查询,参数pszDomainName指定要查询的域名,返回值为查询结果,如果地址为0,具体错误信息从penErr获得 81 | DNS_EXT in_addr_t dns_client_query(INT nClient, in_addr_t unPrimaryDNS, in_addr_t unSecondaryDNS, const CHAR *pszDomainName, EN_ONPSERR *penErr); 82 | #endif 83 | #endif 84 | -------------------------------------------------------------------------------- /include/net_tools/net_virtual_terminal.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/include/net_tools/net_virtual_terminal.h -------------------------------------------------------------------------------- /include/net_tools/ping.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.07.12 14:36 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 提供ping功能实现相关的操作函数 12 | * 13 | */ 14 | #ifndef PING_H 15 | #define PING_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define PING_EXT 19 | #else 20 | #define PING_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if NETTOOLS_PING 24 | 25 | typedef void(*PFUN_PINGRCVHANDLER)(USHORT usIdentifier, void *pvFromAddr, USHORT usSeqNum, UCHAR *pubEchoData, UCHAR ubEchoDataLen, UCHAR ubTTL, UCHAR ubElapsedMSecs, void *pvParam); 26 | typedef void(*PFUN_PINGERRHANDLER)(USHORT usIdentifier, const CHAR *pszDstAddr, UCHAR ubIcmpErrType, UCHAR ubIcmpErrCode, void *pvParam); 27 | 28 | //* 开始ping探测,返回值唯一的标识当前开始的ping探测链路,其用于ping_send()、ping_recv()、ping()、ping_end()函数的调用 29 | PING_EXT INT ping_start(INT family, EN_ONPSERR *penErr); 30 | 31 | //* 结束ping探测 32 | PING_EXT void ping_end(INT nPing); 33 | 34 | //* 发送pin探测报文: 35 | //* 参数unDstAddr指定ping目标地址; 36 | //* 参数usSeqNum指定ping报文序号,一般来说这是一个递增序号; 37 | //* 参数ubTTL指定ping报文的ttl值; 38 | //* 参数pubEcho和ubEchoLen指定ping报文携带的echo数据及其长度; 39 | PING_EXT INT ping_send(INT family, INT nPing, const void *pvDstAddr, USHORT usSeqNum, UCHAR ubTTL, const UCHAR *pubEcho, UCHAR ubEchoLen, EN_ONPSERR *penErr); 40 | 41 | 42 | //* 等待接收ping的应答报文,收到正确的应答报文时返回值为应答报文携带的echo数据的长度,等于0则接收超时,小于0意味着出错,具体原因由参数penErr获取: 43 | //* 参数punFromAddr存储应答报文携带的源地址,如果不需要则参数值可以为NULL; 44 | //* 参数pusSeqNum存储应答报文的序号,序号应与ping_send()函数指定的unSeqNum值一致方可确定收到了正确应答,如果不需要则参数值可以为NULL; 45 | //* 参数pubDataBuf和ubDataBufSize分别指定用于接收应答报文携带的echo数据的缓冲区地址与长度,这两个参数不能为NULL; 46 | //* 参数pubTTL存储应答报文的ttl值,如果不需要则可以为NULL; 47 | //* 参数ubWaitSecs指定接收应答报文的最长等待时间,单位:秒; 48 | PING_EXT INT ping_recv(INT nPing, void *pvFromAddr, USHORT *pusSeqNum, UCHAR *pubDataBuf, UCHAR ubDataBufSize, UCHAR *pubTTL, UCHAR *pubType, UCHAR *pubCode, UCHAR ubWaitSecs, EN_ONPSERR *penErr); 49 | 50 | //* 发送并等待接收应答报文,返回值大于0意味着收到正确的应答报文,等于0则接收超时,小于0意味着出错,具体原因通过参数penErr获取: 51 | //* 参数pszDstAddr指定ping目标地址,可读字符串形式; 52 | //* 参数pfunGetCurMSecs指定一个计时函数,其用于记录ping开始时地毫秒数以及结束时的毫秒数,以计算ping目标地址的时长 53 | //* 参数pfunRcvHandler指向用户自定义的接收处理函数,当收到正确的ping应答报文后调用,用户可根据自己需求实现特定处理逻辑 54 | PING_EXT INT ping(INT nPing, const CHAR *pszDstAddr, USHORT usSeqNum, UCHAR ubTTL, UINT(*pfunGetCurMSecs)(void), PFUN_PINGRCVHANDLER pfunRcvHandler, PFUN_PINGERRHANDLER pfunErrHandler, UCHAR ubWaitSecs, void *pvParam, EN_ONPSERR *penErr); 55 | 56 | #if NETTOOLS_TELNETSRV && NVTCMD_PING_EN 57 | typedef struct _ST_PING_STARTARGS_ { //* ping启动参数 58 | CHAR bIsCpyEnd; 59 | ULONGLONG ullNvtHandle; 60 | INT nFamily; 61 | CHAR szDstIp[40]; 62 | } ST_PING_STARTARGS, *PST_PING_STARTARGS; 63 | PING_EXT void nvt_cmd_ping_entry(void *pvParam); 64 | #endif //* #if NETTOOLS_TELNETSRV && NVTCMD_PING_EN 65 | #endif 66 | #endif 67 | -------------------------------------------------------------------------------- /include/net_tools/sntp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.08.27 17:00 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 实现sntp协议,提供网络对时功能 12 | * 13 | */ 14 | #ifndef SNTP_H 15 | #define SNTP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define SNTP_EXT 19 | #else 20 | #define SNTP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if NETTOOLS_SNTP 24 | 25 | #define SNTP_SRV_PORT 123 //* sntp服务器端口,这是一个固定值 26 | #define DIFF_SEC_1900_1970 2208988800 //* 1900到1970年之间的秒数 27 | 28 | //* dns查询报文标志字段 29 | typedef union _UNI_SNTP_FLAG_ { 30 | struct { 31 | UCHAR mode : 3; //* 0,保留;1,主动对等体模式;2,被动对等体模式;3,客户端模式;4,服务器模式;5,广播模式;6,ntp控制报文;7,内部保留 32 | UCHAR ver : 3; //* 版本号 33 | UCHAR li : 2; //* 00,无告警;01,最后一分钟包含61秒;10,最后一分钟包含59秒;11,警告(时钟未同步) 34 | } stb8; 35 | UCHAR ubVal; 36 | } UNI_SNTP_FLAG, *PUNI_SNTP_FLAG; 37 | 38 | //* ntp数据报文格式 39 | PACKED_BEGIN 40 | typedef struct _ST_SNTP_DATA_ { 41 | UCHAR ubFlag; //* 标志 42 | UCHAR ubStratum; //* 时钟层数 43 | UCHAR ubPoll; //* 轮询时间,即两个连续ntp报文之间的时间间隔,用2的幂来表示,比如值为6表示最小间隔为2^6 = 64s 44 | UCHAR ubPrecision; //* 时钟精度 45 | UINT unRootDelay; //* 到主参考时钟的总往返延迟时间 46 | UINT unRootDispersion; //* 本地时钟相对于主参考时钟的最大误差 47 | UINT unRefId; //* 特定参考时钟标识 48 | ULONGLONG ullRefTimestamp; //* 本地时钟最后一次被设定或更新的时间,如果值为0表示本地时钟从未被同步 49 | ULONGLONG ullOrigiTimestamp; //* NTP报文离开源端时的本地时间 50 | ULONGLONG ullRcvTimestamp; //* NTP报文到达目的端的本地时间 51 | ULONGLONG ullTransTimestatmp; //* 目的端应答报文离开服务器端的本地时间 52 | } PACKED ST_SNTP_DATA, *PST_SNTP_DATA; 53 | PACKED_END 54 | 55 | //* 参数pszIp指定ntp服务器地址,函数指针pfunTime实现读取本地时间(unxi时间戳)可以为空,pfunSetSysTime同样是一个函数指针,用于时间同步成功后设置本地时间, 56 | //* 参数bTimeZone用于指定时区(比如东八区则指定8,西八区则指定-8),参数penErr用于接收错误码(如果函数执行失败的话),同步成功则返回TRUE,反之FALSE 57 | SNTP_EXT time_t sntp_update_by_ip(const CHAR *pszNtpSrvIp, time_t(*pfunTime)(void), void(*pfunSetSysTime)(time_t), CHAR bTimeZone, EN_ONPSERR *penErr); 58 | SNTP_EXT time_t sntp_update(in_addr_t unNtpSrvIp, time_t(*pfunTime)(void), void(*pfunSetSysTime)(time_t), CHAR bTimeZone, EN_ONPSERR *penErr); 59 | #if NETTOOLS_DNS_CLIENT 60 | SNTP_EXT time_t sntp_update_by_dns(const CHAR *pszDomainName, time_t(*pfunTime)(void), void(*pfunSetSysTime)(time_t), CHAR bTimeZone, EN_ONPSERR *penErr); 61 | #endif 62 | #endif 63 | #endif 64 | -------------------------------------------------------------------------------- /include/net_tools/telnet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2023.05.26 10:48 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 实现telnet通讯协议,提供telnet基础通讯用的相关功能函数 12 | * 13 | */ 14 | #ifndef TELNET_H 15 | #define TELNET_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define TELNET_EXT 19 | #else 20 | #define TELNET_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #if NETTOOLS_TELNETSRV 24 | 25 | //* 以下为Telnet命令(Telnet Commands)定义 26 | //* 这之下的命令由[RFC1184]定义,详见:https://www.rfc-editor.org/rfc/rfc1184 27 | #define TELNETCMD_EOF 236 //* End of File,文件结束符 28 | #define TELNETCMD_SUSP 237 //* Suspend the execution of the current process,挂起当前正在执行的进程 29 | #define TELNETCMD_ABORT 238 //* Abort the process,异常中止进程 30 | 31 | //* 由[RFC885]第6节“Implementation Considerations”定义,详见:https://www.rfc-editor.org/rfc/rfc885 32 | #define TELNETCMD_EOR 239 //* End Of Record,记录结束符 33 | 34 | //* 这之下的命令由[RFC854]定义,详见:https://www.rfc-editor.org/rfc/rfc854#page-14 35 | //* telnet在进入正常工作状态之前首先要进行选项协商。任何一方都可以主动发送选项协商请求给对方。协商请求包括以下4种命令字: 36 | //* WILL(TELNETCMD_WILL)、WONT(TELNETCMD_WONT)、DO(TELNETCMD_DO)、DONT(TELNETCMD_DONT) 37 | //* 对于激活选项请求,对端有权同意或者不同意;而对于禁止选项请求,则必须同意。如此,以上4种请求存在6种情况: 38 | //* 发送方 接收方 含义 39 | //* ------------------------------------------------ 40 | //* WILL -> 发送方想激活选项 41 | //* <- DO 接受方同意激活 42 | //* ------------------------------------------------ 43 | //* WILL -> 发送方想激活选项 44 | //* <- DONT 接收方不同意激活 45 | //* ------------------------------------------------ 46 | //* DO -> 发送方想让接收方激活选项 47 | //* <- WILL 接收方同意激活 48 | //* ------------------------------------------------ 49 | //* DO -> 发送方想让接收方激活选项 50 | //* <- WONT 接收方不同意激活 51 | //* ------------------------------------------------ 52 | //* WONT -> 发送方想要禁止选项 53 | //* <- DONT 接收方必须同意对端提出的禁止选项的请求 54 | //* ------------------------------------------------ 55 | //* DONT -> 发送方想让接收方禁止选项 56 | //* <- WONT 接收方必须同意对端提出的本地禁止选项的请求 57 | //* ------------------------------------------------ 58 | #define TELNETCMD_SE 240 //* End of subnegotiation parameters,子选项结束 59 | #define TELNETCMD_NOP 241 //* No operation,无操作 60 | #define TELNETCMD_DM 242 //* Data Mark,数据标记 61 | #define TELNETCMD_BRK 243 //* NVT character BRK,NVT的BRK字符 62 | #define TELNETCMD_IP 244 //* Interrupt Process,中断进程 63 | #define TELNETCMD_AO 245 //* Abort output,异常中止输出 64 | #define TELNETCMD_AYT 246 //* Are You There,对方是否还在运行 65 | #define TELNETCMD_EC 247 //* Erase character,转义字符 66 | #define TELNETCMD_EL 248 //* Erase line,删除行 67 | #define TELNETCMD_GA 249 //* Go ahead,继续进行信号,即GA信号 68 | #define TELNETCMD_SB 250 //* Subnegotiation,子选项开始标志符 69 | #define TELNETCMD_WILL 251 //* 选项协商,发送方本地将激活选项 70 | #define TELNETCMD_WONT 252 //* 选项协商,发送方本地想禁止选项 71 | #define TELNETCMD_DO 253 //* 选项协商,发送方想叫接收方激活选项 72 | #define TELNETCMD_DONT 254 //* 选项协商,发送方想让接收方去禁止选项 73 | #define TELNETCMD_IAC 255 //* Interpret As Command,后面紧跟的一个字节要作为命令字来解释 74 | 75 | //* Telnet选项定义,详见:https://www.iana.org/assignments/telnet-options/telnet-options.xhtml#telnet-options-1 76 | //* 这里只定义协议栈支持的相关选项 77 | #define TELNETOPT_ECHO 1 //* Echo,回显 78 | #define TELNETOPT_SGA 3 //* Suppress Go Ahead,抑制GA信号,NVT默认为半双工设备,在接收用户输入之前必须从服务器进程获得GA信号(其实就是TELNETCMD_GA命令),通过SGA选项禁止发送GA信号则可以让NVT无缝切换用户输入与输出而不再等待GA信号 79 | #define TELNETOPT_TM 6 //* Timing Mark,用于收发双方同步的选项,在这里其被用于“准行方式”协商,其完整使用说明详见[RFC860]:https://www.rfc-editor.org/rfc/rfc860 80 | #define TELNETOPT_TERMTYPE 24 //* Terminal Type,终端类型,详见[RFC1091]:https://www.rfc-editor.org/rfc/rfc1091.html 81 | 82 | PACKED_BEGIN 83 | //* telent选项协商通讯中DO、WILL、DONT、WONT几个命令的报文格式 84 | typedef struct _ST_TELNETPKT_CMD_ { 85 | UCHAR ubIAC; 86 | UCHAR ubCmd; 87 | UCHAR ubNegoOption; 88 | } PACKED ST_TELNETPKT_CMD, *PST_TELNETPKT_CMD; 89 | PACKED_END 90 | 91 | //* telent选项协商通讯终端类型选项的报文格式,终端类型携带的code编码的详细说明,参见:https://www.rfc-editor.org/rfc/rfc1091#page-2 92 | #define TELNETOPT_TTCODE_SEND 1 //* 发送你的终端类型 93 | #define TELNETOPT_TTCODE_IS 0 //* 我的终端类型是…… 94 | PACKED_BEGIN 95 | typedef struct _ST_TELNETPKT_SOPT_TERMTYPE_ { 96 | UCHAR ubSIAC; 97 | UCHAR ubSB; 98 | UCHAR ubOption; 99 | UCHAR ubCode; 100 | UCHAR ubEIAC; 101 | UCHAR ubSE; 102 | } PACKED ST_TELNETPKT_SOPT_TERMTYPE, *PST_TELNETPKT_SOPT_TERMTYPE; 103 | PACKED_END 104 | 105 | #define TERM_NAME_MAX 16 //* 终端名称最大字节数 106 | 107 | TELNET_EXT void telnet_cmd_send(SOCKET hSocket, UCHAR ubCmd, UCHAR ubOption); 108 | TELNET_EXT void telnet_cmd_ack_default(SOCKET hSocket, UCHAR ubCmd, UCHAR ubOption); 109 | TELNET_EXT void telnet_req_term_type(SOCKET hSocket); 110 | TELNET_EXT void telnet_report_term_type(SOCKET hSocket, const CHAR *pszTermType, INT nTremTypeLen); 111 | #endif //* #if NETTOOLS_TELNETSRV 112 | #endif 113 | -------------------------------------------------------------------------------- /include/net_tools/telnet_client.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/include/net_tools/telnet_client.h -------------------------------------------------------------------------------- /include/net_tools/telnet_srv.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/include/net_tools/telnet_srv.h -------------------------------------------------------------------------------- /include/netif/route.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.18 10:03 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 路由功能相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef ROUTE_H 15 | #define ROUTE_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ROUTE_EXT 19 | #else 20 | #define ROUTE_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "netif.h" 23 | 24 | //* Ipv4路由条目存储结构 25 | typedef struct _ST_ROUTE_ { 26 | UINT unSource; 27 | UINT unDestination; 28 | UINT unGateway; 29 | UINT unGenmask; 30 | PST_NETIF pstNetif; 31 | } ST_ROUTE, *PST_ROUTE; 32 | 33 | //* Ipv4路由链表节点 34 | typedef struct _ST_ROUTE_NODE_ { 35 | struct _ST_ROUTE_NODE_ *pstNext; 36 | ST_ROUTE stRoute; 37 | } ST_ROUTE_NODE, *PST_ROUTE_NODE; 38 | 39 | ROUTE_EXT BOOL route_table_init(EN_ONPSERR *penErr); 40 | ROUTE_EXT void route_table_uninit(void); 41 | //* 参数unDestination指定目标网段地址,如果其值为0则其为缺省路由 42 | ROUTE_EXT BOOL route_add(PST_NETIF pstNetif, UINT unDestination, UINT unGateway, UINT unGenmask, EN_ONPSERR *penErr); 43 | ROUTE_EXT BOOL route_del(UINT unDestination, EN_ONPSERR *penErr); 44 | ROUTE_EXT void route_del_ext(PST_NETIF pstNetif); 45 | ROUTE_EXT PST_NETIF route_get_netif(UINT unDestination, BOOL blIsForSending, in_addr_t *punSrcIp, in_addr_t *punArpDstAddr); 46 | ROUTE_EXT PST_NETIF route_get_default(void); 47 | ROUTE_EXT UINT route_get_netif_ip(UINT unDestination); 48 | 49 | #if SUPPORT_IPV6 50 | ROUTE_EXT PST_NETIF route_ipv6_get_netif(const UCHAR ubaDestination[16], BOOL blIsForSending, UCHAR *pubSource, UCHAR *pubNSAddr, UCHAR *pubHopLimit); 51 | ROUTE_EXT UCHAR *route_ipv6_get_source_ip(const UCHAR ubaDestination[16], UCHAR *pubSource); //* 同route_get_netif_ip()函数,确定源地址,用于tcp/udp校验和计算伪ipv6报头 52 | #endif //* #if SUPPORT_IPV6 53 | 54 | #if NETTOOLS_TELNETSRV 55 | ROUTE_EXT const ST_ROUTE *route_get_next(const ST_ROUTE *pstNextRoute); 56 | #endif //* #if NETTOOLS_TELNETSRV 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/one_shot_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.17 17:45 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 协议栈使用的one-shot类型的定时器,时间粒度为1秒 12 | * 13 | */ 14 | #ifndef ONE_SHOT_TIMER_H 15 | #define ONE_SHOT_TIMER_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ONE_SHOT_TIMER_EXT 19 | #else 20 | #define ONE_SHOT_TIMER_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #define ONE_SHOT_TIMER_NUM 16 //* 定时器数量 24 | 25 | typedef void(*PFUN_ONESHOTTIMEOUT_HANDLER)(void *pvParam); 26 | typedef struct _ST_ONESHOTTIMER_ ST_ONESHOTTIMER, *PST_ONESHOTTIMER; 27 | 28 | //* 定时器初始化函数 29 | ONE_SHOT_TIMER_EXT BOOL one_shot_timer_init(EN_ONPSERR *penErr); 30 | 31 | //* 定时器去初始化函数 32 | ONE_SHOT_TIMER_EXT void one_shot_timer_uninit(void); 33 | 34 | //* 结束两个定时器线程,并释放所有工作队列,并归还给系统 35 | ONE_SHOT_TIMER_EXT void one_shot_timer_stop(void); 36 | 37 | //* one-shot定时器计数线程 38 | ONE_SHOT_TIMER_EXT void thread_one_shot_timer_count(void *pvParam); 39 | 40 | //* 创建一个新的定时器,参数pfunTimeoutHandler指定用户自定义的溢出处理函数,pvParam为传递给溢出处理函数的参数,nTimeoutCount指定计数值 41 | ONE_SHOT_TIMER_EXT PST_ONESHOTTIMER one_shot_timer_new(PFUN_ONESHOTTIMEOUT_HANDLER pfunTimeoutHandler, void *pvParam, INT nTimeoutCount); 42 | 43 | //* 定时器重新计数以延长超时时间,重新计数的前提是定时器尚未超时溢出,参数pstTimer指定要重新计数的定时器,nTimeoutCount则指定新的计数值,新的计数值必须大于0,小于等于0无效 44 | ONE_SHOT_TIMER_EXT void one_shot_timer_recount(PST_ONESHOTTIMER pstTimer, INT nTimeoutCount); 45 | 46 | //* 停止并安全释放一个正在计时的定时器,如果已超时溢出则不执行任何操作,与one_shot_timer_free()函数不同,该函数需要先判断其是否 47 | //* 依然还在计数,是才会执行释放并归还操作 48 | ONE_SHOT_TIMER_EXT void one_shot_timer_safe_free(PST_ONESHOTTIMER pstTimer); 49 | 50 | //* 将定时器归还给系统,该函数不做任何判断,直接将参数pstTimer指定的定时器重新连接到系统定时器队列以供用户下次申请使用 51 | ONE_SHOT_TIMER_EXT void one_shot_timer_free(PST_ONESHOTTIMER pstTimer); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /include/onps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.21 10:19 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * open net protocol statck 12 | * 13 | */ 14 | #ifndef ONPS_H 15 | #define ONPS_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ONPS_EXT 19 | #else 20 | #define ONPS_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "port/datatype.h" 23 | #include "port/sys_config.h" 24 | #include "onps_errors.h" 25 | #include "port/os_datatype.h" 26 | #include "port/os_adapter.h" 27 | #include "mmu/buddy.h" 28 | #include "mmu/buf_list.h" 29 | #include "onps_utils.h" 30 | #include "one_shot_timer.h" 31 | #include "netif/netif.h" 32 | #include "netif/route.h" 33 | #if SUPPORT_PPP 34 | #include "ppp/negotiation.h" 35 | #include "ppp/ppp.h" 36 | #endif 37 | #if SUPPORT_ETHERNET 38 | #include "ethernet/ethernet.h" 39 | #include "ethernet/dhcp_client.h" 40 | #endif 41 | #include "ip/icmp.h" 42 | #include "onps_input.h" 43 | #include "bsd/socket.h" 44 | 45 | ONPS_EXT BOOL open_npstack_load(EN_ONPSERR *penErr); 46 | ONPS_EXT void open_npstack_unload(void); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/onps_errors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.14 17:14 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 错误类型定义 12 | * 13 | */ 14 | #ifndef ONPS_ERRORS_H 15 | #define ONPS_ERRORS_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ONPS_ERRORS_EXT 19 | #else 20 | #define ONPS_ERRORS_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | typedef enum { 24 | ERRNO = 0, //* 没有发生任何错误 25 | ERRNOPAGENODE, //* 无可用的内存页面节点 26 | ERRREQMEMTOOLARGE, //* 申请的内存过大,超过了系统支持的最大申请配额 27 | ERRNOFREEMEM, //* 系统已无可用内存 28 | ERRMUTEXINITFAILED, //* 线程同步锁初始化失败 29 | ERRNOBUFLISTNODE, //* 无可用缓冲区链表节点 30 | ERRSEMINITFAILED, //* 信号量初始化失败 31 | ERROPENTTY, //* tty终端打开失败 32 | ERRATWRITE, //* AT指令写错误 33 | ERRATEXEC, //* AT指令返回错误 34 | ERRATEXECTIMEOUT, //* AT指令执行超时 35 | ERRSIMCARD, //* 未检测到SIM卡 36 | ERRREGMOBILENET, //* 没有注册到移动网络 37 | ERRPPPIDXOVERFLOW, //* ppp链路索引溢出 38 | ERRPPPDELIMITER, //* 未找到ppp帧定界符 39 | ERRTOOMANYTTYS, //* tty数量过多 40 | ERRTTYHANDLE, //* tty句柄无效 41 | ERROSADAPTER, //* os适配层错误 42 | ERRUNKNOWNPROTOCOL, //* 未知协议类型 43 | ERRPPPFCS, //* ppp帧校验和错误 44 | ERRNOIDLETIMER, //* 没有空闲的定时器 45 | ERRNOFREEPPWANODE, //* 用于ppp协商等待的节点不可用 46 | ERRPPPWALISTNOINIT, //* ppp等待应答链表未初始化 47 | ERRNONETIFNODE, //* 无可用的netif节点 48 | ERRNONETIFFOUND, //* 未找到网络接口 49 | ERRINPUTOVERFLOW, //* onps输入句柄溢出 50 | ERRUNSUPPIPPROTO, //* 不被支持的IP层协议 51 | ERRUNSUPPIOPT, //* 不支持的配置项 52 | ERRIPROTOMATCH, //* 协议匹配错误 53 | ERRNOROUTENODE, //* 无可用的路由表单元 54 | ERRADDRESSING, //* 寻址失败,不存在缺省路由 55 | ERRADDRFAMILIES, //* 地址族错误 56 | ERRSOCKETTYPE, //* 不被支持的socket类型 57 | ERRNOATTACH, //* 附加数据地址为空 58 | ERRTCSNONTCP, //* 非TCP协议不能获取、设置TCP链路状态 59 | ERRTDSNONTCP, //* 非TCP协议不能获取数据发送状态 60 | ERRTCPCONNTIMEOUT, //* TCP连接超时 61 | ERRTCPCONNRESET, //* TCP连接已被重置 62 | ERRTCPCONNCLOSED, //* TCP链路已关闭 63 | ERRDATAEMPTY, //* 数据段为0 64 | ERRTCPACKTIMEOUT, //* TCP应答超时 65 | ERRNOTCPLINKNODE, //* 无可用tcp link节点 66 | ERRTCPNOTCONNECTED, //* tcp未连接 67 | ERRINVALIDSEM, //* 无效的信号量 68 | ERRSENDZEROBYTES, //* 发送了0字节的数据 69 | ERRPORTOCCUPIED, //* 端口已被占用 70 | ERRSENDADDR, //* 发送地址错误 71 | ERRETHEXTRAEMPTY, //* 无可用的ethernet网卡附加信息节点 72 | ERRNETUNREACHABLE, //* 网络不可达 73 | ERRROUTEADDRMATCH, //* 两次寻址结果不匹配 74 | ERRNEWARPCTLBLOCK, //* arp控制块已空 75 | ERRUNSUPPETHIIPROTO, //* 不被支持的ethernet ii上层协议 76 | ERRPACKETTOOLARGE, //* 报文太大 77 | ERRPORTEMPTY, //* 端口为空 78 | ERRWAITACKTIMEOUT, //* 等待应答超时 79 | ERRIPCONFLICT, //* ip地址冲突 80 | ERRNOTBINDADDR, //* 套接字没有绑定地址 81 | ERRTCPONLY, //* 仅支持tcp协议 82 | ERRTCPSRVEMPTY, //* tcp服务器资源为空 83 | ERRTCPBACKLOGEMPTY, //* tcp服务器的backlog资源为空 84 | ERRTCPRCVQUEUEEMPTY, //* tcp服务器的接收队列资源为空 85 | ERRTCPNOLISTEN, //* tcp服务器未进入listen阶段 86 | ERRTCPBACKLOGFULL, //* tcp服务器的backlog队列已满 87 | ERRDNSQUERYFMT, //* dns查询报文格式错误 88 | ERRDNSSRV, //* dns服务器故障 89 | ERRDNSNAME, //* 域名不存在 90 | ERRDNSQUERYTYPE, //* 不被支持的dns查询类型 91 | ERRDNSREFUSED, //* dns服务器拒绝 92 | ERRDNSNOTRESOLVED, //* 未解析到ip地址 93 | ERRNOUDPLINKNODE, //* 无可用udp link节点 94 | ERRTCPLINKCBNULL, //* tcp link控制块为NULL 95 | #if SUPPORT_IPV6 96 | ERRNEWIPv6MACCTLBLOCK, //* ipv6到mac地址映射表控制块已空 97 | ERRNOIPv6DYNADDRNODE, //* 无可用ipv6动态地址节点 98 | ERRNOIPv6ROUTERNODE, //* 无可用ipv6路由器节点 99 | ERRIPV4FLOWLABEL, //* ipv4协议不支持流标签字段 100 | ERRNODv6CLTCBNODE, //* 无可用dhcpv6客户端控制块节点 101 | ERRROUTERINDEX, //* 路由器节点索引溢出 102 | #endif 103 | ERRFAMILYINCONSISTENT, //* 目标和源地址的地址族不一致 104 | ERRUNSUPPORTEDFAMILY, //* 不支持的地址族 105 | #if NETTOOLS_TELNETSRV 106 | ERRNOTELNETCLTCBNODE, //* 无可用telnet客户端控制块节点 107 | ERRNVTSTART, //* nvt启动失败 108 | #endif 109 | ERRNETIFNOTFOUND, //* 未找到网络接口 110 | ERREXTRAIPLIMIT, //* 附加ip超出数量限制 111 | ERREXTRAIPSAVE, //* 附加ip地址写入系统存储器失败 112 | ERREXTRAIPDEL, //* 附加ip地址从系统存储器删除失败 113 | ERRIPUPDATED, //* 无法覆盖系统存储器的原值 114 | ERRIPNOSTATIC, //* 动态地址(dhcp)模式下不允许增加、删除、修改ip地址 115 | ERRROUTEENTRYNOR, //* 增加或删除路由条目时系统存储器写入失败 116 | ERRROUTEDEFAULTDEL, //* 缺省路由不能被删除 117 | ERRROUTEENTRYNOTEXIST, //* 路由条目不存在 118 | ERRNETIFSEND, //* 网卡返回发送故障 119 | ERRNOSOCKET, //* 无可用套接字 120 | ERRUNKNOWN, //* 未知错误 121 | } EN_ONPSERR; 122 | 123 | typedef struct _ST_ONPSERR_ { 124 | EN_ONPSERR enCode; 125 | CHAR szDesc[128]; 126 | } ST_ONPSERR, *PST_ONPSERR; 127 | 128 | ONPS_ERRORS_EXT const CHAR *onps_error(EN_ONPSERR enErr); 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /include/onps_md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.21 16:48 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 提供md5摘要计算相关的功能函数 12 | * 13 | */ 14 | #ifndef ONPS_MD5_H 15 | #define ONPS_MD5_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define ONPS_MD5_EXT 19 | #else 20 | #define ONPS_MD5_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | //* MD5摘要值结构体 24 | typedef struct _ST_MD5VAL_ { 25 | UINT a; 26 | UINT b; 27 | UINT c; 28 | UINT d; 29 | } ST_MD5VAL, *PST_MD5VAL; 30 | 31 | ONPS_MD5_EXT ST_MD5VAL onps_md5(UCHAR *pubData, UINT unDataBytes); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/ppp/chap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.01 10:58 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成chap协议相关基础数据结构、宏定义,功能函数声明等相关工作 12 | * 13 | */ 14 | #ifndef CHAP_H 15 | #define CHAP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define CHAP_EXT 19 | #else 20 | #define CHAP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | CHAP_EXT void chap_recv(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/ppp/chat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.22 10:17 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 实现对modem的相关工作状态的检测、迁移等相关操作,比如确定SIM卡是否存在、拨号等操作 12 | * 13 | */ 14 | #ifndef CHAT_H 15 | #define CHAT_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define CHAT_EXT 19 | #else 20 | #define CHAT_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | CHAT_EXT BOOL modem_ready(HTTY hTTY, EN_ONPSERR *penErr); 24 | CHAT_EXT BOOL modem_dial(HTTY hTTY, EN_ONPSERR *penErr); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/ppp/ipcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.03 14:01 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ipcp协议相关基础数据结构、宏定义,功能函数声明等相关工作 12 | * 13 | */ 14 | #ifndef IPCP_H 15 | #define IPCP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define IPCP_EXT 19 | #else 20 | #define IPCP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | IPCP_EXT BOOL ipcp_send_conf_request(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 24 | IPCP_EXT void ipcp_recv(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/ppp/lcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.28 18:16 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成lcp协议相关基础数据结构、宏定义,功能函数声明等相关工作 12 | * 13 | */ 14 | #ifndef LCP_H 15 | #define LCP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define LCP_EXT 19 | #else 20 | #define LCP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | LCP_EXT BOOL lcp_start_negotiation(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 24 | LCP_EXT void lcp_end_negotiation(PSTCB_PPP pstcbPPP); 25 | LCP_EXT BOOL lcp_send_conf_request(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 26 | LCP_EXT BOOL lcp_send_terminate_req(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 27 | LCP_EXT BOOL lcp_send_echo_request(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 28 | LCP_EXT void lcp_recv(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/ppp/negotiation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.24 14:48 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ppp链路的协商工作,为ip层通讯准备好ppp链路 12 | * 13 | */ 14 | #ifndef NEGOTIATION_H 15 | #define NEGOTIATION_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define NEGOTIATION_EXT 19 | #else 20 | #define NEGOTIATION_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "tty.h" 23 | #include "negotiation_storage.h" 24 | 25 | //* 与移动运营商协商建立ppp链路,参数pstcbPPP指向ppp链路控制块,用于保存当前ppp链路的协商状态、所使用的tty终端 26 | //* 的句柄等信息,参数pblIsRunning则用于确保上层调用者可以随时终止当前协商过程 27 | NEGOTIATION_EXT void ppp_link_establish(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 28 | BOOL send_nego_packet(PSTCB_PPP pstcbPPP, USHORT usProtocol, UCHAR ubCode, UCHAR ubIdentifier, UCHAR *pubData, USHORT usDataLen, BOOL blIsWaitACK, EN_ONPSERR *penErr); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/ppp/negotiation_storage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.25 10:26 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 用于保存链路协商结果的存储类结构体及其相关辅助宏定义 12 | * 13 | */ 14 | #ifndef NEGOTIATION_STORAGE_H 15 | #define NEGOTIATION_STORAGE_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define NEGOTIATION_STORAGE_EXT 19 | #else 20 | #define NEGOTIATION_STORAGE_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "ppp_utils.h" 23 | #include "wait_ack_list.h" 24 | 25 | //* LCP相关配置项初始值 26 | #define ACCM_INIT 0 //* ACCM初始值,缺省0~31全部不进行转义 27 | 28 | //* IPCP相关配置项初始值 29 | #define IP_ADDR_INIT 0 30 | #define MASK_INIT 0xFFFFFFFF //* 子网掩码强制为255.255.255.255 31 | #define DNS_ADDR_INIT 0 32 | 33 | //* ppp链路工作状态 34 | typedef enum { 35 | TTYINIT = 0, //* tty终端初始化 36 | STARTNEGOTIATION, //* 开启链路协商 37 | NEGOTIATION, //* 协商 38 | LCPCONFREQ, //* LCP配置协商 39 | STARTAUTHEN, //* 开始认证 40 | AUTHENTICATE, //* 认证中 41 | AUTHENFAILED, //* 认证失败 42 | AUTHENTIMEOUT, //* 认证超时,一直未收到对端下发的challenge报文 43 | SENDIPCPCONFREQ, //* 发送IP层配置协商请求报文 44 | WAITIPCPCONFACK, //* 等待IP层配置协商请求应答报文 45 | ESTABLISHED, //* 链路已建立 46 | SENDECHOREQ, //* 发送echo,链路保持 47 | WAITECHOREPLY, //* 等待echo应答 48 | SENDTERMREQ, //* 发送终止链路请求 49 | WAITTERMACK, //* 等待终止请求应答 50 | TERMINATED, //* 链路已终止 51 | STACKFAULT, //* 协议栈严重故障阶段(软件BUG导致) 52 | } EN_PPP_LINK_STATE; 53 | 54 | //* 记录协商结果 55 | typedef struct _ST_PPPNEGORESULT_ { 56 | struct { 57 | UINT unMagicNum; 58 | USHORT usMRU; 59 | UINT unACCM; 60 | struct { 61 | USHORT usType; 62 | UCHAR ubaData[16]; 63 | } stAuth; 64 | BOOL blIsProtoComp; 65 | BOOL blIsAddrCtlComp; 66 | BOOL blIsNegoValOfProtoComp; 67 | BOOL blIsNegoValOfAddrCtlComp; 68 | } stLCP; 69 | struct { 70 | UINT unAddr; 71 | UINT unPrimaryDNS; 72 | UINT unSecondaryDNS; 73 | UINT unPointToPointAddr; 74 | UINT unSubnetMask; 75 | } stIPCP; 76 | UCHAR ubIdentifier; 77 | UINT unLastRcvedSecs; 78 | } ST_PPPNEGORESULT, *PST_PPPNEGORESULT; 79 | 80 | //* PPP接口控制块 81 | typedef struct _STCB_PPP_ { 82 | HTTY hTTY; 83 | EN_PPP_LINK_STATE enState; 84 | PST_PPPNEGORESULT pstNegoResult; 85 | ST_PPPWAITACKLIST stWaitAckList; 86 | } STCB_PPP, *PSTCB_PPP; 87 | 88 | //* LCP/NCP协议配置请求项处理器相关宏、处理函数及结构体定义 89 | typedef INT(*PFUN_PUTREQITEM)(UCHAR *pubFilled, PST_PPPNEGORESULT pstNegoResult); 90 | typedef INT(*PFUN_GETREQVAL)(UCHAR *pubItem, UCHAR *pubVal, PST_PPPNEGORESULT pstNegoResult); 91 | typedef struct _ST_LNCP_CONFREQ_ITEM_ { 92 | UCHAR ubType; 93 | const CHAR *pszName; 94 | BOOL blIsNegoRequired; //* 是否需要协商,生成初始配置请求报文时需要 95 | PFUN_PUTREQITEM pfunPut; //* 填充请求内容到缓冲区,包括请求类型、长度及数据(如果需要携带数据的话) 96 | PFUN_GETREQVAL pfunGet; //* 从收到的配置请求报文中读取协商值 97 | } ST_LNCP_CONFREQ_ITEM, *PST_LNCP_CONFREQ_ITEM; 98 | 99 | //* LCP/NCP协商处理器,其针对报文代码域携带的值分别进行特定处理,在这里定义处理器相关的基础数据结构、宏、处理函数等定义 100 | typedef void(*PFUN_LNCPNEGOHANDLER)(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen); 101 | typedef struct _ST_LCPNEGOHANDLER_ { 102 | EN_CPCODE enCode; 103 | PFUN_LNCPNEGOHANDLER pfunHandler; 104 | } ST_LNCPNEGOHANDLER, *PST_LNCPNEGOHANDLER; 105 | 106 | //* ppp栈支持的上层协议 107 | typedef struct _ST_PPP_PROTOCOL_ { 108 | USHORT usType; 109 | void(*pfunUpper)(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen); 110 | } ST_PPP_PROTOCOL, *PST_PPP_PROTOCOL; 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /include/ppp/pap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.04.02 19:05 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成pap协议相关基础数据结构、宏定义,功能函数声明等相关工作 12 | * 13 | */ 14 | #ifndef PAP_H 15 | #define PAP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define PAP_EXT 19 | #else 20 | #define PAP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | PAP_EXT BOOL pap_send_auth_request(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr); 24 | PAP_EXT void pap_recv(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/ppp/ppp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.21 10:19 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ppp模块相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef PPP_H 15 | #define PPP_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define PPP_EXT 19 | #else 20 | #define PPP_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | typedef struct _ST_DIAL_AUTH_INFO_ { 24 | const CHAR *pszAPN; //* 指定拨号脚本用到的APN 25 | const CHAR *pszUser; //* ppp认证用户名 26 | const CHAR *pszPassword; //* ppp认证密码 27 | } ST_DIAL_AUTH_INFO, *PST_DIAL_AUTH_INFO; 28 | 29 | PPP_EXT BOOL ppp_init(EN_ONPSERR *penErr); 30 | PPP_EXT void ppp_uninit(void); 31 | PPP_EXT void thread_ppp_handler(void *pvParam); 32 | PPP_EXT const CHAR *get_ppp_port_name(HTTY hTTY); 33 | PPP_EXT const ST_DIAL_AUTH_INFO *get_ppp_dial_auth_info(HTTY hTTY); 34 | PPP_EXT INT get_ppp_index(HTTY hTTY); 35 | PPP_EXT void get_ppp_auth_info(HTTY hTTY, const CHAR **pszUser, const CHAR **pszPassword); 36 | PPP_EXT INT ppp_send(HTTY hTTY, EN_NPSPROTOCOL enProtocol, SHORT sBufListHead, EN_ONPSERR *penErr); 37 | PPP_EXT void ppp_link_terminate(INT nPPPIdx); //* 参数nPPPIdx指定ppp链路索引,也就是说指定终止哪一路ppp链路,索引值对应ppp.c中lr_pszaTTY数组定义的tty口建立的ppp链路 38 | PPP_EXT void ppp_link_recreate(INT nPPPIdx); //* 参数nPPPIdx的含义同上,只有链路当前处于TERMINATED状态才会触发重建操作,其它状态不做任何处理 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/ppp/ppp_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.21 14:04 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * ppp帧结构定义 12 | * 13 | */ 14 | #ifndef PPP_FRAME_H 15 | #define PPP_FRAME_H 16 | #include "ppp_protocols.h" 17 | 18 | //* LCP、PAP、CHAP、NCP等协议基本结构定义 19 | //* =============================================================================================== 20 | #define ACCM_BYTES 32 //* 需要转义的ACCM控制字符的数量 21 | 22 | //* PPP帧头部结构体 23 | PACKED_BEGIN 24 | typedef struct _ST_PPP_HDR_ { 25 | UCHAR ubFlag; //* 标志域,固定字符(参见PPP_FLAG宏),其界定一个完整的PPP帧 26 | UCHAR ubAddr; //* 地址域,固定为PPP_ALLSTATIONS 27 | UCHAR ubCtl; //* 控制域,固定为PPP_UI 28 | USHORT usProtocol; //* 协议域,PPP帧携带的协议类型,参见ppp_protocols.h中前缀为PPP_的相关宏定义,如PPP_IP为IP协议 29 | } PACKED ST_PPP_HDR, *PST_PPP_HDR; 30 | PACKED_END 31 | 32 | //* PPP帧尾部结构体 33 | PACKED_BEGIN 34 | typedef struct _ST_PPP_TAIL_ { 35 | USHORT usFCS; //* 校验和 36 | UCHAR ubDelimiter; //* 定界符,与头部标志字符完全相同(参见PPP_FLAG宏) 37 | } PACKED ST_PPP_TAIL, *PST_PPP_TAIL; 38 | PACKED_END 39 | 40 | PACKED_BEGIN 41 | typedef struct _ST_LNCP_HDR_ { //* LCP/NCP帧头部结构体 42 | UCHAR ubCode; //* 代码域,标识LCP帧报文类型 43 | UCHAR ubIdentifier; //* 标识域,唯一的标识一个报文,用于确定应答报文 44 | USHORT usLen; //* 长度域:代码域 + 标识域 + 长度域 + 可边长的数据域 45 | } PACKED ST_LNCP_HDR, *PST_LNCP_HDR; 46 | PACKED_END 47 | 48 | //* 相关控制协议(LCP、IPCP等)的代码域类型定义 49 | #define CPCODE_NUM 11 //* 协商阶段代码域类型数量 50 | typedef enum { 51 | CONFREQ = 1, //* Configure Request,配置请求 52 | CONFACK = 2, //* Configure Ack,配置请求通过应答 53 | CONFNAK = 3, //* Configure Nak,配置请求的未完全通过应答 54 | CONFREJ = 4, //* Configure Reject,配置请求被拒绝(意味着所有配置项均未通过,换言之接收端完全不支持发送端请求的所有配置项) 55 | TERMREQ = 5, //* Terminate Request,链路结束请求 56 | TERMACK = 6, //* Terminate Ack,链路结束请求应答 57 | CODEREJ = 7, //* Code Reject,非法类型,拒绝执行,接收端会在应答报文中将所拒绝报文的全部内容附上 58 | 59 | PROTREJ = 8, //* Protocol Reject,当PPP帧头中协议域类型非法时,接收端回应该类型的报文给发送端(数据域携带协议类型和数据) 60 | //* 注意该报文只有在LCP状态机处于Opened状态时才会被发送,其它状态接收端直接丢弃协议类型错误的报文 61 | 62 | ECHOREQ = 9, //* Echo Request,用以提供数据链路层的环回机制,该类型报文只有在LCP状态机处于Opened状态时才被允许处理,其它状态会被接收端直接丢弃 63 | ECHOREP = 10, //* Echo Reply,同上,Request的应答报文 64 | DISCREQ = 11, //* Discard Request,提供了一种在数据链路层上的测试机制,一方发送该类型报文,另一方接收后直接丢弃 65 | } EN_CPCODE; 66 | 67 | //* LCP配置请求(CONF_REQ, Configure Request)报文的类型定义 68 | #define LCP_CONFREQ_NUM 7 //* 本程序支持的LCP报文配置请求项的数量 69 | typedef enum { 70 | MRU = 1, //* Maximum Receive Unit 71 | ASYNCMAP = 2, //* Async Control Character Map 72 | AUTHTYPE = 3, //* Authentication Type 73 | QUALITY = 4, //* Quality Protocol,链路质量监测协议 74 | MAGICNUMBER = 5, //* Magic Number,魔术字 75 | 76 | PCOMPRESSION = 7, //* Protocol Field Compression,该选项提供了一种压缩数据链路层(即PPP帧)协议域的方法,PPP帧的协议域占两个字节,协商通过后,编号 77 | //* 小于256的协议压缩为单字节传输,比如PPP_IP,但大于256的则无法压缩。因此,协议栈就就需要同时处理PPP帧协议域占两个字节或1个字节的情形 78 | 79 | ACCOMPRESSION = 8, //* Address/Control Field Compression,压缩数据链路层(即PPP帧)地址域和控制域,因为这两个为固定值可以不发送,所以PPP帧不带FF即认为对端进行了压缩 80 | } EN_LCP_CONFREQ_TYPE; 81 | 82 | //* LCP/NCP配置请求报文单条配置项的头部结构 83 | PACKED_BEGIN 84 | typedef struct _ST_LNCP_CONFREQ_HDR_ { 85 | UCHAR ubType; //* 类型域 86 | UCHAR ubLen; //* 长度域:类型域 + 长度域 + 可变长数据域 87 | } PACKED ST_LNCP_CONFREQ_HDR, *PST_LNCP_CONFREQ_HDR; 88 | PACKED_END 89 | 90 | //* LCP配置请求项之MRU,通知对端“我”这边可以接收多大的包,默认值时1500字节 91 | PACKED_BEGIN 92 | typedef struct _ST_LCP_CONFREQ_MRU_ { 93 | ST_LNCP_CONFREQ_HDR stHdr; 94 | USHORT usMRU; //* 最大接收单元,两个字节 95 | } PACKED ST_LCP_CONFREQ_MRU, *PST_LCP_CONFREQ_MRU; 96 | PACKED_END 97 | 98 | //* ASYNCMAP,即ACCM异步链路控制字符映射 99 | PACKED_BEGIN 100 | typedef struct _ST_LCP_CONFREQ_ASYNCMAP_ { 101 | ST_LNCP_CONFREQ_HDR stHdr; 102 | UINT unMap; 103 | } PACKED ST_LCP_CONFREQ_ASYNCMAP, *PST_LCP_CONFREQ_ASYNCMAP; 104 | PACKED_END 105 | 106 | //* AUTHTYPE,认证类型,该配置项紧跟协议类型值之后为可变长数据域,指定具体协议携带的附加数据 107 | PACKED_BEGIN 108 | typedef struct _ST_LCP_CONFREQ_AUTHTYPE_HDR_ { 109 | ST_LNCP_CONFREQ_HDR stHdr; 110 | USHORT usType; //* 协议值:PPP_PAP/PPP_CHAP/其它 111 | } PACKED ST_LCP_CONFREQ_AUTHTYPE_HDR, *PST_LCP_CONFREQ_AUTHTYPE_HDR; 112 | PACKED_END 113 | 114 | //* QUALITY,链路质量监测协议,该配置项紧跟协议类型值之后为可变长数据域,指定具体协议携带的附加数据 115 | PACKED_BEGIN 116 | typedef struct _ST_LCP_CONFREQ_QUALITY_HDR_ { 117 | ST_LNCP_CONFREQ_HDR stHdr; 118 | USHORT usType; //* 协议值:PPP_LQR/其它 119 | } PACKED ST_LCP_CONFREQ_QUALITY_HDR, *PST_LCP_CONFREQ_QUALITY_HDR; 120 | PACKED_END 121 | 122 | //* MAGICNUMBER,魔术字,监测网络是否存在自环情形,即“短路”——自己发给自己 123 | PACKED_BEGIN 124 | typedef struct _ST_LCP_CONFREQ_MAGICNUMBER_ { 125 | ST_LNCP_CONFREQ_HDR stHdr; 126 | UINT unNum; 127 | } PACKED ST_LCP_CONFREQ_MAGICNUMBER, *PST_LCP_CONFREQ_MAGICNUMBER; 128 | PACKED_END 129 | 130 | //* PCOMPRESSION 131 | PACKED_BEGIN 132 | typedef struct _ST_LCP_CONFREQ_PCOMPRESSION_ { 133 | ST_LNCP_CONFREQ_HDR stHdr; 134 | } PACKED ST_LCP_CONFREQ_PCOMPRESSION, *PST_LCP_CONFREQ_PCOMPRESSION; 135 | PACKED_END 136 | 137 | //* ACCOMPRESSION 138 | PACKED_BEGIN 139 | typedef struct _ST_LCP_CONFREQ_ACCOMPRESSION_ { 140 | ST_LNCP_CONFREQ_HDR stHdr; 141 | } PACKED ST_LCP_CONFREQ_ACCOMPRESSION, *PST_LCP_CONFREQ_ACCOMPRESSION; 142 | PACKED_END 143 | 144 | //* Echo Request 145 | PACKED_BEGIN 146 | typedef struct _ST_LCP_ECHO_REQ_HDR_ { 147 | UINT unLocalMagicNum; 148 | } PACKED ST_LCP_ECHO_REQ_HDR, *PST_LCP_ECHO_REQ_HDR; 149 | PACKED_END 150 | 151 | //* Echo Reply 152 | PACKED_BEGIN 153 | typedef struct _ST_LCP_ECHO_REPLY_HDR_ { 154 | UINT unLocalMagicNum; 155 | UINT unRemoteMagicNum; 156 | } PACKED ST_LCP_ECHO_REPLY_HDR, *PST_LCP_ECHO_REPLY_HDR; 157 | PACKED_END 158 | 159 | //* CHAP协议的数据域结构 160 | #define CHAP_CHALLENGE_LEN 16 //* CHAP协议固定使用MD5算法,挑战字符串的长度固定16个字节 161 | PACKED_BEGIN 162 | typedef struct _ST_CHAP_DATA_ { 163 | UCHAR ubChallengeLen; 164 | UCHAR ubaChallenge[CHAP_CHALLENGE_LEN]; 165 | } ST_CHAP_DATA, *PST_CHAP_DATA; 166 | PACKED_END 167 | 168 | typedef enum { 169 | CHALLENGE = 1, 170 | RESPONSE = 2, 171 | SUCCEEDED = 3, 172 | FAILURE = 4 173 | } EN_CHAPCODE; 174 | 175 | typedef enum { 176 | AUTHREQ = 1, 177 | AUTHPASSED = 2, 178 | AUTHREFUSED = 3 179 | } EN_PAPCODE; 180 | 181 | //* IPCP配置请求项相关宏及数据结构定义 182 | #define IPCP_CONFREQ_NUM 5 //* 本程序支持的IPCP报文配置请求项的数量 183 | typedef enum { 184 | ADDRS = 1, //* IP-Addresses,IP地址选项配置,该选项因为具体应用存在问题现已被停用,只有对端强制要求时才会被启用 185 | COMPRESSION_PROTOCOL = 2, //* IP-Compression-Protocol,指定要使用的压缩协议,缺省不进行压缩,所以这个程序同样不处理这个配置项 186 | ADDR = 3, //* IP-Addr,协商本地使用的IP地址,数据域全为0则要求对端给分配一个地址,此时对端会在CONFNAK帧中携带这个地址 187 | PRIMARYDNS = 129, //* Primary DNS Server addr,协商主DNS服务器地址,数据域全为0则要求对端提供一个DNS地址,对端同样在CONFNAK帧中给出这个地址 188 | 189 | SECONDARYDNS = 131 //* Secondary DNS server addr, 协商次DNS服务器地址,规则与上同 190 | //* 另,130和132用于协商NetBIOS网络节点的主、次地址,本系统不支持 191 | } EN_IPCP_CONFREQ_TYPE; 192 | PACKED_BEGIN 193 | typedef struct _ST_IPCP_CONFREQ_ADDR_ { 194 | ST_LNCP_CONFREQ_HDR stHdr; 195 | UINT unVal; //* 地址 196 | } PACKED ST_IPCP_CONFREQ_ADDR, *PST_IPCP_CONFREQ_ADDR; 197 | PACKED_END 198 | //* =============================================================================================== 199 | 200 | #endif 201 | -------------------------------------------------------------------------------- /include/ppp/ppp_protocols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.21 10:19 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * ppp协议解析相关的宏定义:包括支持的上层协议、协议头相关的标志字符串、地址、MRU等定义 12 | * 13 | */ 14 | #ifndef PPP_PROTOCOLS_H 15 | #define PPP_PROTOCOLS_H 16 | #include "protocols.h" 17 | 18 | #define PPP_ALLSTATIONS 0xFF //* All-Stations broadcast address 19 | #define PPP_UI 0x03 //* Unnumbered Information 20 | #define PPP_FLAG 0x7E //* Flag Sequence 21 | #define PPP_ESCAPE 0x7D //* Asynchronous Control Escape 22 | #define PPP_TRANS 0x20 //* Asynchronous transparency modifier 23 | 24 | #define PPP_INITFCS 0xFFFF //* Initial FCS value 25 | #define PPP_MRU 1500 //* default MRU = max length of info field 26 | 27 | //* PPP支持的上层协议值定义 28 | #define PPP_IP 0x21 //* Internet Protocol 29 | #define PPP_AT 0x29 //* AppleTalk Protocol 30 | #define PPP_IPX 0x2B //* IPX protocol 31 | #define PPP_VJC_COMP 0x2D //* VJ compressed TCP 32 | #define PPP_VJC_UNCOMP 0x2F //* VJ uncompressed TCP 33 | #define PPP_MP 0x3D //* Multilink protocol 34 | #define PPP_IPV6 0x57 //* Internet Protocol Version 6 35 | #define PPP_COMPFRAG 0xFB //* fragment compressed below bundle 36 | #define PPP_COMP 0xFD //* compressed packet 37 | #define PPP_MPLS_UC 0x0281 //* Multi Protocol Label Switching - Unicast 38 | #define PPP_MPLS_MC 0x0283 //* Multi Protocol Label Switching - Multicast 39 | #define PPP_IPCP 0x8021 //* IP Control Protocol 40 | #define PPP_ATCP 0x8029 //* AppleTalk Control Protocol 41 | #define PPP_IPXCP 0x802B //* IPX Control Protocol 42 | #define PPP_IPV6CP 0x8057 //* IPv6 Control Protocol 43 | #define PPP_CCPFRAG 0x80FB //* CCP at link level (below MP bundle) 44 | #define PPP_CCP 0x80FD //* Compression Control Protocol 45 | #define PPP_MPLSCP 0x80FD //* MPLS Control Protocol 46 | #define PPP_LCP 0xC021 //* Link Control Protocol 47 | #define PPP_PAP 0xC023 //* Password Authentication Protocol 48 | #define PPP_LQR 0xC025 //* Link Quality Report protocol 49 | #define PPP_CHAP 0xC223 //* Cryptographic Handshake Auth. Protocol 50 | #define PPP_CBCP 0xC029 //* Callback Control Protocol 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/ppp/ppp_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.21 10:19 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 完成ppp模块相关宏定义、接口函数、结构体定义等工作 12 | * 13 | */ 14 | #ifndef PPP_UTILS_H 15 | #define PPP_UTILS_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define PPP_UTILS_EXT 19 | #else 20 | #define PPP_UTILS_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "ppp_frame.h" 23 | 24 | PPP_UTILS_EXT const CHAR *get_protocol_name(USHORT usProtocol); 25 | PPP_UTILS_EXT const CHAR *get_cpcode_name(EN_CPCODE enCode); 26 | PPP_UTILS_EXT const CHAR *get_chap_code_name(EN_CHAPCODE enCode); 27 | PPP_UTILS_EXT const CHAR *get_pap_code_name(EN_PAPCODE enCode); 28 | PPP_UTILS_EXT USHORT ppp_fcs16(UCHAR *pubData, USHORT usDataLen); 29 | PPP_UTILS_EXT USHORT ppp_fcs16_ext(SHORT sBufListHead); 30 | PPP_UTILS_EXT UINT ppp_escape_encode(UINT unACCM, UCHAR *pubData, UINT unDataLen, UCHAR *pubDstBuf, UINT *punEncodedBytes); 31 | PPP_UTILS_EXT void ppp_escape_encode_init(UINT unACCM, UCHAR ubaACCM[]); 32 | PPP_UTILS_EXT UINT ppp_escape_encode_ext(UCHAR ubaACCM[], UCHAR *pubData, UINT unDataLen, UCHAR *pubDstBuf, UINT *punEncodedBytes); 33 | PPP_UTILS_EXT UINT ppp_escape_decode(UCHAR *pubData, UINT unDataLen, UCHAR *pubDstBuf, UINT *punDecodedBytes); 34 | PPP_UTILS_EXT UINT ppp_escape_decode_ext(UCHAR *pubData, UINT unStartIdx, UINT unEndIdx, UINT unDataBufSize, UCHAR *pubDstBuf, UINT *punDecodedBytes); 35 | #endif 36 | -------------------------------------------------------------------------------- /include/ppp/tty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.22 10:17 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * tty终端,提供与modem设备进行通讯的相关功能函数 12 | * 13 | */ 14 | #ifndef TTY_H 15 | #define TTY_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define TTY_EXT 19 | #else 20 | #define TTY_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | #define TTY_RCV_BUF_SIZE 2048 //* 指定tty接收缓冲区的大小(一定要大于等于最大ppp帧的长度才可) 24 | #define TTY_SEND_BUF_SIZE 256 //* 指定tty发送缓冲区的大小,该缓冲区用于发送前ppp转义,其大小可以任意指定,如果内存够用建议比系统要发送的最大数据报稍大些,这样可以一次转义完毕,一次全部发送,而不是分段转义分段发送 25 | 26 | typedef struct _STCB_TTYIO_ { 27 | HTTY hTTY; 28 | struct { 29 | INT nWriteIdx; 30 | INT nReadIdx; 31 | CHAR bState; 32 | CHAR bErrCount; 33 | } stRecv; 34 | 35 | UCHAR ubaSendBuf[TTY_SEND_BUF_SIZE]; 36 | } STCB_TTYIO, *PSTCB_TTYIO; 37 | 38 | TTY_EXT HTTY tty_init(const CHAR *pszTTYName, EN_ONPSERR *penErr); 39 | TTY_EXT void tty_uninit(HTTY hTTY); 40 | TTY_EXT BOOL tty_ready(HTTY hTTY, EN_ONPSERR *penErr); 41 | TTY_EXT INT tty_recv(INT nPPPIdx, HTTY hTTY, UCHAR *pubRecvBuf, INT nRecvBufLen, void(*pfunPacketHandler)(INT, UCHAR *, INT), INT nWaitSecs, EN_ONPSERR *penErr); 42 | TTY_EXT INT tty_send(HTTY hTTY, UINT unACCM, UCHAR *pubData, INT nDataLen, EN_ONPSERR *penErr); 43 | TTY_EXT INT tty_send_ext(HTTY hTTY, UINT unACCM, SHORT sBufListHead, EN_ONPSERR *penErr); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/ppp/wait_ack_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.29 10:34 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 提供针对ppp协商阶段以及链路保持阶段需要等待应答的报文链表队列的相关管理函数声明及辅助宏定义 12 | * 13 | */ 14 | #ifndef WAIT_ACK_LIST_H 15 | #define WAIT_ACK_LIST_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define WAIT_ACK_LIST_EXT 19 | #else 20 | #define WAIT_ACK_LIST_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | #include "one_shot_timer.h" 23 | 24 | typedef struct _ST_PPPWAITACKLIST_ ST_PPPWAITACKLIST, *PST_PPPWAITACKLIST; 25 | typedef struct _ST_PPPWAITACKNODE_ { //* 等待应答的PPP报文链表节点 26 | struct _ST_PPPWAITACKNODE_ *pstPrev; 27 | struct _ST_PPPWAITACKNODE_ *pstNext; 28 | CHAR bIsUsed; 29 | CHAR bIsAcked; 30 | struct { 31 | UCHAR ubCode; 32 | UCHAR ubIdentifier; 33 | USHORT usProtocol; 34 | } stPacket; 35 | PST_ONESHOTTIMER pstTimer; 36 | PST_PPPWAITACKLIST pstList; 37 | } ST_PPPWAITACKNODE, *PST_PPPWAITACKNODE; 38 | 39 | typedef struct _ST_PPPWAITACKLIST_ { //* 等待应答的PPP报文链表 40 | PST_PPPWAITACKNODE pstHead; 41 | HMUTEX hMutex; 42 | CHAR bPPPIdx; 43 | UCHAR ubIsTimeout; 44 | UCHAR ubTimeoutCount; //* 连续触发超时事件的累计次数 45 | } ST_PPPWAITACKLIST, *PST_PPPWAITACKLIST; 46 | 47 | WAIT_ACK_LIST_EXT BOOL wait_ack_list_init(PST_PPPWAITACKLIST pstWAList, EN_ONPSERR *penErr); 48 | WAIT_ACK_LIST_EXT void wait_ack_list_uninit(PST_PPPWAITACKLIST pstWAList); 49 | WAIT_ACK_LIST_EXT BOOL wait_ack_list_add(PST_PPPWAITACKLIST pstWAList, USHORT usProtocol, UCHAR ubCode, UCHAR ubIdentifier, INT nTimerCount, EN_ONPSERR *penErr); 50 | WAIT_ACK_LIST_EXT void wait_ack_list_del(PST_PPPWAITACKLIST pstWAList, USHORT usProtocol, UCHAR ubIdentifier); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/protocols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.26 10:00 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 协议栈支持的通讯协议类型值 12 | * 13 | */ 14 | #ifndef PROTOCOLS_H 15 | #define PROTOCOLS_H 16 | 17 | //* 协议栈支持的通讯协议类型值,其用于业务逻辑实现 18 | typedef enum { 19 | LCP = 0, 20 | PAP, 21 | CHAP, 22 | IPCP, 23 | #if SUPPORT_IPV6 24 | IPV6CP, 25 | #endif 26 | IPV4, 27 | #if SUPPORT_IPV6 28 | IPV6, 29 | #endif 30 | 31 | ICMP, 32 | #if SUPPORT_IPV6 33 | ICMPV6, 34 | #endif 35 | ARP, 36 | TCP, 37 | UDP, 38 | } EN_NPSPROTOCOL; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ip/udp_link.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "port/os_adapter.h" 17 | #include "one_shot_timer.h" 18 | #include "onps_input.h" 19 | #define SYMBOL_GLOBALS 20 | #include "ip/udp_link.h" 21 | #undef SYMBOL_GLOBALS 22 | 23 | static ST_UDPLINK l_staUdpLinkNode[UDP_LINK_NUM_MAX]; 24 | static PST_UDPLINK l_pstFreeUdpLinkList = NULL; 25 | static HMUTEX l_hMtxUdpLinkList = INVALID_HMUTEX; 26 | 27 | BOOL udp_link_init(EN_ONPSERR *penErr) 28 | { 29 | //* 链接 30 | INT i; 31 | for (i = 0; i < UDP_LINK_NUM_MAX - 1; i++) 32 | { 33 | l_staUdpLinkNode[i].bIdx = i; 34 | l_staUdpLinkNode[i].bNext = i + 1; 35 | } 36 | l_staUdpLinkNode[i].bIdx = i; 37 | l_staUdpLinkNode[i].bNext = -1; 38 | l_pstFreeUdpLinkList = &l_staUdpLinkNode[0]; 39 | 40 | l_hMtxUdpLinkList = os_thread_mutex_init(); 41 | if (INVALID_HMUTEX != l_hMtxUdpLinkList) 42 | return TRUE; 43 | 44 | if (penErr) 45 | *penErr = ERRMUTEXINITFAILED; 46 | return FALSE; 47 | } 48 | 49 | void udp_link_uninit(void) 50 | { 51 | if (INVALID_HMUTEX != l_hMtxUdpLinkList) 52 | os_thread_mutex_uninit(l_hMtxUdpLinkList); 53 | } 54 | 55 | PST_UDPLINK udp_link_get(EN_ONPSERR *penErr) 56 | { 57 | PST_UDPLINK pstFreeNode; 58 | os_thread_mutex_lock(l_hMtxUdpLinkList); 59 | { 60 | if (NULL == l_pstFreeUdpLinkList) 61 | { 62 | os_thread_mutex_unlock(l_hMtxUdpLinkList); 63 | 64 | if (penErr) 65 | *penErr = ERRNOUDPLINKNODE; 66 | 67 | return NULL; 68 | } 69 | 70 | pstFreeNode = l_pstFreeUdpLinkList; 71 | if (l_pstFreeUdpLinkList->bNext >= 0) 72 | l_pstFreeUdpLinkList = &l_staUdpLinkNode[l_pstFreeUdpLinkList->bNext]; 73 | else 74 | l_pstFreeUdpLinkList = NULL; 75 | } 76 | os_thread_mutex_unlock(l_hMtxUdpLinkList); 77 | 78 | pstFreeNode->stPeerAddr.saddr_ipv4 = 0; 79 | pstFreeNode->stPeerAddr.usPort = 0; 80 | return pstFreeNode; 81 | } 82 | 83 | void udp_link_free(PST_UDPLINK pstUdpLink) 84 | { 85 | os_thread_mutex_lock(l_hMtxUdpLinkList); 86 | { 87 | if (l_pstFreeUdpLinkList) 88 | pstUdpLink->bNext = l_pstFreeUdpLinkList->bIdx; 89 | else 90 | pstUdpLink->bNext = -1; 91 | l_pstFreeUdpLinkList = pstUdpLink; 92 | } 93 | os_thread_mutex_unlock(l_hMtxUdpLinkList); 94 | } 95 | -------------------------------------------------------------------------------- /mmu/buf_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/os_datatype.h" 14 | #include "port/os_adapter.h" 15 | #include "port/sys_config.h" 16 | #include "onps_errors.h" 17 | 18 | #define SYMBOL_GLOBALS 19 | #include "mmu/buf_list.h" 20 | #undef SYMBOL_GLOBALS 21 | 22 | //* 不使用结构体设计方式,目的是为了节省内存,同时避免因使用强制对齐方式降低系统执行性能的问题 23 | static void *l_pvaBufNode[BUF_LIST_NUM]; 24 | static USHORT l_usaBufSize[BUF_LIST_NUM]; 25 | static SHORT l_saFreeBufNode[BUF_LIST_NUM]; 26 | static SHORT l_sFreeBufList = -1; 27 | //static HMUTEX l_hMtxMMUBufList = INVALID_HMUTEX; 28 | 29 | //* 协议栈初始加载时别忘了要先调用这个初始设置函数 30 | BOOL buf_list_init(EN_ONPSERR *penErr) 31 | { 32 | INT i; 33 | 34 | //* 清0 35 | memset(l_pvaBufNode, 0, sizeof(l_pvaBufNode)); 36 | 37 | //* 链接 38 | for (i = 0; i < BUF_LIST_NUM - 1; i++) 39 | l_saFreeBufNode[i] = i + 1; 40 | l_saFreeBufNode[BUF_LIST_NUM - 1] = -1; 41 | l_sFreeBufList = 0; 42 | 43 | #if 0 44 | l_hMtxMMUBufList = os_thread_mutex_init(); 45 | if (INVALID_HMUTEX != l_hMtxMMUBufList) 46 | return TRUE; 47 | 48 | if(penErr) 49 | *penErr = ERRMUTEXINITFAILED; 50 | return FALSE; 51 | #else 52 | return TRUE; 53 | #endif 54 | } 55 | 56 | void buf_list_uninit(void) 57 | { 58 | //if (INVALID_HMUTEX != l_hMtxMMUBufList) 59 | // os_thread_mutex_uninit(l_hMtxMMUBufList); 60 | } 61 | 62 | SHORT buf_list_get(EN_ONPSERR *penErr) 63 | { 64 | SHORT sRtnNode; 65 | 66 | os_critical_init(); 67 | 68 | //os_thread_mutex_lock(l_hMtxMMUBufList); 69 | os_enter_critical(); 70 | { 71 | if (l_sFreeBufList < 0) 72 | { 73 | os_exit_critical(); 74 | //os_thread_mutex_unlock(l_hMtxMMUBufList); 75 | 76 | if (penErr) 77 | *penErr = ERRNOBUFLISTNODE; 78 | 79 | return -1; 80 | } 81 | 82 | sRtnNode = l_sFreeBufList; 83 | l_sFreeBufList = l_saFreeBufNode[l_sFreeBufList]; 84 | } 85 | //os_thread_mutex_unlock(l_hMtxMMUBufList); 86 | os_exit_critical(); 87 | 88 | return sRtnNode; 89 | } 90 | 91 | SHORT buf_list_get_ext(void *pvData, UINT unDataSize, EN_ONPSERR *penErr) 92 | { 93 | SHORT sRtnNode; 94 | 95 | os_critical_init(); 96 | 97 | //os_thread_mutex_lock(l_hMtxMMUBufList); 98 | os_enter_critical(); 99 | { 100 | if (l_sFreeBufList < 0) 101 | { 102 | //os_thread_mutex_unlock(l_hMtxMMUBufList); 103 | os_exit_critical(); 104 | 105 | if (penErr) 106 | *penErr = ERRNOBUFLISTNODE; 107 | 108 | return -1; 109 | } 110 | 111 | sRtnNode = l_sFreeBufList; 112 | l_sFreeBufList = l_saFreeBufNode[l_sFreeBufList]; 113 | } 114 | os_exit_critical(); 115 | //os_thread_mutex_unlock(l_hMtxMMUBufList); 116 | 117 | l_pvaBufNode[sRtnNode] = pvData; 118 | l_usaBufSize[sRtnNode] = (USHORT)unDataSize; 119 | return sRtnNode; 120 | } 121 | 122 | void buf_list_attach_data(SHORT sNode, void *pvData, UINT unDataSize) 123 | { 124 | l_pvaBufNode[sNode] = pvData; 125 | l_usaBufSize[sNode] = (USHORT)unDataSize; 126 | } 127 | 128 | void buf_list_free(SHORT sNode) 129 | { 130 | if (sNode < 0) 131 | return; 132 | 133 | os_critical_init(); 134 | 135 | //os_thread_mutex_lock(l_hMtxMMUBufList); 136 | os_enter_critical(); 137 | { 138 | l_pvaBufNode[sNode] = NULL; 139 | l_usaBufSize[sNode] = 0; 140 | l_saFreeBufNode[sNode] = l_sFreeBufList; 141 | l_sFreeBufList = sNode; 142 | } 143 | //os_thread_mutex_unlock(l_hMtxMMUBufList); 144 | os_exit_critical(); 145 | } 146 | 147 | void buf_list_free_head(SHORT *psHead, SHORT sNode) 148 | { 149 | if (sNode < 0) 150 | return; 151 | 152 | *psHead = l_saFreeBufNode[sNode]; 153 | buf_list_free(sNode); 154 | } 155 | 156 | void buf_list_put_head(SHORT *psHead, SHORT sNode) 157 | { 158 | l_saFreeBufNode[sNode] = *psHead; 159 | *psHead = sNode; 160 | } 161 | 162 | void buf_list_put_tail(SHORT sHead, SHORT sNode) 163 | { 164 | SHORT sNextNode = sHead; 165 | while (sNextNode >= 0) 166 | { 167 | if (l_saFreeBufNode[sNextNode] < 0) 168 | { 169 | l_saFreeBufNode[sNextNode] = sNode; 170 | l_saFreeBufNode[sNode] = -1; 171 | break; 172 | } 173 | 174 | sNextNode = l_saFreeBufNode[sNextNode]; 175 | } 176 | } 177 | 178 | void *buf_list_get_next_node(SHORT *psNextNode, USHORT *pusDataLen) 179 | { 180 | if (*psNextNode < 0) 181 | return NULL; 182 | 183 | void *pvData = NULL; 184 | *pusDataLen = l_usaBufSize[*psNextNode]; 185 | pvData = l_pvaBufNode[*psNextNode]; 186 | *psNextNode = l_saFreeBufNode[*psNextNode]; 187 | 188 | return pvData; 189 | } 190 | 191 | UINT buf_list_get_len(SHORT sBufListHead) 192 | { 193 | SHORT sNextNode = sBufListHead; 194 | USHORT usDataLen; 195 | UINT unTotalLen = 0; 196 | 197 | while (NULL != buf_list_get_next_node(&sNextNode, &usDataLen)) 198 | unTotalLen += (UINT)usDataLen; 199 | 200 | return unTotalLen; 201 | } 202 | 203 | //* 将list保存地报文取出、合并后保存到参数pubPacket指向的缓冲区 204 | void buf_list_merge_packet(SHORT sBufListHead, UCHAR *pubPacket) 205 | { 206 | SHORT sNextNode = sBufListHead; 207 | UCHAR *pubData; 208 | USHORT usDataLen; 209 | UINT unMergeBytes = 0; 210 | 211 | __lblGetNextNode: 212 | pubData = (UCHAR *)buf_list_get_next_node(&sNextNode, &usDataLen); 213 | if (NULL == pubData) 214 | return; 215 | 216 | //* 搬运数据 217 | memcpy(pubPacket + unMergeBytes, pubData, usDataLen); 218 | unMergeBytes += (UINT)usDataLen; 219 | 220 | goto __lblGetNextNode; 221 | } 222 | 223 | SHORT buf_list_free_nodes_num(void) 224 | { 225 | SHORT sFreeNodesNum = 0; 226 | os_critical_init(); 227 | 228 | os_enter_critical(); 229 | { 230 | if (!(l_sFreeBufList < 0)) 231 | { 232 | SHORT sNextNode = l_sFreeBufList; 233 | while (!(sNextNode < 0)) 234 | { 235 | sFreeNodesNum++; 236 | sNextNode = l_saFreeBufNode[sNextNode]; 237 | } 238 | } 239 | } 240 | os_exit_critical(); 241 | 242 | return sFreeNodesNum; 243 | } 244 | -------------------------------------------------------------------------------- /net_tools/sntp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "port/os_adapter.h" 17 | #include "mmu/buddy.h" 18 | #include "onps_utils.h" 19 | #include "onps_input.h" 20 | #include "netif/netif.h" 21 | #include "netif/route.h" 22 | #include "ip/udp.h" 23 | #include "net_tools/dns.h" 24 | #define SYMBOL_GLOBALS 25 | #include "net_tools/sntp.h" 26 | #undef SYMBOL_GLOBALS 27 | 28 | #if NETTOOLS_SNTP 29 | time_t sntp_update(in_addr_t unNtpSrvIp, time_t(*pfunTime)(void), void(*pfunSetSysTime)(time_t), CHAR bTimeZone, EN_ONPSERR *penErr) 30 | { 31 | UNI_SNTP_FLAG uniFlag; 32 | ST_SNTP_DATA stData; 33 | UCHAR ubRetryNum = 0; 34 | INT nSndBytes, nRcvBytes; 35 | time_t tTimestamp = 0; 36 | ULONGLONG ullTransTimestatmp; 37 | 38 | //* 新建一个udp客户端 39 | #if SUPPORT_IPV6 40 | INT nClient = onps_input_new(AF_INET, IPPROTO_UDP, penErr); 41 | #else 42 | INT nClient = onps_input_new(IPPROTO_UDP, penErr); 43 | #endif 44 | if (nClient < 0) 45 | return 0; 46 | 47 | CHAR bRcvTimeout = 3; 48 | if (!onps_input_set(nClient, IOPT_SETRCVTIMEOUT, &bRcvTimeout, penErr)) 49 | goto __lblEnd; 50 | 51 | __lblSend: 52 | ubRetryNum++; 53 | if (ubRetryNum > 3) 54 | { 55 | if (penErr) 56 | *penErr = ERRWAITACKTIMEOUT; 57 | goto __lblEnd; 58 | } 59 | 60 | //* 填充报文 61 | uniFlag.stb8.li = 0; 62 | uniFlag.stb8.ver = 3; 63 | uniFlag.stb8.mode = 3; 64 | stData.ubFlag = uniFlag.ubVal; 65 | stData.ubStratum = 0; 66 | stData.ubPoll = 1; //* 2^1 = 2秒 67 | stData.ubPrecision = 0/*-16*/; //* 时钟精度 2^(-16) = 152.58微秒,也可以置为0 68 | stData.unRootDelay = 0; 69 | stData.unRootDispersion = 0; 70 | stData.unRefId = 0; 71 | stData.ullRefTimestamp = 0; 72 | stData.ullOrigiTimestamp = 0; 73 | stData.ullRcvTimestamp = 0; 74 | ullTransTimestatmp = pfunTime ? (ULONGLONG)pfunTime() : 0; 75 | stData.ullTransTimestatmp = htonll(((ULONGLONG)DIFF_SEC_1900_1970 + ullTransTimestatmp) << 32); 76 | 77 | //* 发送对时报文 78 | nSndBytes = udp_sendto(nClient, unNtpSrvIp, SNTP_SRV_PORT, (UCHAR *)&stData, sizeof(ST_SNTP_DATA)); 79 | if (nSndBytes < 0) 80 | { 81 | onps_get_last_error(nClient, penErr); 82 | goto __lblEnd; 83 | } 84 | 85 | //* 等待应答 86 | nRcvBytes = udp_recv_upper(nClient, (UCHAR *)&stData, sizeof(stData), NULL, NULL, bRcvTimeout); 87 | if (nRcvBytes > 0) 88 | { 89 | //* 非常简单的处理逻辑,就是本身单片机系统的时钟就不够精确,同时,现代网络已经足够快,所以这里直接用服务器端的应答报文离开时间作为校准时间 90 | ULONGLONG ullSrvTime = htonll(stData.ullTransTimestatmp); 91 | PUNI_ULONG_LONG puniSrvTime = (PUNI_ULONG_LONG)&ullSrvTime; 92 | tTimestamp = puniSrvTime->stUInt64.h - DIFF_SEC_1900_1970 + (((INT)bTimeZone) * 3600); 93 | pfunSetSysTime(tTimestamp); 94 | 95 | goto __lblEnd; 96 | } 97 | else 98 | { 99 | if (nRcvBytes < 0) 100 | goto __lblEnd; 101 | } 102 | 103 | goto __lblSend; 104 | 105 | __lblEnd: 106 | onps_input_free(nClient); 107 | return tTimestamp; 108 | } 109 | 110 | time_t sntp_update_by_ip(const CHAR *pszNtpSrvIp, time_t(*pfunTime)(void), void(*pfunSetSysTime)(time_t), CHAR bTimeZone, EN_ONPSERR *penErr) 111 | { 112 | return sntp_update(inet_addr(pszNtpSrvIp), pfunTime, pfunSetSysTime, bTimeZone, penErr); 113 | } 114 | 115 | #if NETTOOLS_DNS_CLIENT 116 | time_t sntp_update_by_dns(const CHAR *pszDomainName, time_t(*pfunTime)(void), void(*pfunSetSysTime)(time_t), CHAR bTimeZone, EN_ONPSERR *penErr) 117 | { 118 | time_t tRtnVal = 0; 119 | in_addr_t unPrimaryDNS, unSecondaryDNS; 120 | INT nDnsClient = dns_client_start(&unPrimaryDNS, &unSecondaryDNS, 3, penErr); 121 | if (nDnsClient < 0) 122 | return 0; 123 | 124 | //* 查询ntp服务器地址 125 | in_addr_t unNtpSrvIp = dns_client_query(nDnsClient, unPrimaryDNS, unSecondaryDNS, pszDomainName, penErr); 126 | dns_client_end(nDnsClient); 127 | 128 | //* 获得服务器地址则同步时间 129 | if (unNtpSrvIp) 130 | tRtnVal = sntp_update(unNtpSrvIp, pfunTime, pfunSetSysTime, bTimeZone, penErr); 131 | 132 | return tRtnVal; 133 | } 134 | #endif 135 | #endif 136 | -------------------------------------------------------------------------------- /net_tools/telnet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "port/os_adapter.h" 17 | #include "mmu/buddy.h" 18 | #include "onps_utils.h" 19 | #include "onps_input.h" 20 | #include "netif/netif.h" 21 | #include "netif/route.h" 22 | #include "bsd/socket.h" 23 | 24 | #if NETTOOLS_TELNETSRV 25 | #define SYMBOL_GLOBALS 26 | #include "net_tools/telnet.h" 27 | #undef SYMBOL_GLOBALS 28 | 29 | void telnet_cmd_send(SOCKET hSocket, UCHAR ubCmd, UCHAR ubOption) 30 | { 31 | ST_TELNETPKT_CMD stCmd; 32 | stCmd.ubIAC = TELNETCMD_IAC; 33 | stCmd.ubCmd = ubCmd; 34 | stCmd.ubNegoOption = ubOption; 35 | send(hSocket, (UCHAR *)&stCmd, sizeof(ST_TELNETPKT_CMD), 1); 36 | } 37 | 38 | //* 协议栈不支持的协商选项一律禁止激活,该函数按照这个原则回馈应答 39 | void telnet_cmd_ack_default(SOCKET hSocket, UCHAR ubCmd, UCHAR ubOption) 40 | { 41 | if (TELNETCMD_WILL == ubCmd) 42 | telnet_cmd_send(hSocket, TELNETCMD_DONT, ubOption); 43 | else if (TELNETCMD_WONT == ubCmd) 44 | telnet_cmd_send(hSocket, TELNETCMD_DONT, ubOption); 45 | else if (TELNETCMD_DO == ubCmd) 46 | telnet_cmd_send(hSocket, TELNETCMD_WONT, ubOption); 47 | else if (TELNETCMD_DONT == ubCmd) 48 | telnet_cmd_send(hSocket, TELNETCMD_WONT, ubOption); 49 | else; 50 | } 51 | 52 | void telnet_req_term_type(SOCKET hSocket) 53 | { 54 | //* 发送请求,要求对端上报终端类型 55 | ST_TELNETPKT_SOPT_TERMTYPE stSubOptTermType; 56 | stSubOptTermType.ubSIAC = TELNETCMD_IAC; 57 | stSubOptTermType.ubSB = TELNETCMD_SB; 58 | stSubOptTermType.ubOption = TELNETOPT_TERMTYPE; 59 | stSubOptTermType.ubCode = TELNETOPT_TTCODE_SEND; 60 | stSubOptTermType.ubEIAC = TELNETCMD_IAC; 61 | stSubOptTermType.ubSE = TELNETCMD_SE; 62 | send(hSocket, (UCHAR *)&stSubOptTermType, sizeof(ST_TELNETPKT_SOPT_TERMTYPE), 1); 63 | } 64 | 65 | void telnet_report_term_type(SOCKET hSocket, const CHAR *pszTermType, INT nTremTypeLen) 66 | { 67 | UCHAR ubaSndBuf[sizeof(ST_TELNETPKT_SOPT_TERMTYPE) + TERM_NAME_MAX]; 68 | PST_TELNETPKT_SOPT_TERMTYPE pstTermType = (PST_TELNETPKT_SOPT_TERMTYPE)ubaSndBuf; 69 | pstTermType->ubSIAC = TELNETCMD_IAC; 70 | pstTermType->ubSB = TELNETCMD_SB; 71 | pstTermType->ubOption = TELNETOPT_TERMTYPE; 72 | pstTermType->ubCode = TELNETOPT_TTCODE_IS; 73 | memcpy(&ubaSndBuf[offsetof(ST_TELNETPKT_SOPT_TERMTYPE, ubEIAC)], pszTermType, nTremTypeLen); 74 | ubaSndBuf[offsetof(ST_TELNETPKT_SOPT_TERMTYPE, ubEIAC) + nTremTypeLen] = TELNETCMD_IAC; 75 | ubaSndBuf[offsetof(ST_TELNETPKT_SOPT_TERMTYPE, ubEIAC) + nTremTypeLen + 1] = TELNETCMD_SE; 76 | send(hSocket, (UCHAR *)ubaSndBuf, sizeof(ST_TELNETPKT_SOPT_TERMTYPE) + nTremTypeLen, 1); 77 | } 78 | #endif 79 | -------------------------------------------------------------------------------- /onps_entry.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #define SYMBOL_GLOBALS 13 | #include "onps.h" 14 | #undef SYMBOL_GLOBALS 15 | 16 | HMUTEX o_hMtxPrintf = INVALID_HMUTEX; 17 | BOOL open_npstack_load(EN_ONPSERR *penErr) 18 | { 19 | //* lcp魔术字生成及tcp/udp端口号动态分配都需要随机数生成函数,所以协议栈启动时先设置个种子,确保栈每次启动时生成不同的随机数 20 | srand(os_get_system_msecs()); 21 | 22 | do { 23 | if (!buddy_init(penErr)) 24 | break; 25 | 26 | if (!buf_list_init(penErr)) 27 | break; 28 | 29 | #if SUPPORT_PRINTF && PRINTF_THREAD_MUTEX 30 | o_hMtxPrintf = os_thread_mutex_init(); 31 | if (INVALID_HMUTEX == o_hMtxPrintf) 32 | { 33 | *penErr = ERRMUTEXINITFAILED; 34 | break; 35 | } 36 | #endif 37 | 38 | if (!one_shot_timer_init(penErr)) 39 | break; 40 | 41 | if (!onps_input_init(penErr)) 42 | break; 43 | 44 | if (!netif_init(penErr)) 45 | break; 46 | 47 | if (!route_table_init(penErr)) 48 | break; 49 | 50 | #if SUPPORT_PPP 51 | if (!ppp_init(penErr)) 52 | break; 53 | #endif 54 | 55 | #if SUPPORT_ETHERNET 56 | ethernet_init(); 57 | #endif 58 | 59 | //* 启动协议栈 60 | os_thread_onpstack_start(NULL); 61 | 62 | return TRUE; 63 | } while (FALSE); 64 | 65 | netif_uninit(); 66 | onps_input_uninit(); 67 | 68 | if (INVALID_HMUTEX != o_hMtxPrintf) 69 | os_thread_mutex_uninit(o_hMtxPrintf); 70 | 71 | buf_list_uninit(); 72 | buddy_uninit(); 73 | one_shot_timer_uninit(); 74 | 75 | return FALSE; 76 | } 77 | 78 | void open_npstack_unload(void) 79 | { 80 | #if SUPPORT_PPP 81 | ppp_uninit(); 82 | #endif 83 | route_table_uninit(); 84 | netif_uninit(); 85 | one_shot_timer_uninit(); 86 | onps_input_uninit(); 87 | 88 | if (INVALID_HMUTEX != o_hMtxPrintf) 89 | os_thread_mutex_uninit(o_hMtxPrintf); 90 | 91 | buf_list_uninit(); 92 | buddy_uninit(); 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /onps_errors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #define SYMBOL_GLOBALS 15 | #include "onps_errors.h" 16 | #undef SYMBOL_GLOBALS 17 | #include "port/os_datatype.h" 18 | #include "port/os_adapter.h" 19 | 20 | static const ST_ONPSERR lr_staErrorList[] = { 21 | { ERRNO, "no errors" }, 22 | { ERRNOPAGENODE, "no page nodes available"}, 23 | { ERRREQMEMTOOLARGE, "The requested memory is too large, please refer to the macro definition BUDDY_MEM_SIZE" }, 24 | { ERRNOFREEMEM, "The mmu has no memory available" }, 25 | { ERRMUTEXINITFAILED, "thread mutex initialization failed" }, 26 | { ERRNOBUFLISTNODE, "the buffer list is empty" }, 27 | { ERRSEMINITFAILED, "thread semphore initialization failed" }, 28 | { ERROPENTTY, "tty open error" }, 29 | { ERRATWRITE, "write AT command error" }, 30 | { ERRATEXEC, "the at command returned an error" }, 31 | { ERRATEXECTIMEOUT, "AT command exec timeout" }, 32 | { ERRSIMCARD, "no sim card detected" }, 33 | { ERRREGMOBILENET, "Unable to register to mobile network" }, 34 | { ERRPPPIDXOVERFLOW, "ppp link index overflow" }, 35 | { ERRPPPDELIMITER, "ppp frame delimiter not found" }, 36 | { ERRTOOMANYTTYS, "too many ttys" }, 37 | { ERRTTYHANDLE, "invalid tty handle" }, 38 | { ERROSADAPTER, "os adaptation layer error" }, 39 | { ERRUNKNOWNPROTOCOL, "Unknown protocol type" }, 40 | { ERRPPPFCS, "ppp frame checksum error" }, 41 | { ERRNOIDLETIMER, "no idle timer" }, 42 | { ERRNOFREEPPWANODE, "Node unavailable for ppp negotiation wait" }, 43 | { ERRPPPWALISTNOINIT, "ppp's waiting list for ack is not initialized" }, 44 | { ERRNONETIFNODE, "no netif nodes available" }, 45 | { ERRNONETIFFOUND, "No network interface found" }, 46 | { ERRINPUTOVERFLOW, "Handle/Input overflow" }, 47 | { ERRUNSUPPIPPROTO, "Unsupported ip upper layer protocol" }, 48 | { ERRUNSUPPIOPT, "Unsupported control options" }, 49 | { ERRIPROTOMATCH, "Protocol match error" }, 50 | { ERRNOROUTENODE, "no route nodes available" }, 51 | { ERRADDRESSING,"Addressing failure, default route does not exist" }, 52 | { ERRADDRFAMILIES, "Unsupported address families" }, 53 | { ERRSOCKETTYPE, "Unsupported socket type" }, 54 | { ERRNOATTACH, "Attached data address is null" }, 55 | { ERRTCSNONTCP, "Non-TCP can't get/set tcp link state" }, 56 | { ERRTDSNONTCP, "Non-TCP can't get tcp send data state" }, 57 | { ERRTCPCONNTIMEOUT, "tcp connection timeout" }, 58 | { ERRTCPCONNRESET, "tcp connection reset by peer" }, 59 | { ERRTCPCONNCLOSED, "TCP link closed" }, 60 | { ERRDATAEMPTY, "tcp/udp data segment is empty" }, 61 | { ERRTCPACKTIMEOUT, "tcp ack timeout" }, 62 | { ERRNOTCPLINKNODE, "the tcp link list is empty" }, 63 | { ERRTCPNOTCONNECTED, "tcp link not connected" }, 64 | { ERRINVALIDSEM, "invalid semaphore" }, 65 | { ERRSENDZEROBYTES, "0 bytes of data are sent" }, 66 | { ERRPORTOCCUPIED, "Port is already occupied" }, 67 | { ERRSENDADDR, "destination address is empty" }, 68 | { ERRETHEXTRAEMPTY, "No eth additional info node available" }, 69 | { ERRNETUNREACHABLE, "Network unreachable" }, 70 | { ERRROUTEADDRMATCH, "Addressing result does not match" }, 71 | { ERRNEWARPCTLBLOCK, "arp control block is empty" }, 72 | { ERRUNSUPPETHIIPROTO, "unsupported ethernet ii upper layer protocol(only ipv4/arp/rarp/ipv6)" }, 73 | { ERRPACKETTOOLARGE, "packet too large" }, 74 | { ERRPORTEMPTY, "port number is empty" }, 75 | { ERRWAITACKTIMEOUT, "Timeout waiting for the reply packet" }, 76 | { ERRIPCONFLICT, "ip address conflict" }, 77 | { ERRNOTBINDADDR, "The socket does not bind the address" }, 78 | { ERRTCPONLY, "Only supports tcp protocol" }, 79 | { ERRTCPSRVEMPTY, "tcp server resource is empty"}, 80 | { ERRTCPBACKLOGEMPTY, "backlog resource for tcp server is empty" }, 81 | { ERRTCPRCVQUEUEEMPTY, "recv queue resource for tcp server is empty" }, 82 | { ERRTCPNOLISTEN, "tcp server does not enter the listen stage" }, 83 | { ERRTCPBACKLOGFULL, "backlog resource for tcp server is full" }, 84 | { ERRDNSQUERYFMT, "The format of the dns query packet is wrong" }, 85 | { ERRDNSSRV, "dns server failure" }, 86 | { ERRDNSNAME, "domain name does not exist" }, 87 | { ERRDNSQUERYTYPE, "unsupported dns query type" }, 88 | { ERRDNSREFUSED, "Refused by DNS server" }, 89 | { ERRDNSNOTRESOLVED, "not resolved to ip address" }, 90 | { ERRNOUDPLINKNODE, "the udp link list is empty" }, 91 | { ERRTCPLINKCBNULL, "the tcp link control block is NULL" }, 92 | #if SUPPORT_IPV6 93 | { ERRNEWIPv6MACCTLBLOCK, "The control block of the ipv6 to mac address mapping table is empty" }, 94 | { ERRNOIPv6DYNADDRNODE, "the ipv6 dynamic addr list is empty" }, 95 | { ERRNOIPv6ROUTERNODE, "the ipv6 router list is empty" }, 96 | { ERRIPV4FLOWLABEL, "Ipv4 does not support flow label fields" }, 97 | { ERRNODv6CLTCBNODE, "Dhcpv6 client control block list is empty" }, 98 | { ERRROUTERINDEX, "router index overflow" }, 99 | #endif 100 | { ERRFAMILYINCONSISTENT, "The address family of the target and source addresses is inconsistent" }, 101 | { ERRUNSUPPORTEDFAMILY, "Unsupported address family" }, 102 | #if NETTOOLS_TELNETSRV 103 | { ERRNOTELNETCLTCBNODE, "Telnet client control block list is empty" }, 104 | { ERRNVTSTART, "Network virtual terminal startup failed" }, 105 | #endif 106 | { ERRNETIFNOTFOUND, "no network interface found" }, 107 | { ERREXTRAIPLIMIT, "exceeded maximum number of IP addresses" }, 108 | { ERREXTRAIPSAVE, "failed to write the IP address to the system memory" }, 109 | { ERREXTRAIPDEL, "failed to remove IP address from system memory" }, 110 | { ERRIPUPDATED, "unable to overwrite the original value in the system memory" }, 111 | { ERRIPNOSTATIC, "adding, deleting, or updating IP addresses is not allowed in DHCP mode" }, 112 | { ERRROUTEENTRYNOR, "failed to write to system memory when adding or deleting routing entries" }, 113 | { ERRROUTEDEFAULTDEL, "the default route cannot be deleted" }, 114 | { ERRROUTEENTRYNOTEXIST, "the routing entry does not exist" }, 115 | { ERRNETIFSEND, "The network card returns a sending failure" }, 116 | { ERRNOSOCKET, "No socket available" }, 117 | { ERRUNKNOWN, "unknown error" } 118 | }; 119 | 120 | const CHAR *onps_error(EN_ONPSERR enErr) 121 | { 122 | UINT unIndex = (UINT)enErr; 123 | if (unIndex < sizeof(lr_staErrorList) / sizeof(ST_ONPSERR)) 124 | return lr_staErrorList[unIndex].szDesc; 125 | 126 | return "unrecognized error code"; 127 | } 128 | -------------------------------------------------------------------------------- /onps栈API接口手册.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/onps栈API接口手册.pdf -------------------------------------------------------------------------------- /onps栈架构图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/onps栈架构图.jpg -------------------------------------------------------------------------------- /onps栈用户使用手册.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/onps栈用户使用手册.pdf -------------------------------------------------------------------------------- /onps栈移植手册.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/onps栈移植手册.pdf -------------------------------------------------------------------------------- /onps网络协议栈技术交流群群二维码.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/onps网络协议栈技术交流群群二维码.png -------------------------------------------------------------------------------- /onps网络协议栈移植及使用说明.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/onps网络协议栈移植及使用说明.pdf -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "onps", 3 | "description": "An open-source network protocol stack that provides complete implementation of the ethernet/ppp/ip/ipv6/tcp/udp/arp/icmp protocol family, and also provides network tools such as sntp, dns, ping, telnet, etc.", 4 | "description_zh": "一个开源的国产网络协议栈,提供完整的ethernet/ppp/ip/ipv6/tcp/udp/arp/icmp协议族实现,提供sntp、dns、ping、telnet等网络工具", 5 | "enable": "PKG_USING_ONPS", 6 | "keywords": [ 7 | "onps", "tcp/ip", "ipv6", "lwip", "telnet", "ping", "ntp", "dns" 8 | ], 9 | "category": "system", 10 | "author": { 11 | "name": "Neo-T", 12 | "email": "marsstory99@hotmail.com", 13 | "gitee": "Neo-T", 14 | "github": "Neo-T" 15 | }, 16 | "license": "Apache-2.0", 17 | "repository": "https://gitee.com/Neo-T/open-npstack/tree/v1.1.0.230726", 18 | "icon": "unknown", 19 | "homepage": "https://gitee.com/Neo-T/open-npstack/tree/v1.1.0.230726#readme", 20 | "doc": "https://gitee.com/Neo-T/open-npstack/blob/v1.1.0.230726/onps%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE%E6%A0%88%E7%A7%BB%E6%A4%8D%E5%8F%8A%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.pdf", 21 | "site": [ 22 | { 23 | "version": "v1.1.0", 24 | "URL": "https://gitee.com/Neo-T/open-npstack.git", 25 | "filename": "v1.1.0.230726.zip", 26 | "VER_SHA": "v1.1.0.230726" 27 | }, 28 | { 29 | "version": "latest", 30 | "URL": "https://gitee.com/Neo-T/open-npstack.git", 31 | "filename": "v1.1.0.230726.zip", 32 | "VER_SHA": "master" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /port/include/port/datatype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.11 13:39 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 通用数据类型定义 12 | * 13 | */ 14 | #ifndef DATATYPE_H 15 | #define DATATYPE_H 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define PACKED __attribute__((packed)) 23 | #define PACKED_FIELD(x) PACKED x 24 | #define PACKED_BEGIN 25 | #define PACKED_END 26 | 27 | //* 系统常用数据类型定义(不同的编译器版本,各数据类型的位宽亦不同,请根据后面注释选择相同位宽的类型定义) 28 | typedef unsigned long long ULONGLONG; //* 64位无符号长整型 29 | typedef long long LONGLONG; //* 64位有符号长整型 30 | typedef signed long LONG; //* 32位的有符号长整型 31 | typedef unsigned long ULONG; //* 32位的无符号长整型 32 | typedef float FLOAT; //* 32位的浮点型 33 | typedef double DOUBLE; //* 64位的双精度浮点型 34 | typedef signed int INT; //* 32位的有符号整型 35 | typedef unsigned int UINT; //* 32位的无符号整型 36 | typedef signed short SHORT; //* 16位的有符号短整型 37 | typedef unsigned short USHORT; //* 16位的无符号短整型 38 | typedef char CHAR; //* 8位有符号字节型 39 | typedef unsigned char UCHAR; //* 8位无符号字节型 40 | typedef unsigned int in_addr_t; //* internet地址类型 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /port/include/port/os_adapter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.15 13:53 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 操作系统适配层,在此定义与目标操作系统相关的接口函数 12 | * 13 | */ 14 | #ifndef OS_ADAPTER_H 15 | #define OS_ADAPTER_H 16 | 17 | #ifdef SYMBOL_GLOBALS 18 | #define OS_ADAPTER_EXT 19 | #else 20 | #define OS_ADAPTER_EXT extern 21 | #endif //* SYMBOL_GLOBALS 22 | 23 | //* 一些协议栈要用到的与OS适配层相关的全局变量、函数、结构体定义 24 | //* ============================================================================================== 25 | typedef struct _STCB_PSTACKTHREAD_ { //* 协议栈内部工作线程控制块,其用于线程建立 26 | void(*pfunThread)(void *pvParam); 27 | void *pvParam; 28 | } STCB_PSTACKTHREAD, *PSTCB_PSTACKTHREAD; 29 | 30 | //* 解决多线程输出调试信息互相干扰的问题 31 | #if SUPPORT_PRINTF && PRINTF_THREAD_MUTEX 32 | extern HMUTEX o_hMtxPrintf; 33 | #endif 34 | //* ============================================================================================== 35 | 36 | //* 一些协议栈要用到的需要OS提供的支撑函数 37 | //* ============================================================================================== 38 | OS_ADAPTER_EXT void os_sleep_secs(UINT unSecs); //* 休眠,单位:秒 39 | OS_ADAPTER_EXT void os_sleep_ms(UINT unMSecs); //* 休眠,单位:毫秒 40 | OS_ADAPTER_EXT UINT os_get_system_secs(void); //* 获取系统启动以来已运行的秒数(从0开始) 41 | OS_ADAPTER_EXT UINT os_get_system_msecs(void); //* 获取系统启动以来已运行的毫秒数(从0开始) 42 | OS_ADAPTER_EXT HMUTEX os_thread_mutex_init(void); //* 线程同步锁初始化,成功返回同步锁句柄,失败则返回INVALID_HMUTEX 43 | OS_ADAPTER_EXT void os_thread_mutex_lock(HMUTEX hMutex); //* 线程同步区加锁 44 | OS_ADAPTER_EXT void os_thread_mutex_unlock(HMUTEX hMutex); //* 线程同步区解锁 45 | OS_ADAPTER_EXT void os_thread_mutex_uninit(HMUTEX hMutex); //* 删除线程同步锁,释放该资源 46 | OS_ADAPTER_EXT HSEM os_thread_sem_init(UINT unInitVal, UINT unCount); //* 信号量初始化,参数unInitVal指定初始信号量值, unCount指定信号量最大数值 47 | OS_ADAPTER_EXT void os_thread_sem_post(HSEM hSem); //* 投递信号量 48 | OS_ADAPTER_EXT INT os_thread_sem_pend(HSEM hSem, INT nWaitSecs); //* 等待信号量到达,参数nWaitSecs指定要等待的超时时间(单位为秒):0,一直等下去直至信号量到达,收到信号则返回值为0,出错则返回值为-1;其它,等待指定时间,如果指定时间内信号量到达,则返回值为0,超时则返回值为1,出错则返回值为-1 49 | OS_ADAPTER_EXT void os_thread_sem_uninit(HSEM hSem); //* 信号量去初始化,释放该资源 50 | OS_ADAPTER_EXT void os_thread_onpstack_start(void *pvParam); //* 启动协议栈内部工作线程 51 | 52 | #define os_critical_init() //* 临界区初始化 53 | #define os_enter_critical() //* 进入临界区(关中断) 54 | #define os_exit_critical() //* 退出临界区(开中断) 55 | 56 | #if SUPPORT_PPP 57 | OS_ADAPTER_EXT HTTY os_open_tty(const CHAR *pszTTYName); 58 | OS_ADAPTER_EXT void os_close_tty(HTTY hTTY); 59 | OS_ADAPTER_EXT INT os_tty_send(HTTY hTTY, UCHAR *pubData, INT nDataLen); 60 | OS_ADAPTER_EXT INT os_tty_recv(HTTY hTTY, UCHAR *pubRcvBuf, INT nRcvBufLen, INT nWaitSecs); 61 | OS_ADAPTER_EXT void os_modem_reset(HTTY hTTY); 62 | #endif 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /port/include/port/os_datatype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.14 15:56 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 与目标操作系统相关的通用数据类型定义 12 | * 13 | */ 14 | #ifndef OS_DATATYPE_H 15 | #define OS_DATATYPE_H 16 | 17 | typedef INT HMUTEX; //* 线程同步锁句柄 18 | #define INVALID_HMUTEX -1 //* 无效的线程同步锁句柄 19 | 20 | #if SUPPORT_PPP 21 | typedef INT HTTY; //* tty终端句柄 22 | #define INVALID_HTTY -1 //* 无效的tty终端句柄 23 | #endif 24 | 25 | typedef INT HSEM; //* 信号量,适用与不同线程间通讯 26 | #define INVALID_HSEM -1 //* 无效的信号量句柄 27 | 28 | #ifndef NULL 29 | #define NULL ((void *)0) 30 | #endif 31 | 32 | typedef unsigned int BOOL; //* bool型变量 33 | #ifndef TRUE 34 | #define TRUE 1 35 | #endif 36 | 37 | #ifndef FALSE 38 | #define FALSE 0 39 | #endif 40 | 41 | #ifndef s_addr //* Internet address 42 | struct in_addr 43 | { 44 | in_addr_t s_addr; 45 | }; 46 | #define s_addr s_addr 47 | #endif 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /port/include/port/sys_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T, Created in 2022.03.11 14:45 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | * 系统配置头文件,用户可根据实际情况对协议栈进行裁剪、参数配置等工作 12 | * 13 | */ 14 | #ifndef SYS_CONFIG_H 15 | #define SYS_CONFIG_H 16 | 17 | #define SOCKET_NUM_MAX 16 //* 系统支持的最大SOCKET数量,如实际应用中超过这个数量则会导致用户层业务逻辑无法全部正常运行(icmp/tcp/udp业务均受此影响),其值应大于等于TCP_LINK_NUM_MAX值 18 | #define IP_TTL_DEFAULT 64 //* 缺省TTL值 19 | 20 | //* 系统支持哪些功能模块由此配置 21 | //* =============================================================================================== 22 | #define SUPPORT_IPV6 1 //* 是否支持IPv6:1,支持;0,不支持 23 | #define SUPPORT_PRINTF 1 //* 是否支持调用printf()输出相关调试或系统信息 24 | #if SUPPORT_PRINTF 25 | #define PRINTF_THREAD_MUTEX 1 //* 是否支持使用printf线程互斥锁,确保不同线程的调试输出信息不被互相干扰,值为1则支持互斥锁 26 | #define DEBUG_LEVEL 4 //* 共5个调试级别: 27 | //* 0 输出协议栈底层严重错误 28 | //* 1 输出所有系统错误(包括0级错误) 29 | //* 2 输出协议栈重要的配置、运行信息,同时包括0、1级信息 30 | //* 3 输出网卡的原始通讯通讯报文(ppp为收发,ethnernet为发送),以及0、1、2级信息 31 | //* 4 输出ethernet网卡接收的原始通讯报文,被协议栈丢弃的非法(校验和错误、通讯链路不存在等原因)通讯报文,以及0、1、2、3级信息(除ethernet发送的原始报文) 32 | 33 | #endif 34 | 35 | #define SUPPORT_PPP 1 //* 是否支持ppp模块:1,支持;0,不支持,如果选择支持,则系统会将ppp模块代码加入到协议栈中 36 | #if SUPPORT_PPP 37 | #define APN_DEFAULT "4gnet" //* 根据实际情况在这里设置缺省APN 38 | #define AUTH_USER_DEFAULT "card" //* ppp认证缺省用户名 39 | #define AUTH_PASSWORD_DEFAULT "any_char" //* ppp认证缺省口令 40 | 41 | #define PPP_NETLINK_NUM 1 //* 协议栈加载几路ppp链路(系统存在几个modem这里就指定几就行) 42 | #define SUPPORT_ECHO 1 //* 对端是否支持echo链路探测 43 | #define WAIT_ACK_TIMEOUT_NUM 5 //* 在这里指定连续几次接收不到对端的应答报文就进入协议栈故障处理流程(STACKFAULT),这意味着当前链路已经因严重故障终止了 44 | #else 45 | #define PPP_NETLINK_NUM 0 46 | #endif 47 | 48 | #define SUPPORT_ETHERNET 1 //* 是否支持ethernet:1,支持;0,不支持 49 | #if SUPPORT_ETHERNET 50 | #define ETHERNET_NUM 1 //* 要添加几个ethernet网卡(实际存在几个就添加几个) 51 | #define ARPENTRY_NUM 32 //* arp条目缓存表的大小(不要超过127),只要不小于局域网内目标通讯节点的个数即可确保arp寻址次数为1,否则就会出现频繁寻址的可能,当然这也不会妨碍正常通讯逻辑,只不过这会降低通讯效率 52 | #if SUPPORT_IPV6 53 | #define IPV6TOMAC_ENTRY_NUM 8 //* Ipv6到以太网mac地址映射缓存表的大小(不要超过127),这个配置项指定缓存条目的数量,同样确保其不小于Ipv6通讯节点数量即可避免重复寻址的问题 54 | #define IPV6_CFG_ADDR_NUM 8 //* 指定所有以太网卡能够自动/手动配置的最大地址数量(不要超过128),超过这个数量将无法为网卡配置新的地址,如果目标网络环境地址数量确定建议将该值调整到合适的值以节省内存 55 | #define IPV6_ROUTER_NUM 4 //* 指定所有以太网卡能够添加的路由器最大数量(最多8个),请根据目标网络实际情况调整该值以最大限度节省内存使用 56 | #endif 57 | 58 | #define ETH_EXTRA_IP_EN 1 //* 是否允许添加多个ip地址 59 | #if ETH_EXTRA_IP_EN 60 | #define ETH_EXTRA_IP_NUM 2 //* 允许添加的ip地址数量 61 | #endif 62 | #else 63 | #define ETHERNET_NUM 0 64 | #endif 65 | 66 | #define NETIF_NUM (PPP_NETLINK_NUM + ETHERNET_NUM) //* 系统支持的网卡数量 67 | #define ROUTE_ITEM_NUM 8 //* Ipv4系统路由表数量 68 | //* =============================================================================================== 69 | 70 | //* ip支持的上层协议相关配置项 71 | //* =============================================================================================== 72 | #define SUPPORT_SACK 1 //* 系统是否支持sack项 73 | 74 | #define ICMPRCVBUF_SIZE 128 //* icmp发送echo请求报文时指定的接收缓冲区的大小,注意,如果要发送较大的ping包就必须指定较大的接收缓冲区 75 | 76 | #define TCPRCVBUF_SIZE 2048 //* tcp层接收缓冲区大小,大小应是2^n次幂才能最大限度不浪费budyy模块分配的内存 77 | #if SUPPORT_SACK 78 | #define TCPSNDBUF_SIZE 4096 //* 这样,如果设置值是一个算式,需要加上括号,tcp层发送缓冲区大小,同接收缓冲区,大小应是2^n次幂才能最大限度不浪费budyy模块分配的内存 79 | #endif 80 | 81 | #define TCPUDP_PORT_START 20000 //* TCP/UDP协议动态分配的起始端口号 82 | 83 | #define TCP_WINDOW_SCALE 0 //* 窗口扩大因子缺省值 84 | #define TCP_CONN_TIMEOUT 30 //* 缺省TCP连接超时时间 85 | #define TCP_ACK_TIMEOUT 3 //* 缺省TCP应答超时时间 86 | #define TCP_LINK_NUM_MAX 16 //* 系统支持最多建立多少路TCP链路(涵盖所有TCP客户端 + TCP服务器的并发连接数),超过这个数量将无法建立新的tcp链路,另外这个值最大为127,超过则系统无法正常运行 87 | #define TCP_ACK_DELAY_MSECS 100 //* 延迟多少毫秒发送ack报文,这个值最小40毫秒,最大200毫秒 88 | //#define TCP_ENABLE_JUMBO_FRAME 89 | #ifdef TCP_ENABLE_JUMBO_FRAME 90 | #define ONPS_TCP_MSS (8 * 1024) 91 | #else 92 | #define ONPS_TCP_MSS 1460 93 | #endif 94 | 95 | #if SUPPORT_ETHERNET 96 | #define TCPSRV_BACKLOG_NUM_MAX 10 //* tcp服务器支持的最大请求队列数量,任意时刻所有已开启的tcp服务器的请求连接队列数量之和应小于该值,否则将会出现拒绝连接的情况 97 | #define TCPSRV_NUM_MAX 0 //* 系统能够同时建立的tcp服务器数量 98 | #define TCPSRV_RECV_QUEUE_NUM 64 //* tcp服务器接收队列大小,所有已开启的tcp服务器共享该队列资源,如果单位时间内到达所有已开启tcp服务器的报文数量较大,应将该值调大 99 | #endif 100 | 101 | #define UDP_LINK_NUM_MAX 4 //* 调用connect()函数连接对端udp服务器的最大数量(一旦调用connect()函数,收到的非服务器报文将被直接丢弃) 102 | //* =============================================================================================== 103 | 104 | //* 网络工具配置项 105 | //* =============================================================================================== 106 | #define NETTOOLS_PING 1 //* 使能或禁止ping,置位使能,复位禁止,下同 107 | #define NETTOOLS_DNS_CLIENT 1 //* 使能或禁止dns查询客户端 108 | #define NETTOOLS_SNTP 1 //* 使能或禁止sntp客户端 109 | #define NETTOOLS_TELNETSRV 1 //* 使能或禁止telnet服务端,其值必须为0或1(禁止/使能),因为其还被用于tcp服务器资源分配统计(TCPSRV_NUM_MAX + NETTOOLS_TELNETSRV) 110 | 111 | #if NETTOOLS_TELNETSRV 112 | #define NVTCMD_MEMUSAGE_EN 1 //* 使能或禁止nvt命令:memusage 113 | #define NVTCMD_NETIF_EN 1 //* 使能或禁止nvt命令:netif 114 | #define NVTCMD_IFIP_EN 1 //* 使能或禁止nvt命令:ifip 115 | #define NVTCMD_ROUTE_EN 1 //* 使能或禁止nvt命令:route 116 | #define NVTCMD_TELNET_EN 1 //* 使能或禁止nvt命令:telnet 117 | 118 | #if NETTOOLS_SNTP 119 | #define NVTCMD_NTP_EN 1 //* 使能或禁止nvt命令:ntp,其必须先使能NETTOOLS_SNTP 120 | #endif //* #if NETTOOLS_SNTP 121 | 122 | #if NETTOOLS_DNS_CLIENT 123 | #define NVTCMD_NSLOOKUP_EN 1 //* 使能或禁止nvt命令:nslookup,其必须先使能NETTOOLS_DNS_CLIENT 124 | #endif //* #if NETTOOLS_DNS_CLIENT 125 | 126 | #if NETTOOLS_PING 127 | #define NVTCMD_PING_EN 1 //* 使能或禁止nvt命令:ping,使能ping命令时应同时使能NETTOOLS_PING 128 | #endif //* #if NETTOOLS_PING 129 | 130 | #define NVTCMD_RESET_EN 1 //* 使能或禁止nvt命令:reset 131 | 132 | #if NVTCMD_TELNET_EN 133 | //* telnet客户端接收缓冲区大小,注意关闭TCP SACK选项时,设置的接收缓冲区大小一旦超过过tcp mtu(一般 134 | //* 为1460字节),就必须在用户层限定单个发包的大小不能超过tcp mtu,否则会丢失数据 135 | #define TELNETCLT_RCVBUF_SIZE 1024 136 | #endif //* #if NVTCMD_TELNET_EN 137 | 138 | #define NVTNUM_MAX 2 //* 指定nvt并发工作的数量,其实就是指定telnet服务器在同一时刻并发连接的数量,超过这个数值服务器拒绝连接 139 | #define NVTCMDCACHE_EN 1 //* 是否支持命令缓存,也就是通过“↑↓”切换曾经输入的指令 140 | #define NVTCMDCACHE_SIZE 256 //* 指定指令缓存区的大小 141 | 142 | #if SUPPORT_IPV6 143 | #define TELNETSRV_SUPPORT_IPv6 1 //* telnet服务器使能或禁止ipv6支持,与NETTOOLS_TELNETSRV同,其值必须为0或1(禁止/使能) 144 | #endif //* #if SUPPORT_IPV6 145 | #endif //* #if NETTOOLS_TELNETSRV 146 | //* =============================================================================================== 147 | 148 | //* 内存管理单元(mmu)相关配置项,其直接影响协议栈能分配多少个socket给用户使用 149 | //* =============================================================================================== 150 | #define BUF_LIST_NUM 80 //* 缓存链表的节点数,最大不能超过2的15次方(32768) 151 | #define BUDDY_PAGE_SIZE 32 //* 系统能够分配的最小页面大小,其值必须是2的整数次幂 152 | #define BUDDY_ARER_COUNT 9 //* 指定buddy算法管理的内存块数组单元数量 153 | 154 | #define BUDDY_MEM_SIZE 8192 //* buddy算法管理的内存总大小,其值由BUDDY_PAGE_SIZE、BUDDY_ARER_COUNT两个宏计算得到: 155 | //* 32 * (2 ^ (9 - 1)),即BUDDY_MEM_SIZE = BUDDY_PAGE_SIZE * (2 ^ (BUDDY_ARER_COUNT - 1)) 156 | //* 之所以在此定义好要管理的内存大小,原因是buddy管理的内存其实就是一块提前分配好的静态存储 157 | //* 时期的字节型一维数组,以确保协议栈不占用宝贵的堆空间 158 | //* =============================================================================================== 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /port/include/telnet/nvt_cmd.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/port/include/telnet/nvt_cmd.h -------------------------------------------------------------------------------- /port/include/telnet/os_nvt.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/port/include/telnet/os_nvt.h -------------------------------------------------------------------------------- /port/os_adapter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "one_shot_timer.h" 17 | #include "onps_utils.h" 18 | #include "protocols.h" 19 | #include "onps_input.h" 20 | 21 | #if SUPPORT_PPP 22 | #include "ppp/negotiation_storage.h" 23 | #include "ppp/ppp.h" 24 | #endif 25 | 26 | #include "ip/tcp.h" 27 | 28 | #define SYMBOL_GLOBALS 29 | #include "port/os_adapter.h" 30 | #undef SYMBOL_GLOBALS 31 | 32 | #if SUPPORT_PPP 33 | //* 在此指定连接modem的串行口,以此作为tty终端进行ppp通讯,其存储索引应与os_open_tty()返回的tty句柄值一一对应 34 | const CHAR *or_pszaTTY[PPP_NETLINK_NUM] = { "SCP3" }; 35 | const ST_DIAL_AUTH_INFO or_staDialAuth[PPP_NETLINK_NUM] = { 36 | { "4gnet", "card", "any_char" }, /* 注意ppp账户和密码尽量控制在20个字节以内,太长需要需要修改chap.c中send_response()函数的szData数组容量及 */ 37 | /* pap.c中pap_send_auth_request()函数的ubaPacket数组的容量,确保其能够封装一个完整的响应报文 */ 38 | }; 39 | ST_PPPNEGORESULT o_staNegoResult[PPP_NETLINK_NUM] = { 40 | { 41 | { 0, PPP_MRU, ACCM_INIT,{ PPP_CHAP, 0x05 /* 对于CHAP协议来说,0-4未使用,0x05代表采用MD5算法 */ }, TRUE, TRUE, FALSE, FALSE }, 42 | { IP_ADDR_INIT, DNS_ADDR_INIT, DNS_ADDR_INIT, IP_ADDR_INIT, MASK_INIT }, 0 43 | }, 44 | 45 | /* 系统存在几路ppp链路,就在这里添加几路的协商初始值,如果不确定,可以直接将上面预定义的初始值直接复制过来即可 */ 46 | }; 47 | #endif 48 | 49 | #if SUPPORT_ETHERNET 50 | const CHAR *or_pszaEthName[ETHERNET_NUM] = { 51 | "eth0" 52 | }; 53 | #endif 54 | 55 | //* 协议栈内部工作线程列表 56 | const static STCB_PSTACKTHREAD lr_stcbaPStackThread[] = { 57 | { thread_one_shot_timer_count, NULL}, 58 | #if SUPPORT_PPP 59 | //* 在此按照顺序建立ppp工作线程,入口函数为thread_ppp_handler(),线程入口参数为os_open_tty()返回的tty句柄值 60 | //* 其直接强行进行数据类型转换即可,即作为线程入口参数时直接以如下形式传递: 61 | //* (void *)nPPPIdx 62 | //* 不要传递参数地址,即(void *)&nPPPIdx,这种方式是错误的 63 | #endif 64 | 65 | #if SUPPORT_SACK 66 | { thread_tcp_handler, NULL }, 67 | #endif 68 | }; 69 | 70 | /* 用户自定义变量声明区 */ 71 | /* …… */ 72 | 73 | //* 当前线程休眠指定的秒数,参数unSecs指定要休眠的秒数 74 | void os_sleep_secs(UINT unSecs) 75 | { 76 | #error os_sleep_secs() cannot be empty 77 | } 78 | 79 | //* 当前线程休眠指定的毫秒数,单位:毫秒 80 | void os_sleep_ms(UINT unMSecs) 81 | { 82 | #error os_sleep_ms() cannot be empty 83 | } 84 | 85 | //* 获取系统启动以来已运行的秒数(从0开始) 86 | UINT os_get_system_secs(void) 87 | { 88 | #error os_get_system_secs() cannot be empty 89 | 90 | return 0; 91 | } 92 | 93 | //* 获取系统启动以来已运行的毫秒数(从0开始) 94 | UINT os_get_system_msecs(void) 95 | { 96 | #error os_get_system_msecs() cannot be empty 97 | 98 | return 0; 99 | } 100 | 101 | void os_thread_onpstack_start(void *pvParam) 102 | { 103 | #error os_thread_onpstack_start() cannot be empty 104 | 105 | //* 建立工作线程 106 | INT i; 107 | for (i = 0; i < sizeof(lr_stcbaPStackThread) / sizeof(STCB_PSTACKTHREAD); i++) 108 | { 109 | //* 在此按照顺序建立工作线程 110 | } 111 | 112 | /* 用户自定义代码 */ 113 | /* …… */ 114 | } 115 | 116 | HMUTEX os_thread_mutex_init(void) 117 | { 118 | #error os_thread_mutex_init() cannot be empty 119 | 120 | return INVALID_HMUTEX; //* 初始失败要返回一个无效句柄 121 | } 122 | 123 | void os_thread_mutex_lock(HMUTEX hMutex) 124 | { 125 | #error os_thread_mutex_lock() cannot be empty 126 | } 127 | 128 | void os_thread_mutex_unlock(HMUTEX hMutex) 129 | { 130 | #error os_thread_mutex_unlock() cannot be empty 131 | } 132 | 133 | void os_thread_mutex_uninit(HMUTEX hMutex) 134 | { 135 | #error os_thread_mutex_uninit() cannot be empty 136 | } 137 | 138 | HSEM os_thread_sem_init(UINT unInitVal, UINT unCount) 139 | { 140 | #error os_thread_sem_init() cannot be empty 141 | 142 | return INVALID_HSEM; //* 初始失败要返回一个无效句柄 143 | } 144 | 145 | void os_thread_sem_post(HSEM hSem) 146 | { 147 | #error os_thread_sem_post() cannot be empty 148 | } 149 | 150 | INT os_thread_sem_pend(HSEM hSem, INT nWaitSecs) 151 | { 152 | #error os_thread_sem_pend() cannot be empty 153 | 154 | return -1; 155 | } 156 | 157 | void os_thread_sem_uninit(HSEM hSem) 158 | { 159 | #error os_thread_sem_uninit() cannot be empty 160 | } 161 | 162 | #if SUPPORT_PPP 163 | HTTY os_open_tty(const CHAR *pszTTYName) 164 | { 165 | #error os_open_tty() cannot be empty 166 | 167 | return INVALID_HTTY; 168 | } 169 | 170 | void os_close_tty(HTTY hTTY) 171 | { 172 | #error os_close_tty() cannot be empty 173 | } 174 | 175 | INT os_tty_send(HTTY hTTY, UCHAR *pubData, INT nDataLen) 176 | { 177 | #error os_tty_send() cannot be empty 178 | 179 | return 0; 180 | } 181 | 182 | INT os_tty_recv(HTTY hTTY, UCHAR *pubRcvBuf, INT nRcvBufLen, INT nWaitSecs) 183 | { 184 | #error os_tty_recv() cannot be empty 185 | 186 | return 0; 187 | } 188 | 189 | void os_modem_reset(HTTY hTTY) 190 | { 191 | /* 用户自定义代码,不需要复位modem设备则这里可以不进行任何操作 */ 192 | /* …… */ 193 | } 194 | #endif 195 | 196 | -------------------------------------------------------------------------------- /port/telnet/nvt_cmd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "port/os_adapter.h" 17 | #include "mmu/buddy.h" 18 | #include "onps_utils.h" 19 | #include "onps_input.h" 20 | #include "netif/netif.h" 21 | #include "netif/route.h" 22 | 23 | #if NETTOOLS_TELNETSRV 24 | #include "net_tools/net_virtual_terminal.h" 25 | #if NVTCMD_TELNET_EN 26 | #include "net_tools/telnet_client.h" 27 | #endif //* #if NVTCMD_TELNET_EN 28 | #include "net_tools/telnet.h" 29 | #define SYMBOL_GLOBALS 30 | #include "telnet/nvt_cmd.h" 31 | #undef SYMBOL_GLOBALS 32 | 33 | //* 在这里定义你自己要添加的nvt指令 34 | //* =================================================================================== 35 | #if NVTCMD_TELNET_EN 36 | static INT telnet(CHAR argc, CHAR* argv[], ULONGLONG ullNvtHandle); 37 | #endif //* #if NVTCMD_TELNET_EN 38 | 39 | #if NETTOOLS_PING && NVTCMD_PING_EN 40 | #include "net_tools/ping.h" 41 | static INT nvt_cmd_ping(CHAR argc, CHAR* argv[], ULONGLONG ullNvtHandle); 42 | #endif //* #if NETTOOLS_PING && NVTCMD_PING_EN 43 | 44 | #if NVTCMD_RESET_EN 45 | static INT reset(CHAR argc, CHAR* argv[], ULONGLONG ullNvtHandle); 46 | #endif //* #if NVTCMD_RESET_EN 47 | 48 | //* NVT自定义命令数组 49 | static const ST_NVTCMD l_staNvtCmd[] = { 50 | #if NVTCMD_TELNET_EN 51 | { telnet, "telnet", "used to log in to remote telnet host.\r\n" }, 52 | #endif //* #if NVTCMD_TELNET_EN 53 | 54 | #if NETTOOLS_PING && NVTCMD_PING_EN 55 | { nvt_cmd_ping, "ping", "A lightweight ping testing tool that supports IPv4 and IPv6 address probing.\r\n" }, 56 | #endif //* #if NETTOOLS_PING && NVTCMD_PING_EN 57 | 58 | #if NVTCMD_RESET_EN 59 | { reset, "reset", "system reset.\r\n" }, 60 | #endif //* #if NVTCMD_RESET_EN 61 | 62 | { NULL, "", "" } //* 注意这个不要删除,当所有nvt命令被用户禁止时其被用于避免编译器报错 63 | }; 64 | 65 | static ST_NVTCMD_NODE l_staNvtCmdNode[sizeof(l_staNvtCmd) / sizeof(ST_NVTCMD)]; 66 | //* =================================================================================== 67 | 68 | void nvt_cmd_register(void) 69 | { 70 | UCHAR i; 71 | for (i = 0; i < sizeof(l_staNvtCmd) / sizeof(ST_NVTCMD); i++) 72 | { 73 | if(l_staNvtCmd[i].pfun_cmd_entry) 74 | nvt_cmd_add(&l_staNvtCmdNode[i], &l_staNvtCmd[i]); 75 | } 76 | } 77 | 78 | //* 杀死当前正在执行的指令,该函数用于以线程/任务方式启动的指令,当用户退出登录或者长时间没有任何操作,需要主动结束nvt结束运行时, 79 | //* 此时如果存在正在执行的指令,nvt会先主动通知其结束运行,如果规定时间内其依然未结束运行,nvt会调用这个函数强制其结束运行释放占 80 | //* 用的线程/任务资源 81 | void nvt_cmd_kill(void) 82 | { 83 | 84 | } 85 | 86 | //* 以线程方式运行地命令在线程结束时应显式地告知其已结束运行,因为协议栈运行的目标系统属于资源受限系统,凡是以线程运行的nvt命令在 87 | //* 同一时刻只允许运行一个实例,这个函数确保nvt能够安全运行下一个线程实例 88 | void nvt_cmd_thread_end(void) 89 | { 90 | 91 | } 92 | 93 | #if NVTCMD_TELNET_EN 94 | #define NVTHELP_TELNET_USAGE "Please enter the telnet server address, usage as follows:\r\n \033[01;37mtelnet xxx.xxx.xxx.xxx [port]\033[0m\r\n" 95 | #define NVTHELP_TELNET_LOGIN_LOCAL "Due to resource constraints, the telnet command is prohibited from logging in to its own server.\r\n" 96 | static INT telnet(CHAR argc, CHAR* argv[], ULONGLONG ullNvtHandle) 97 | { 98 | ST_TELCLT_STARTARGS stArgs; 99 | 100 | if (argc != 2 && argc != 3) 101 | { 102 | nvt_output(ullNvtHandle, NVTHELP_TELNET_USAGE, sizeof(NVTHELP_TELNET_USAGE) - 1); 103 | nvt_cmd_exec_end(ullNvtHandle); 104 | return -1; 105 | } 106 | 107 | if (is_local_ip(inet_addr(argv[1]))) 108 | { 109 | nvt_output(ullNvtHandle, NVTHELP_TELNET_LOGIN_LOCAL, sizeof(NVTHELP_TELNET_LOGIN_LOCAL) - 1); 110 | nvt_cmd_exec_end(ullNvtHandle); 111 | return -1; 112 | } 113 | 114 | stArgs.bIsCpyEnd = FALSE; 115 | stArgs.ullNvtHandle = ullNvtHandle; 116 | stArgs.stSrvAddr.saddr_ipv4 = inet_addr(argv[1]); 117 | if (argc == 3) 118 | stArgs.stSrvAddr.usPort = atoi(argv[2]); 119 | else 120 | stArgs.stSrvAddr.usPort = 23; 121 | 122 | 123 | /* 在这里添加线程/任务启动telnet客户端的代码 124 | 线程/任务入口函数为telnet_clt_entry() 125 | */ 126 | 127 | while (!stArgs.bIsCpyEnd) 128 | os_sleep_ms(10); 129 | 130 | return 0; 131 | } 132 | #endif //* #if NVTCMD_TELNET_EN 133 | 134 | #if NVTCMD_RESET_EN 135 | static INT reset(CHAR argc, CHAR* argv[], ULONGLONG ullNvtHandle) 136 | { 137 | nvt_output(ullNvtHandle, "The system will be reset ...", sizeof("The system will be reset ...") - 1); 138 | os_sleep_secs(3); 139 | nvt_close(ullNvtHandle); 140 | 141 | //* 在这里添加目标系统的复位指令 142 | 143 | return 0; 144 | } 145 | #endif //* #if NVTCMD_RESET_EN 146 | 147 | #if NETTOOLS_PING && NVTCMD_PING_EN 148 | #if SUPPORT_IPV6 149 | #define NVTHELP_PING_USAGE "Usage as follows:\r\n \033[01;37mping [4] xxx.xxx.xxx.xxx\033[0m\r\n \033[01;37mping 6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx\033[0m\r\n" 150 | #else //* #if SUPPORT_IPV6 151 | #define NVTHELP_PING_USAGE "Usage as follows:\r\n \033[01;37mping xxx.xxx.xxx.xxx\033[0m\r\n" 152 | #endif //* #if SUPPORT_IPV6 153 | static INT nvt_cmd_ping(CHAR argc, CHAR* argv[], ULONGLONG ullNvtHandle) 154 | { 155 | ST_PING_STARTARGS stArgs; 156 | #if SUPPORT_IPV6 157 | if (argc != 2 && argc != 3) 158 | #else 159 | if (argc != 2) 160 | #endif 161 | goto __lblHelp; 162 | else 163 | { 164 | #if SUPPORT_IPV6 165 | if (argc == 3) 166 | { 167 | if (strlen(argv[1]) == 1) 168 | { 169 | if ('4' == argv[1][0]) 170 | stArgs.nFamily = AF_INET; 171 | else if('6' == argv[1][0]) 172 | stArgs.nFamily = AF_INET6; 173 | else 174 | goto __lblHelp; 175 | 176 | snprintf(stArgs.szDstIp, sizeof(stArgs.szDstIp), "%s", argv[2]); 177 | if (AF_INET == stArgs.nFamily) 178 | { 179 | if (!is_valid_ip(stArgs.szDstIp)) 180 | goto __lblHelp; 181 | } 182 | } 183 | else 184 | goto __lblHelp; 185 | } 186 | else 187 | { 188 | stArgs.nFamily = AF_INET; 189 | snprintf(stArgs.szDstIp, sizeof(stArgs.szDstIp), "%s", argv[1]); 190 | if (!is_valid_ip(stArgs.szDstIp)) 191 | goto __lblHelp; 192 | } 193 | #else 194 | stArgs.nFamily = AF_INET; 195 | snprintf(stArgs.szDstIp, sizeof(stArgs.szDstIp), "%s", argv[1]); 196 | if (!is_valid_ip(stArgs.szDstIp)) 197 | goto __lblHelp; 198 | #endif 199 | } 200 | 201 | stArgs.bIsCpyEnd = FALSE; 202 | stArgs.ullNvtHandle = ullNvtHandle; 203 | 204 | /* 在这里添加线程/任务启动ping探测代码 205 | 线程/任务入口函数为nvt_cmd_ping_entry() 206 | */ 207 | 208 | while (!stArgs.bIsCpyEnd) 209 | os_sleep_ms(10); 210 | 211 | return 0; 212 | 213 | __lblHelp: 214 | nvt_output(ullNvtHandle, NVTHELP_PING_USAGE, sizeof(NVTHELP_PING_USAGE) - 1); 215 | nvt_cmd_exec_end(ullNvtHandle); 216 | return -1; 217 | } 218 | #endif //* #if NETTOOLS_PING && NVTCMD_PING_EN 219 | #endif //* #if NETTOOLS_TELNETSRV 220 | -------------------------------------------------------------------------------- /port/telnet/os_nvt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "one_shot_timer.h" 17 | #include "onps_utils.h" 18 | #include "protocols.h" 19 | #include "onps_input.h" 20 | 21 | #if NETTOOLS_TELNETSRV 22 | #define SYMBOL_GLOBALS 23 | #include "telnet/os_nvt.h" 24 | #undef SYMBOL_GLOBALS 25 | 26 | void os_nvt_init(void) 27 | { 28 | } 29 | 30 | void os_nvt_uninit(void) 31 | { 32 | } 33 | 34 | BOOL os_nvt_start(void *pvParam) 35 | { 36 | 37 | } 38 | 39 | void os_nvt_stop(void *pvParam, BOOL blIsNvtEnd) 40 | { 41 | 42 | } 43 | 44 | #if SUPPORT_ETHERNET && NVTCMD_IFIP_EN 45 | #if ETH_EXTRA_IP_EN 46 | BOOL os_nvt_add_ip(const CHAR *pszIfName, in_addr_t unIp, in_addr_t unSubnetMask) 47 | { 48 | return TRUE; 49 | } 50 | 51 | BOOL os_nvt_del_ip(const CHAR *pszIfName, in_addr_t unIp) 52 | { 53 | return TRUE; 54 | } 55 | #endif //* #if ETH_EXTRA_IP_EN 56 | BOOL os_nvt_set_ip(const CHAR *pszIfName, in_addr_t unIp, in_addr_t unSubnetMask, in_addr_t unGateway) 57 | { 58 | return TRUE; 59 | } 60 | 61 | BOOL os_nvt_set_mac(const CHAR *pszIfName, const CHAR *pszMac) 62 | { 63 | return TRUE; 64 | } 65 | 66 | BOOL os_nvt_set_dns(const CHAR *pszIfName, in_addr_t unPrimaryDns, in_addr_t unSecondaryDns) 67 | { 68 | return TRUE; 69 | } 70 | 71 | BOOL os_nvt_set_dhcp(const CHAR *pszIfName) 72 | { 73 | return TRUE; 74 | } 75 | 76 | void os_nvt_system_reset(void) 77 | { 78 | 79 | } 80 | #endif //* #if SUPPORT_ETHERNET && NVTCMD_IFIP_EN 81 | 82 | #if NVTCMD_ROUTE_EN 83 | BOOL os_nvt_add_route_entry(const CHAR *pszIfName, in_addr_t unDestination, in_addr_t unGenmask, in_addr_t unGateway) 84 | { 85 | return TRUE; 86 | } 87 | 88 | BOOL os_nvt_del_route_entry(in_addr_t unDestination) 89 | { 90 | return TRUE; 91 | } 92 | #endif //* #if NVTCMD_ROUTE_EN 93 | 94 | #if NETTOOLS_PING && NVTCMD_PING_EN 95 | UINT os_get_elapsed_millisecs(void) 96 | { 97 | return 0; 98 | } 99 | #endif //* #if NETTOOLS_PING && NVTCMD_PING_EN 100 | 101 | #if NETTOOLS_SNTP && NVTCMD_NTP_EN 102 | void os_nvt_set_system_time(time_t tNtpTime) 103 | { 104 | 105 | } 106 | #endif //* #if NETTOOLS_SNTP && NVTCMD_NTP_EN 107 | 108 | #endif //* #if NETTOOLS_TELNETSRV 109 | -------------------------------------------------------------------------------- /ppp/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | compile_flags.txt 4 | 5 | # Object files 6 | *.o 7 | *.ko 8 | *.obj 9 | *.elf 10 | 11 | # Linker output 12 | *.ilk 13 | *.map 14 | *.exp 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | 26 | # Shared objects (inc. Windows DLLs) 27 | *.dll 28 | *.so 29 | *.so.* 30 | *.dylib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app 36 | *.i*86 37 | *.x86_64 38 | *.hex 39 | 40 | # Debug files 41 | *.dSYM/ 42 | *.su 43 | *.idb 44 | *.pdb 45 | 46 | # Kernel Module Compile Results 47 | *.mod* 48 | *.cmd 49 | .tmp_versions/ 50 | modules.order 51 | Module.symvers 52 | Mkfile.old 53 | dkms.conf 54 | .codelite/ 55 | ppp.project 56 | -------------------------------------------------------------------------------- /ppp/chap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "port/os_datatype.h" 15 | #include "port/os_adapter.h" 16 | #include "onps_errors.h" 17 | #include "onps_utils.h" 18 | #include "onps_md5.h" 19 | #include "mmu/buf_list.h" 20 | 21 | #if SUPPORT_PPP 22 | #include "ppp/negotiation.h" 23 | #define SYMBOL_GLOBALS 24 | #include "ppp/chap.h" 25 | #undef SYMBOL_GLOBALS 26 | #include "ppp/ppp.h" 27 | 28 | static void send_response(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen) 29 | { 30 | CHAR szData[64]; 31 | PST_CHAP_DATA pstData = (PST_CHAP_DATA)(pubPacket + sizeof(ST_LNCP_HDR)); 32 | PST_LNCP_HDR pstHdr = (PST_LNCP_HDR)pubPacket; 33 | 34 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 35 | snprintf_hex(pstData->ubaChallenge, (USHORT)pstData->ubChallengeLen, szData, sizeof(szData) - 1, FALSE); 36 | printf(", Challenge = <%s>", szData); 37 | UINT unCpyBytes = nPacketLen - sizeof(ST_LNCP_HDR) - sizeof(ST_CHAP_DATA); 38 | unCpyBytes = unCpyBytes < sizeof(szData) - 1 ? unCpyBytes : sizeof(szData) - 1; 39 | memcpy(szData, pubPacket + sizeof(ST_LNCP_HDR) + sizeof(ST_CHAP_DATA), unCpyBytes); 40 | szData[unCpyBytes] = 0; 41 | printf(", name = \"%s\"]\r\n", szData); 42 | #endif 43 | 44 | const CHAR *pszUser, *pszPassword; 45 | get_ppp_auth_info(pstcbPPP->hTTY, &pszUser, &pszPassword); 46 | 47 | //* 使用MD5算法生成Challenge值:ubIdentifier + 拨号脚本设置的密码 + 对端下发的Challenge值 48 | UINT unOriginalLen, unPasswordLen = strlen(pszPassword); 49 | szData[0] = pstHdr->ubIdentifier; 50 | unOriginalLen = 1; 51 | memcpy(&szData[1], pszPassword, unPasswordLen); 52 | unOriginalLen += unPasswordLen; 53 | memcpy(&szData[unOriginalLen], pstData->ubaChallenge, pstData->ubChallengeLen); 54 | unOriginalLen += (UINT)pstData->ubChallengeLen; 55 | ST_MD5VAL stChallengeCode = onps_md5((UCHAR *)szData, unOriginalLen); 56 | 57 | //* 封装报文 58 | USHORT usDataLen; 59 | UINT unUserLen = strlen(pszUser); 60 | PST_CHAP_DATA pstRespData = (PST_CHAP_DATA)&szData[sizeof(ST_LNCP_HDR)]; 61 | usDataLen = sizeof(ST_LNCP_HDR); 62 | pstRespData->ubChallengeLen = CHAP_CHALLENGE_LEN; 63 | memcpy(pstRespData->ubaChallenge, (UCHAR *)&stChallengeCode, sizeof(stChallengeCode)); 64 | usDataLen += sizeof(ST_CHAP_DATA); 65 | memcpy(&szData[sizeof(ST_LNCP_HDR) + sizeof(ST_CHAP_DATA)], pszUser, unUserLen); 66 | usDataLen += unUserLen; 67 | 68 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 69 | CHAR szChallenge[CHAP_CHALLENGE_LEN * 2 + 1]; 70 | snprintf_hex(pstRespData->ubaChallenge, CHAP_CHALLENGE_LEN, szChallenge, sizeof(szChallenge) - 1, FALSE); 71 | printf("sent [Protocol CHAP, Id = %02X, Code = 'Response', Challenge = <%s>, name = \"%s\"]\r\n", pstHdr->ubIdentifier, szChallenge, pszUser); 72 | #endif 73 | 74 | //* 发送响应报文 75 | send_nego_packet(pstcbPPP, CHAP, (UCHAR)RESPONSE, pstHdr->ubIdentifier, (UCHAR *)szData, (USHORT)usDataLen, TRUE, NULL); 76 | } 77 | 78 | //* chap协议接收函数 79 | void chap_recv(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen) 80 | { 81 | PST_LNCP_HDR pstHdr = (PST_LNCP_HDR)pubPacket; 82 | 83 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 84 | printf("recv [Protocol CHAP, Id = %02X, Code = '%s'", pstHdr->ubIdentifier, get_chap_code_name((EN_CHAPCODE)pstHdr->ubCode)); 85 | #endif 86 | 87 | switch ((EN_CHAPCODE)pstHdr->ubCode) 88 | { 89 | case CHALLENGE: 90 | pstcbPPP->pstNegoResult->unLastRcvedSecs = os_get_system_secs(); //* 收到challenge报文,更新接收时间,避免协商状态机报错 91 | send_response(pstcbPPP, pubPacket, nPacketLen); 92 | break; 93 | 94 | case SUCCEEDED: 95 | //* 收到应答则清除等待队列节点 96 | wait_ack_list_del(&pstcbPPP->stWaitAckList, CHAP, pstHdr->ubIdentifier); 97 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 98 | printf("]\r\nCHAP authentication succeeded. \r\n"); 99 | #endif 100 | pstcbPPP->enState = SENDIPCPCONFREQ; 101 | break; 102 | 103 | case FAILURE: 104 | //* 收到应答则清除等待队列节点 105 | wait_ack_list_del(&pstcbPPP->stWaitAckList, CHAP, pstHdr->ubIdentifier); 106 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 107 | printf("]\r\nCHAP authentication failed.\r\n"); 108 | #endif 109 | pstcbPPP->enState = AUTHENFAILED; 110 | break; 111 | 112 | case RESPONSE: 113 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 114 | printf("]\r\nCHAP authentication failed, unsupported response type.\r\n"); 115 | #endif 116 | pstcbPPP->enState = AUTHENFAILED; 117 | break; 118 | } 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /ppp/negotiation.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "port/os_datatype.h" 15 | #include "port/os_adapter.h" 16 | #include "onps_errors.h" 17 | #include "mmu/buf_list.h" 18 | #include "onps_utils.h" 19 | 20 | #if SUPPORT_PPP 21 | #define SYMBOL_GLOBALS 22 | #include "ppp/negotiation.h" 23 | #undef SYMBOL_GLOBALS 24 | #include "ppp/lcp.h" 25 | #include "ppp/pap.h" 26 | #include "ppp/ipcp.h" 27 | #include "ppp/ppp.h" 28 | 29 | BOOL send_nego_packet(PSTCB_PPP pstcbPPP, USHORT usProtocol, UCHAR ubCode, UCHAR ubIdentifier, UCHAR *pubData, USHORT usDataLen, BOOL blIsWaitACK, EN_ONPSERR *penErr) 30 | { 31 | PST_LNCP_HDR pstHdr = (PST_LNCP_HDR)pubData; 32 | pstHdr->ubCode = ubCode; 33 | pstHdr->ubIdentifier = ubIdentifier; 34 | pstHdr->usLen = ENDIAN_CONVERTER_USHORT(usDataLen); 35 | 36 | //* 申请一个buf list节点 37 | SHORT sBufListHead = -1; 38 | SHORT sNode = buf_list_get_ext(pubData, usDataLen, penErr); 39 | if (sNode < 0) 40 | return FALSE; 41 | buf_list_put_head(&sBufListHead, sNode); 42 | 43 | //* 发送 44 | INT nRtnVal = ppp_send(pstcbPPP->hTTY, (EN_NPSPROTOCOL)usProtocol, sBufListHead, penErr); 45 | 46 | //* 释放刚才申请的buf list节点 47 | buf_list_free(sNode); 48 | 49 | //* 大于0意味着发送成功 50 | if (nRtnVal > 0) 51 | { 52 | //* 需要等待应答则将其加入等待队列 53 | if (blIsWaitACK) 54 | { 55 | pstcbPPP->stWaitAckList.ubIsTimeout = FALSE; 56 | return wait_ack_list_add(&pstcbPPP->stWaitAckList, usProtocol, ubCode, ubIdentifier, 6, penErr); 57 | } 58 | 59 | return TRUE; 60 | } 61 | 62 | return FALSE; 63 | } 64 | 65 | static void ppp_negotiate(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr) 66 | { 67 | switch (pstcbPPP->enState) 68 | { 69 | case LCPCONFREQ: 70 | if (pstcbPPP->stWaitAckList.ubIsTimeout) //* 意味着没收到应答报文 71 | { 72 | if (!lcp_send_conf_request(pstcbPPP, penErr)) //* 再发送一次lcp配置请求报文 73 | { 74 | #if SUPPORT_PRINTF && DEBUG_LEVEL 75 | printf("lcp_send_conf_request() failed, %s\r\n", onps_error(*penErr)); 76 | #endif 77 | 78 | pstcbPPP->enState = STACKFAULT; 79 | } 80 | } 81 | break; 82 | 83 | case STARTAUTHEN: 84 | if (pstcbPPP->pstNegoResult->stLCP.stAuth.usType == PPP_CHAP) 85 | { 86 | //* CHAP协议会在收到LCP协商通过的应答报文后,主动下发认证报文,在这里记录下开始时间,以避免ppp栈一直等待下去(如果链路已经异常断开的话) 87 | pstcbPPP->pstNegoResult->unLastRcvedSecs = os_get_system_secs(); 88 | pstcbPPP->enState = AUTHENTICATE; 89 | } 90 | else if (pstcbPPP->pstNegoResult->stLCP.stAuth.usType == PPP_PAP) 91 | { 92 | //* 发送认证报文 93 | if (pap_send_auth_request(pstcbPPP, penErr)) 94 | { 95 | pstcbPPP->enState = AUTHENTICATE; 96 | } 97 | else 98 | { 99 | #if SUPPORT_PRINTF && DEBUG_LEVEL 100 | printf("pap_send_auth_request() failed, %s\r\n", onps_error(*penErr)); 101 | #endif 102 | 103 | pstcbPPP->enState = STACKFAULT; 104 | } 105 | } 106 | else 107 | { 108 | #if SUPPORT_PRINTF && DEBUG_LEVEL 109 | printf("error: unrecognized authentication protocol\r\n"); 110 | #endif 111 | pstcbPPP->enState = STACKFAULT; 112 | } 113 | 114 | break; 115 | 116 | case AUTHENTICATE: 117 | if (pstcbPPP->pstNegoResult->stLCP.stAuth.usType == PPP_CHAP) 118 | { 119 | if (os_get_system_secs() - pstcbPPP->pstNegoResult->unLastRcvedSecs > 30) //* 如果超过30秒还未收到对端发送的认证报文那么在这里就认为链路已经异常断开了,需要重新建立链路了,此时我们只需把状态迁移到AUTHENTIMEOUT就可了 120 | pstcbPPP->enState = AUTHENTIMEOUT; 121 | } 122 | else 123 | { 124 | if (pstcbPPP->stWaitAckList.ubIsTimeout) //* 意味着没收到应答报文,需要回到STARTAUTHEN阶段再发送一次认证报文 125 | pstcbPPP->enState = STARTAUTHEN; 126 | } 127 | 128 | break; 129 | 130 | case SENDIPCPCONFREQ: 131 | if (ipcp_send_conf_request(pstcbPPP, penErr)) 132 | { 133 | pstcbPPP->enState = WAITIPCPCONFACK; 134 | } 135 | else 136 | { 137 | #if SUPPORT_PRINTF && DEBUG_LEVEL 138 | printf("ipcp_send_conf_request() failed, %s\r\n", onps_error(*penErr)); 139 | #endif 140 | pstcbPPP->enState = STACKFAULT; 141 | } 142 | break; 143 | 144 | case WAITIPCPCONFACK: 145 | if (pstcbPPP->stWaitAckList.ubIsTimeout) //* 意味着没收到应答报文 146 | pstcbPPP->enState = SENDIPCPCONFREQ; 147 | } 148 | } 149 | 150 | void ppp_link_establish(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr) 151 | { 152 | switch (pstcbPPP->enState) 153 | { 154 | case STARTNEGOTIATION: 155 | if (lcp_start_negotiation(pstcbPPP, penErr)) 156 | pstcbPPP->enState = NEGOTIATION; 157 | else 158 | { 159 | pstcbPPP->enState = STACKFAULT; 160 | return; 161 | } 162 | 163 | default: 164 | ppp_negotiate(pstcbPPP, penErr); 165 | return; 166 | } 167 | } 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /ppp/pap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "port/os_datatype.h" 15 | #include "port/os_adapter.h" 16 | #include "onps_errors.h" 17 | #include "mmu/buf_list.h" 18 | #include "onps_utils.h" 19 | #include "onps_md5.h" 20 | 21 | #if SUPPORT_PPP 22 | #include "ppp/negotiation.h" 23 | #define SYMBOL_GLOBALS 24 | #include "ppp/pap.h" 25 | #undef SYMBOL_GLOBALS 26 | #include "ppp/ppp.h" 27 | 28 | BOOL pap_send_auth_request(PSTCB_PPP pstcbPPP, EN_ONPSERR *penErr) 29 | { 30 | UCHAR ubaPacket[64]; 31 | UCHAR ubIdentifier = pstcbPPP->pstNegoResult->ubIdentifier++; 32 | 33 | const CHAR *pszUser, *pszPassword; 34 | get_ppp_auth_info(pstcbPPP->hTTY, &pszUser, &pszPassword); 35 | 36 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 37 | printf("sent [Protocol PAP, Id = %02X, Code = '%s', User = '%s']\r\n", ubIdentifier, get_pap_code_name(AUTHREQ), pszUser); 38 | #endif 39 | USHORT usUserLen = strlen(pszUser), usPasswordLen = strlen(pszPassword); 40 | USHORT usDataLen = sizeof(ST_LNCP_HDR); 41 | ubaPacket[usDataLen] = (UCHAR)usUserLen; 42 | usDataLen += 1; 43 | memcpy(&ubaPacket[usDataLen], pszUser, usUserLen); 44 | usDataLen += usUserLen; 45 | ubaPacket[usDataLen] = (UCHAR)usPasswordLen; 46 | usDataLen += 1; 47 | memcpy(&ubaPacket[usDataLen], pszPassword, usPasswordLen); 48 | usDataLen += usPasswordLen; 49 | 50 | return send_nego_packet(pstcbPPP, PAP, (UCHAR)AUTHREQ, ubIdentifier, ubaPacket, (USHORT)usDataLen, TRUE, penErr); 51 | } 52 | 53 | static void get_message(UCHAR *pubPacket, INT nPacketLen, CHAR *pszMessageBuf, UCHAR ubMessageBufLen) 54 | { 55 | UCHAR ubMessageLen = pubPacket[sizeof(ST_LNCP_HDR)]; 56 | UINT unCpyBytes = ubMessageLen < ubMessageBufLen - 1 ? (UINT)ubMessageLen : (UINT)ubMessageBufLen - 1; 57 | memcpy(pszMessageBuf, pubPacket + sizeof(ST_LNCP_HDR) + 1, unCpyBytes); 58 | pszMessageBuf[unCpyBytes] = 0; 59 | } 60 | 61 | //* pap协议接收函数 62 | void pap_recv(PSTCB_PPP pstcbPPP, UCHAR *pubPacket, INT nPacketLen) 63 | { 64 | PST_LNCP_HDR pstHdr = (PST_LNCP_HDR)pubPacket; 65 | 66 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 67 | CHAR szMessage[32]; 68 | #endif 69 | 70 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 71 | printf("recv [Protocol PAP, Id = %02X, Code = '%s'", pstHdr->ubIdentifier, get_pap_code_name((EN_PAPCODE)pstHdr->ubCode)); 72 | #endif 73 | 74 | switch ((EN_PAPCODE)pstHdr->ubCode) 75 | { 76 | case AUTHPASSED: 77 | //* 收到应答则清除等待队列节点 78 | wait_ack_list_del(&pstcbPPP->stWaitAckList, PAP, pstHdr->ubIdentifier); 79 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 80 | get_message(pubPacket, nPacketLen, szMessage, sizeof(szMessage)); 81 | printf(", Message = \"%s\"]\r\nPAP authentication succeeded. \r\n", szMessage); 82 | #endif 83 | pstcbPPP->enState = SENDIPCPCONFREQ; 84 | break; 85 | 86 | case AUTHREFUSED: 87 | //* 收到应答则清除等待队列节点 88 | wait_ack_list_del(&pstcbPPP->stWaitAckList, PAP, pstHdr->ubIdentifier); 89 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 90 | get_message(pubPacket, nPacketLen, szMessage, sizeof(szMessage)); 91 | printf(", Message = \"%s\"]\r\nPAP authentication failed.\r\n", szMessage); 92 | #endif 93 | pstcbPPP->enState = AUTHENFAILED; 94 | break; 95 | 96 | case AUTHREQ: 97 | #if SUPPORT_PRINTF && DEBUG_LEVEL > 1 98 | printf("]\r\nPAP authentication failed, unsupported request type.\r\n"); 99 | #endif 100 | pstcbPPP->enState = AUTHENFAILED; 101 | break; 102 | } 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /ppp/wait_ack_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 The Onps Project Author All Rights Reserved. 3 | * 4 | * Author:Neo-T 5 | * 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * http://www.onps.org.cn/apache2.0.txt 10 | * 11 | */ 12 | #include "port/datatype.h" 13 | #include "port/sys_config.h" 14 | #include "onps_errors.h" 15 | #include "port/os_datatype.h" 16 | #include "port/os_adapter.h" 17 | #include "mmu/buddy.h" 18 | 19 | #if SUPPORT_PPP 20 | #define SYMBOL_GLOBALS 21 | #include "ppp/wait_ack_list.h" 22 | #undef SYMBOL_GLOBALS 23 | 24 | #define PPP_WAIT_ACK_NODE_NUM 5 //* 分配的应答等待节点的数量,每个ppp链路拨号时使用4个,多出几个留点裕富 25 | static ST_PPPWAITACKNODE l_staaPPPWaitAckNode[PPP_NETLINK_NUM][PPP_WAIT_ACK_NODE_NUM]; 26 | 27 | //* 等待应答队列 28 | BOOL wait_ack_list_init(PST_PPPWAITACKLIST pstWAList, EN_ONPSERR *penErr) 29 | { 30 | if (pstWAList->bPPPIdx < 0 || pstWAList->bPPPIdx >= PPP_NETLINK_NUM) 31 | { 32 | if (penErr) 33 | *penErr = ERRPPPIDXOVERFLOW; 34 | return FALSE; 35 | } 36 | 37 | pstWAList->hMutex = os_thread_mutex_init(); 38 | if (INVALID_HMUTEX == pstWAList->hMutex) 39 | { 40 | if(penErr) 41 | *penErr = ERRMUTEXINITFAILED; 42 | return FALSE; 43 | } 44 | 45 | INT i; 46 | for (i = 0; i < PPP_WAIT_ACK_NODE_NUM; i++) 47 | l_staaPPPWaitAckNode[pstWAList->bPPPIdx][i].bIsUsed = FALSE; 48 | 49 | pstWAList->pstHead = NULL; 50 | pstWAList->ubTimeoutCount = 0; 51 | 52 | return TRUE; 53 | } 54 | 55 | void wait_ack_list_uninit(PST_PPPWAITACKLIST pstWAList) 56 | { 57 | if (pstWAList && INVALID_HMUTEX != pstWAList->hMutex) 58 | { 59 | os_thread_mutex_lock(pstWAList->hMutex); 60 | { 61 | //* 销毁所有尚未等到应答的节点资源,避免内存泄露 62 | PST_PPPWAITACKNODE pstNextNode = pstWAList->pstHead; 63 | while (pstNextNode) 64 | { 65 | one_shot_timer_recount(pstNextNode->pstTimer, 1); //* 其实还是交给超时函数去统一处理,这样才可确保对该链表的访问不会冲突 66 | pstNextNode = pstNextNode->pstNext; //* 移动到下一个节点 67 | } 68 | } 69 | os_thread_mutex_unlock(pstWAList->hMutex); 70 | 71 | //* 等待所有节点释放完毕 72 | while (pstWAList->pstHead) 73 | os_sleep_ms(10); 74 | 75 | //* 销毁互斥锁 76 | os_thread_mutex_uninit(pstWAList->hMutex); 77 | pstWAList->hMutex = INVALID_HMUTEX; 78 | } 79 | } 80 | 81 | static PST_PPPWAITACKNODE wait_ack_list_get_free_node(PST_PPPWAITACKLIST pstWAList) 82 | { 83 | PST_PPPWAITACKNODE pstNode = NULL; 84 | os_thread_mutex_lock(pstWAList->hMutex); 85 | { 86 | INT i; 87 | for (i = 0; i < PPP_WAIT_ACK_NODE_NUM; i++) 88 | { 89 | if (!l_staaPPPWaitAckNode[pstWAList->bPPPIdx][i].bIsUsed) 90 | { 91 | pstNode = &l_staaPPPWaitAckNode[pstWAList->bPPPIdx][i]; 92 | pstNode->bIsUsed = TRUE; 93 | break; 94 | } 95 | } 96 | } 97 | os_thread_mutex_unlock(pstWAList->hMutex); 98 | 99 | return pstNode; 100 | } 101 | 102 | static void wait_ack_list_free_node(PST_PPPWAITACKLIST pstWAList, PST_PPPWAITACKNODE pstFreedNode) 103 | { 104 | if (!pstWAList || INVALID_HMUTEX == pstWAList->hMutex || !pstFreedNode) 105 | return; 106 | 107 | //* 从链表中摘除 108 | if (pstFreedNode->pstPrev) 109 | pstFreedNode->pstPrev->pstNext = pstFreedNode->pstNext; 110 | if (pstFreedNode->pstNext) 111 | pstFreedNode->pstNext->pstPrev = pstFreedNode->pstPrev; 112 | if (pstWAList->pstHead == pstFreedNode) 113 | pstWAList->pstHead = pstFreedNode->pstNext; 114 | 115 | //* 归还当前已经结束使命的wait ack节点 116 | pstFreedNode->bIsUsed = FALSE; 117 | } 118 | 119 | static void wait_ack_timeout_handler(void *pvParam) 120 | { 121 | PST_PPPWAITACKNODE pstTimeoutNode = (PST_PPPWAITACKNODE)pvParam; 122 | PST_PPPWAITACKLIST pstWAList = pstTimeoutNode->pstList; 123 | 124 | os_thread_mutex_lock(pstWAList->hMutex); 125 | { 126 | if (pstTimeoutNode->bIsAcked) //* 如果已经收到应答报文,则错误计数归零 127 | pstWAList->ubTimeoutCount = 0; 128 | else //* 超时了,当前节点记录的报文未收到应答 129 | { 130 | if (pstTimeoutNode->bIsAcked) //* 存在这种情况,等待进入临界段时好巧不巧收到应答报文了 131 | pstWAList->ubTimeoutCount = 0; 132 | else 133 | { 134 | pstWAList->ubIsTimeout = TRUE; 135 | pstWAList->ubTimeoutCount++; 136 | } 137 | } 138 | 139 | //* 直接释放当前节点即可,不需要单独释放申请的定时器,定时器超时后会自动归还给系统 140 | wait_ack_list_free_node(pstWAList, pstTimeoutNode); 141 | } 142 | os_thread_mutex_unlock(pstWAList->hMutex); 143 | } 144 | 145 | BOOL wait_ack_list_add(PST_PPPWAITACKLIST pstWAList, USHORT usProtocol, UCHAR ubCode, UCHAR ubIdentifier, INT nTimerCount, EN_ONPSERR *penErr) 146 | { 147 | if (!pstWAList || INVALID_HMUTEX == pstWAList->hMutex) 148 | { 149 | if (penErr) 150 | *penErr = ERRPPPWALISTNOINIT; 151 | return FALSE; 152 | } 153 | 154 | //* 申请一块内存以建立一个新的队列节点 155 | PST_PPPWAITACKNODE pstNewNode = wait_ack_list_get_free_node(pstWAList); 156 | if (!pstNewNode) 157 | { 158 | if (penErr) 159 | *penErr = ERRNOFREEPPWANODE; 160 | 161 | return FALSE; 162 | } 163 | 164 | //* 新建一个定时器用于等待应答计时 165 | pstNewNode->pstTimer = one_shot_timer_new(wait_ack_timeout_handler, pstNewNode, nTimerCount); 166 | if (!pstNewNode->pstTimer) 167 | { 168 | //buddy_free(pstNewNode); 169 | 170 | if (penErr) 171 | *penErr = ERRNOIDLETIMER; 172 | return FALSE; 173 | } 174 | //* 记录等待应答报文的关键特征数据 175 | pstNewNode->stPacket.usProtocol = usProtocol; 176 | pstNewNode->stPacket.ubCode = ubCode; 177 | pstNewNode->stPacket.ubIdentifier = ubIdentifier; 178 | //* 尚未等到应答 179 | pstNewNode->bIsAcked = FALSE; 180 | 181 | //* 记录链表首地址,超时处理函数需要 182 | pstNewNode->pstList = pstWAList; 183 | 184 | //* 加入队列 185 | pstNewNode->pstNext = NULL; 186 | pstNewNode->pstPrev = NULL; 187 | os_thread_mutex_lock(pstWAList->hMutex); 188 | { 189 | pstNewNode->pstNext = pstWAList->pstHead; 190 | if (pstWAList->pstHead) 191 | pstWAList->pstHead->pstPrev = pstNewNode; 192 | pstWAList->pstHead = pstNewNode; 193 | } 194 | os_thread_mutex_unlock(pstWAList->hMutex); 195 | 196 | return TRUE; 197 | } 198 | 199 | void wait_ack_list_del(PST_PPPWAITACKLIST pstWAList, USHORT usProtocol, UCHAR ubIdentifier) 200 | { 201 | if (!pstWAList || INVALID_HMUTEX == pstWAList->hMutex) 202 | return; 203 | 204 | os_thread_mutex_lock(pstWAList->hMutex); 205 | { 206 | PST_PPPWAITACKNODE pstNextNode = pstWAList->pstHead; 207 | while (pstNextNode) 208 | { 209 | if (usProtocol == pstNextNode->stPacket.usProtocol && ubIdentifier == pstNextNode->stPacket.ubIdentifier) 210 | { 211 | pstNextNode->bIsAcked = TRUE; 212 | one_shot_timer_recount(pstNextNode->pstTimer, 1); //* 其实还是交给超时函数去统一处理,这样才可确保对该链表的访问不会冲突,因为存在应答收到这一刻同时定时器超时溢出的情况,所以 213 | //* 在这里我们只是打上已收到应答的标志,同时调整定时器1秒后溢出,由定时器超时函数统一回收相关资源 214 | break; 215 | } 216 | 217 | pstNextNode = pstNextNode->pstNext; 218 | } 219 | } 220 | os_thread_mutex_unlock(pstWAList->hMutex); 221 | } 222 | 223 | #endif 224 | -------------------------------------------------------------------------------- /tencentpay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo-T/OpenNPStack/bb0d59d46bdf4b126a46b98da25cf530d612e000/tencentpay.jpg --------------------------------------------------------------------------------