看明白在uclibc中网络系统调用是如何实现的

有源滤波电路设计 目录一、低通滤波器1、同相输入低通滤波器(1)一阶低通滤波电路(2)二阶低通滤波电路(压控电压源;Sallen-Key)2、反相输入低通滤波器(1)一阶低通滤波电路(2)二阶低通滤波电路(无限增益多路反馈)二、高通滤波器1、同相输入高通滤波器(1)一阶高通滤波电路(2)二阶高通滤波电路(压控电压源;Sallen-Key)2、反相输入高通滤波电路(1)二阶高通滤波电路(无限增益多路反馈) 一、低通滤波器 1、同相输入低通滤波器 (1)一阶低通滤波电路 即在一阶无源低通滤波器的基础上,加了一个集成运放。 它的 阅读详情

目标: 看明白在uclibc中网络系统调用是如何实现的,和普通的Linux有什么区别

0. 将uClibc-0.9.30.1/libc/inet目录下的文件按文件大小排列一下,会发出100多字节的文件有很多,都是调用的。呵呵。

1. 代码文件:uClibc-0.9.30.1/libc/inet/socketcall.c 代码如下:

#ifdef L_recv

extern __typeof(recv) __libc_recv;

#ifdef __NR_recv

#define __NR___libc_recv __NR_recv

_syscall4(ssize_t, __libc_recv, int, sockfd, __ptr_t, buffer, size_t, len,

int, flags)

#elif defined(__NR_socketcall)

/* recv, recvfrom added by bir7@leland.stanford.edu */

ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)

{

unsigned long args[4];

 

args[0] = sockfd;

args[1] = (unsigned long) buffer;

args[2] = len;

args[3] = flags;

return (__socketcall(SYS_RECV, args));

}

#elif defined(__NR_recvfrom)

libc_hidden_proto(recvfrom)

ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)

{

return (recvfrom(sockfd, buffer, len, flags, NULL, NULL));

}

#endif

libc_hidden_proto(recv)

weak_alias(__libc_recv,recv)

libc_hidden_weak(recv)

#endif

 

#ifdef L_connect

extern __typeof(connect) __libc_connect;

#ifdef __NR_connect

#define __NR___libc_connect __NR_connect

_syscall3(int, __libc_connect, int, sockfd, const struct sockaddr *, saddr, socklen_t, addrlen)

#elif defined(__NR_socketcall)

int __libc_connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen)

{

unsigned long args[3];

 

args[0] = sockfd;

args[1] = (unsigned long) saddr;

args[2] = addrlen;

return __socketcall(SYS_CONNECT, args);

}

#endif

libc_hidden_proto(connect)

weak_alias(__libc_connect,connect)

libc_hidden_weak(connect)

#endif

 

#ifdef L_getpeername

#ifdef __NR_getpeername

_syscall3(int, getpeername, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen)

#elif defined(__NR_socketcall)

int getpeername(int sockfd, struct sockaddr *addr, socklen_t * paddrlen)

{

unsigned long args[3];

 

args[0] = sockfd;

args[1] = (unsigned long) addr;

args[2] = (unsigned long) paddrlen;

return __socketcall(SYS_GETPEERNAME, args);

}

#endif

#endif

 

2. 对上面代码的分析:

A. 将网络系统调用传送过来的参数放到一个unsigned long 型参数数组中, 再将这些参数传递给内核的__开头的函数库。 

B. 注意:为什么是unsigned long ? 因为unsigned long 可以存储指针的地址。 还有这里有不同的recv版本的,这个和当时编译的环境相关

C. 不过这里没有对入口参数进行判断,会不会被黑客利用?

 

3. ntohl.c

#if __BYTE_ORDER == __BIG_ENDIAN

uint32_t ntohl (uint32_t x)

{

return x;

}

 

uint16_t ntohs (uint16_t x)

{

return x;

}

 

uint32_t htonl (uint32_t x)

{

return x;

}

 

uint16_t htons (uint16_t x)

{

return x;

}

#elif __BYTE_ORDER == __LITTLE_ENDIAN

uint32_t ntohl (uint32_t x)

{

return __bswap_32(x);

}

 

uint16_t ntohs (uint16_t x)

{

return __bswap_16(x);

}

 

uint32_t htonl (uint32_t x)

{

return __bswap_32(x);

}

 

uint16_t htons (uint16_t x)

{

return __bswap_16(x);

}

#else

#error "You seem to have an unsupported byteorder"

#endif

4. 对上面代码分析:  三种模式: 大端,小端,不可识别的。

大端的时候是uclinux默认的,而小端就需要用函数转换一下了

 

5. getaddrinfo.c

libc_hidden_proto(getaddrinfo)

int

getaddrinfo(const char *name, const char *service,

    const struct addrinfo *hints, struct addrinfo **pai)

{

int i = 0, j, last_i = 0;

struct addrinfo *p = NULL, **end;

const struct gaih *g = gaih, *pg = NULL;

struct gaih_service gaih_service, *pservice;

struct addrinfo default_hints;

 

if (name != NULL && name[0] == '*' && name[1] == 0)

name = NULL;

 

if (service != NULL && service[0] == '*' && service[1] == 0)

service = NULL;

 

if (name == NULL && service == NULL)

return EAI_NONAME;

 

if (hints == NULL) {

memset(&default_hints, 0, sizeof(default_hints));

if (AF_UNSPEC)

default_hints.ai_family = AF_UNSPEC;

hints = &default_hints;

}

 

if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|

AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL))

return EAI_BADFLAGS;

 

if ((hints->ai_flags & AI_CANONNAME) && name == NULL)

return EAI_BADFLAGS;

 

if (service && service[0]) {

char *c;

gaih_service.name = service;

gaih_service.num = strtoul(gaih_service.name, &c, 10);

if (*c != '/0') {

if (hints->ai_flags & AI_NUMERICSERV)

return EAI_NONAME;

gaih_service.num = -1;

} else {

/*

* Can't specify a numerical socket unless a protocol

* family was given.

*/

if (hints->ai_socktype == 0 && hints->ai_protocol == 0)

return EAI_SERVICE;

}

pservice = &gaih_service;

} else

pservice = NULL;

 

end = NULL;

if (pai)

end = &p;

 

j = 0;

while (g->gaih) {

if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC) {

if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family)) {

++g;

continue;

}

j++;

if (pg == NULL || pg->gaih != g->gaih) {

pg = g;

i = g->gaih(name, pservice, hints, end);

if (i != 0) {

last_i = i;

if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))

continue;

if (p)

freeaddrinfo(p);

return -(i & GAIH_EAI);

}

if (end)

while (*end)

end = &((*end)->ai_next);

}

}

++g;

}

 

if (j == 0)

return EAI_FAMILY;

 

if (p) {

*pai = p;

return 0;

}

 

if (pai == NULL && last_i == 0)

return 0;

 

/* if (p) - never happens, see above */

/* freeaddrinfo(p); */

 

return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;

}

libc_hidden_def(getaddrinfo)

6. 对上面代码的分析:

A.  比较复杂

B. 太懒了,不想看,也看不懂

 

7. 对这些代码阅读之后的感想。

怎样才是一个合格或者是熟练的uclinux 上的软件开发工程师?这里只说C。。 我想应该要用熟练这个库里提供的所有函数,这样应该就OK了,有心人的话,也可以把这些函数库全部读一遍,有个一两年Linux平台下C开发经验的人,读这个应该很快的吧,而且会得心应手,发现uclibc的库真简单,难点不是太多,但是全部掌握这个库也要花点心血的。

应该没有必要去重写这个库,不过,用这个库去做一些实事,倒是最为重要的。这个目标和大部分库的目标是一样的。 为了让更多人使用

手把手教你学simulink(31.31)--双向DCDC电源场景示例:设计并实现一个基于变频控制的双向降压变换 设计并实现一个基于 Simulink 的双向降压变换器,能够在充电模式(从高压侧向低压侧传输能量)和放电模式(从低压侧向高压侧传输能量)之间切换,确保输出电压稳定,并根据负载变化自动调整工作模式。 阅读详情

相关推荐

Linux下开机异常(fsck exited with status code 4)

Linux下开机异常事情是这样的,本来我呢跑着程序听着歌,结果忽然就死机了,我只能强制关机,再次打开系统的时候,就提示这样fsck from util-linux 2.26.2 /dev/sda10 contains a file system with errors, check forced. /dev/sda10: Inodes that were part of a corrupted pr

芳草碧连天 2万+

出现 尝试连接“EAI_NONAME未提供,或不知道节点名或服务名”失败 解决办法!

出现 尝试连接“EAI_NONAME未提供,或不知道节点名或服务名”失败 解决办法 1.问题的原因:IP地址不在同一网关 VirtualBox虚拟机装的Ubuntu系统设置的是默认IP是:10.0.2.15(属于A类IP),而我的win10上的IP是192.168.x.x(x代替数字,就不写真正的了),这是C类IP,这俩不在同一网关,就是类似不在同一个频道,我们要做的是将Ubuntu系统设置的是默认IP是:10.0.2.15 改为C类的就可以了。 2.解决方案: 一种是在Ubuntu终端上进行代码命令更改,

m0_49324068的博客 3713

PCB设计之ODB++文件格式详解

ODB++(Open Database++)是一种广泛应用于PCB(印制电路板)设计和制造领域的开放数据交换格式。它由Valor Computerized Systems(现为Siemens EDA的一部分)开发,旨在替代传统的Gerber文件格式,提供更完整、结构化的制造数据,从而优化PCB设计到生产的流程。ODB++通过结构化数据整合了PCB设计到制造的全流程信息,显著提高了生产效率和准确性。尽管存在一定的兼容性挑战,但其在复杂项目和高可靠性场景中的价值不可替代。

ZZcppc的博客 1万+

libc_hidden_def、libc_hidden_weak、libc_hidden_proto

libc_hidden_def、libc_hidden_weak、libc_hidden_proto 在阅读glibc源码的时候,遇见了几个没见过的宏,几乎所有的函数都会使用这几个宏:libc_hidden_def、libc_hidden_weak、libc_hidden_proto 因为我比较好奇,所以特地去找了一下有关这些宏的定义(主要也是想多学一点) Linux下学习源码,最方便的地方就是它的各种命令 使用find ./ | grep -r "define libc_hidden_def",发现在in

私のBookShelf 2403

注册“Oracle Provider for OLE DB”和创建链接服务器

注册“Oracle Provider for OLE DB”和创建链接服务器 在sql server 数据库上创建链接服务器,连接oracle数据库,访问接口需要设置为:“Oracle Provider for OLE DB”。 如果电脑上没有这个驱动,安装一个完整的Oracle11gR2程序是一个有效的方法,但这个64位版本的安装包有2个多G, 相当庞大,如果仅仅...

weixin_30760895的博客 2383

Unity AssetBundle 之 (入门)简单的资源打包成AB包的方法

Unity AssetBundle 之 (入门)简单的资源打包成AB包的方法 目录 Unity AssetBundle 之 (入门)简单的资源打包成AB包的方法 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、实现步骤 六、关键代码 一、简单介绍 Unity中的一些基础知识点。 本节介绍,Asset Bundle 在 Unity中的使用,入门第一篇,如何AssetBundle标记,如何打包成AssetBundle的操作方法,有不对的地方欢迎指正。...

仙魁XAN 1万+

fileZilla连接服务器报错

fileZilla连接服务器    1 服务器地址 2 服务器用户名和密码 3 端口 22   如果报错很有可能是服务器没有开启ssh服务,只需开启服务器的ssh服务即可

zt1212121z的博客 1121

数学建模入门——数据预处理(全)

介绍了数据预处理的入门知识

n04j04h06的博客 4346

linux下的系统调用函数到内核函数的追踪

转自:http://blog.chinaunix.net/uid-28458801-id-3468966.html 非常感谢! 使用的 glibc : glibc-2.17 使用的 linux kernel :linux-3.2.07   系统调用是内核向用户进程提供服务的唯一方法,应用程序调用操作系统提供的功能模块(函数)。 用户程序通过系统调

missingu1314的专栏 1256

ptrade从零开始学习量化交易第166期【ptrade量化策略研究参考--三个因子挖掘思路】

三个因子挖掘思路

GJ57017_wx的博客 1246

Halcon实例转OpenCVSharp--粘连物体分割与计数(基于距离变换+分水岭算法) (附源码)

本文作者Color Space,文章未经作者允许禁止转载! 本文将介绍OpenCVSharp应用实例--粘连物体分割与计数(基于距离变换+分水岭算法)! 本文使用的OpenCVSharp版本---》v4.5.3。 实现目标:将下图中的硬币分割出来并计算数量。 预期效果图: ...

Color Space的博客 2419

Android DNS之getaddrinfo()的实现

这篇笔记分析了库函数getaddrinfo()的代码实现。 原型解读 int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res); hostname: 和gethostbyname()的入参hostname相同,要查询的域...

九天小哥的专栏 8371

SAR图像去斑(Despeckling)研究的主流开源数据集

这些数据集专门用于训练监督学习去斑模型,提供了配对的含斑SAR图像和对应的无噪声参考图像(Ground Truth)。这些数据集主要用于目标检测/识别,但包含原始SAR图像,可用于。由于缺乏真实无噪声SAR图像,许多研究采用。

VectorShift的博客 128

Linux多线程调试 windows多线程调试

gdb调试基本命令 gdb attach 进程id info thread (gdb) info thread Id Target Id Frame * 1 Thread 0x7f28dbf76f40 (LWP 2563) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep ( requested_time=requested_time@entry=0x7fff2da728d0, remaining=r

irislin1988的博客 2976

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

glibc中socket syscall的主要文件

sysdeps/unix/sysv/linux/x86_64/syscalls.list 2.# proper socket implementations:accept - accept Ci:iBN __libc_accept __accept accept bind - bind i:ipi __bind bind

hl001的专栏 948

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

getaddrinfo返回值为7(EAI_NODATA),失败排查

常量 描述 EAI_ADDRFAMILY 不支持hostname的地址族 1 EAI_AGAIN 名字解析中的暂时失败 2 EAI_BADFLAGS ai_flags的值无效 3 EAI_FAIL 名字解析中不可恢复的失败 4 EAI_FAMILY 不支持ai_family 5 EAI_MEMORY 内存分配失败 6 EAI_NODATA 没有与hostname相关联的地址7 EAI_NONAME hostname或service未提供,或者不可知 8 EAI_SERVICE 不支持ai_socktype类

u011018840的博客 3280

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

socket系统调用

Linux网络编程中调用的socket函数,是在glibc中通过汇编代码封装起来的。 uClibc-0.9.30.3/libc/inet/socketcalls.c #ifdef L_socket libc_hidden_proto(socket) #ifdef __NR_socket _syscall3(int, socket, int, family, int, type, int,

hpp205的专栏 1621

linux 系统调用(二)源码分析

本文基于linux3.10内核 1 应用层处理 在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的。在glibc库中,通过封装例程(Wrapper Routine)将API和系统调用关联起来。API是头文件中所定义的函数接口,而位于glibc中的封装例程则是对该API对应功能的具体实现。事实上,我们知道接口op...

oqqYuJi12345678的博客 1883

glibc php,glibc 源码之 include/libc-symbols.h

/* The following macros are used for PLT bypassing within libc.so(and if needed other libraries similarly).First of all, you need to have the function prototyped somewhere,say in foo/foo.h:int foo (in...

weixin_42097819的博客 426

ARM Linux系统调用的原理

ARM Linux系统调用的原理 操作系统为在用户态运行的进程与硬件设备进行交互提供了一组接口。在应用程序和硬件之间设置一个额外层具有很多优点。首先,这使得编程更加容易,把用户从学习硬件设备的低级编程特性中解放出来。其次,这极大地提高了系统的安全性,因为内核在试图满足某个请求之

5019

Arm Linux系统调用流程详细解析

Linux系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口。 系统调用是操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,系统调用的执行让用户程序陷入内核,该陷入动作由swi软中断完成。 1、用户可以通过两种方式使用系统调用: 第一种方式是通过C库函数,包括系统调用在C库中的封装函数和其他普通函数。 第二种方式是使用...

weixin_30908649的博客 355

Linux高性能服务器编程(6)socket基础

Linux网络编程基础APIsocket地址API。socket最开始的含义是一个IP地址和端口对(ip,port)。它唯一地表示了使用TCP通信地一端。socket基础API。socket地主要API都定义在sys/socket.h头文件中,包括创建socket、命名socket、监听socket、接收连接、发起连接、读写数据、获取地址信息、检测带外标记,以及读取和设置socket选项。网络信息API。

qq_53002662的博客 475

GNU C库「glibc」getaddrinfo 发现重大漏洞

本文翻译至:http://www.itmedia.co.jp/enterprise/articles/1602/17/news065.html  大部分Linux应用程序使用的GNU C库「glibc」发现重大漏洞,美国Google和Red Hat的研究人员于2月16日公开开发的补丁。  该漏洞存在于2008年5月发布的glibc 2.9之后的版本。据Google称,使用glibc库的「get

闲云孤鹤 1963

uClibc-0.9.33\include\wordexp.h

uClibc-0.9.33\include\wordexp.h

llrraa2010的专栏 1810

【Linux C | 网络编程】getaddrinfo 函数详解及C语言例子

👉本文重点介绍了 getaddrinfo、freeaddrinfo、gai_strerror 三个函数,并给出C语言使用例子。

wkd_007的博客 9453

perf mysql_通过perf 查看mysql 堆栈

OS version:Red Hat Enterprise Linux Server release 6.3 (Santiago)MYSQL version: 8.0.18-commercial MySQL Enterprise Server - Commercial[root@dbmspredb308 mysql_backup]# perf record -a --call-graph -p 2...

weixin_28687685的博客 1741
上一篇: debian 系列 ubuntu..让一个网卡支持多个IP
下一篇: tftp 协议分析
brauceunix
博客等级 码龄16年 26粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值