0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

網(wǎng)絡(luò)套接字系統(tǒng)調(diào)用如何到達sys_socketcall

麥辣雞腿堡 ? 來源:技術(shù)簡說 ? 作者:技術(shù)簡說 ? 2023-07-24 11:35 ? 次閱讀

套接字系統(tǒng)調(diào)用如何到達sys_socketcall

accept函數(shù)為例

系統(tǒng)調(diào)用中參數(shù)從用戶態(tài)向內(nèi)核態(tài)的傳遞是通過寄存器完成的,eax表示系統(tǒng)調(diào)用,ebx表示第一個參數(shù),ecx表示第二個參數(shù),edx表示第三個參數(shù)(主要針對socke.S)

第一層:accept.s文件

(glibc函數(shù)庫)sysdepsunissysvlinuxaccept.S

#define socket accept    //將socket定義為accept
#define _socket _libc_accept
#define NARGS 3           //系統(tǒng)調(diào)用的個數(shù)
#include < socket.S >     //這幾個套接字函數(shù)的通用實現(xiàn)

第二層:socket.S文件

#include < sysdep.h >
#include < sys/socketcall.h >

#define P(a, b) P2(a, b)
#define P2(a, b) a##b

.text
/* The socket-oriented system calls are handled unusally in Linux.
  They are all gated through the single `socketcall' system call number.
  `socketcall' takes two arguments: the first is the subcode, specifying
  which socket function is being called; and the second is a pointer to
  the arguments to the specific function.

  The .S files for the other calls just #define socket and #include this. */

.globl P(__,socket)
ENTRY (P(__,socket))

/* Save registers. */
movl %ebx, %edx

movl $SYS_ify(socketcall), %eax/* System call number in %eax. */
//展開$SYS_iff()宏
/* Use ## so `socket' is a separate token that might be #define'd. */
movl $P(SOCKOP_,socket), %ebx/* Subcode is first arg to syscall. */
lea 4(%esp), %ecx/* Address of args is 2nd arg. */

       /* Do the system call trap. */
int $0x80

/* Restore registers. */
movl %edx, %ebx

/* %eax is < 0 if there was an error. */
cmpl $-125, %eax
jae syscall_error

/* Successful; return the syscall's value. */
ret

PSEUDO_END (P(__,socket))
c
weak_alias (P(__,socket), socket)

重點看:

movl $SYS_ify(socketcall), %eax /* System call number in %eax. */

展開SYS_iff()宏 (glibc函數(shù)庫: sysdepsunixsysdep.h)

#ifdef __STDC__
#define SYS_ify(syscall_name) SYS_##syscall_name
#else
#define SYS_ify(syscall_name) SYS_/**/syscall_name
#endif

預(yù)處理后為:

movl $SYS_socketcall,%eax
//將系統(tǒng)調(diào)用號放入eax中,但是對于網(wǎng)絡(luò)套接字所有的接口函數(shù)而言,他們的共同入口函數(shù)是sys_socketcall
//在內(nèi)核中,總?cè)肟诤瘮?shù)sys_socketcall的系統(tǒng)調(diào)用號為_NR_socketcall,定義在include/linux/unistd.h
#define __NR_socketcall102
//在glib函數(shù)庫中,有如下的預(yù)定義
#define SYS_socketcall _NR_socketcall

所以:

movl $SYS_socketcall,%eax
//將sys_socketcall函數(shù)對應(yīng)的系統(tǒng)調(diào)用號賦予eax寄存器,從而使套接字系統(tǒng)調(diào)用進入到正常的入口函數(shù)中

這樣套接字系統(tǒng)調(diào)用進入到正確的函數(shù)中了。

那么第一個參數(shù)是識別系統(tǒng)調(diào)用的具體函數(shù)的,這個參數(shù)在socket.S(glibc庫)中:

movl $P(SOCKOP_,socket), %ebx
//預(yù)處理后:
movl $SOCKOP_accept,%ebx//這就完成了第一個參數(shù)的傳遞

關(guān)于SOCKOP_accept:

查看(glibc庫:sysdepsunixsysvlinuxsocketcall.h)

#ifndef _SYS_SOCKETCALL_H

#define _SYS_SOCKETCALL_H	1

/* Define unique numbers for the operations permitted on socket.  Linux
   uses a single system call for all these functions.  The relevant code
   file is /usr/include/linux/net.h.
   We cannot use a enum here because the values are used in assembler
   code.  */

#define SOCKOP_socket		1
#define SOCKOP_bind		2
#define SOCKOP_connect		3
#define SOCKOP_listen		4
//可以看到SOCKOP_accept對應(yīng)的值為5
#define SOCKOP_accept		5
#define SOCKOP_getsockname	6
#define SOCKOP_getpeername	7
#define SOCKOP_socketpair	8
#define SOCKOP_send		9
#define SOCKOP_recv		10
#define SOCKOP_sendto		11
#define SOCKOP_recvfrom		12
#define SOCKOP_shutdown		13
#define SOCKOP_setsockopt	14
#define SOCKOP_getsockopt	15
#define SOCKOP_sendmsg		16
#define SOCKOP_recvmsg		17

#endif /* _SYS_SOCKETCALL_H */

在linux內(nèi)核(include/linux/net.h):

#ifndef _SYS_SOCKETCALL_H

#define _SYS_SOCKETCALL_H	1

/* Define unique numbers for the operations permitted on socket.  Linux
   uses a single system call for all these functions.  The relevant code
   file is /usr/include/linux/net.h.
   We cannot use a enum here because the values are used in assembler
   code.  */

#define SOCKOP_socket		1
#define SOCKOP_bind		2
#define SOCKOP_connect		3
#define SOCKOP_listen		4
//這與glibc庫中的SOCKOP_accept對應(yīng)的值相同
#define SOCKOP_accept		5
#define SOCKOP_getsockname	6
#define SOCKOP_getpeername	7
#define SOCKOP_socketpair	8
#define SOCKOP_send		9
#define SOCKOP_recv		10
#define SOCKOP_sendto		11
#define SOCKOP_recvfrom		12
#define SOCKOP_shutdown		13
#define SOCKOP_setsockopt	14
#define SOCKOP_getsockopt	15
#define SOCKOP_sendmsg		16
#define SOCKOP_recvmsg		17

#endif /* _SYS_SOCKETCALL_H */

第二個參數(shù)

在socket.S中:以指針的方式設(shè)置了sys_socketcall的第二個參數(shù)

lea 4(%esp), %ecx		/* Address of args is 2nd arg.  */

設(shè)置完以上的系統(tǒng)調(diào)用號還有參數(shù)后進入軟中斷:int $0x80,進入了內(nèi)核態(tài)進行處理

第三層:entry.S文件

_system_call:
	pushl %eax			# save orig_eax
	SAVE_ALL
	movl $-ENOSYS,EAX(%esp)
	cmpl $(NR_syscalls),%eax
	jae ret_from_sys_call
    /*對應(yīng)上面,未調(diào)用軟中斷之前,eax寄存器中被初始化為系統(tǒng)調(diào)用號,即_NR_socketcall,
       這個調(diào)用號別用于在_sys_call_table數(shù)組中進行函數(shù)指針的尋址,將對應(yīng)的函數(shù)地址對eax寄存器賦值      */
	movl _sys_call_table(,%eax,4),%eax
	testl %eax,%eax
	je ret_from_sys_call
	movl _current,%ebx
	andl $~CF_MASK,EFLAGS(%esp)	# clear carry - assume no errors
	movl $0,errno(%ebx)
	movl %db6,%edx
	movl %edx,dbgreg6(%ebx)  # save current hardware debugging status
	testb $0x20,flags(%ebx)		# PF_TRACESYS
	jne 1f
    /*上面給eax復(fù)制后,這里進行調(diào)用該函數(shù),到這為止,accept系統(tǒng)調(diào)用將請求傳遞給了sys_socketcall,
        然后將socket.S中設(shè)置的參數(shù)傳遞給sock_accept函數(shù),就完成了應(yīng)用層接口函數(shù)accept到BSD socket層函數(shù)的請求傳遞工作
        */
	call *%eax
	movl %eax,EAX(%esp)		# save the return value
	movl errno(%ebx),%edx
	negl %edx
	je ret_from_sys_call
	movl %edx,EAX(%esp)
	orl $(CF_MASK),EFLAGS(%esp)	# set carry to indicate error
	jmp ret_from_sys_call
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5359

    瀏覽量

    120827
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4344

    瀏覽量

    62818
  • 系統(tǒng)
    +關(guān)注

    關(guān)注

    1

    文章

    1018

    瀏覽量

    21385
收藏 人收藏

    評論

    相關(guān)推薦

    【MiCOKit試用體驗】慶科MiCO系統(tǒng)篇(5)MiCO 套接

    管理協(xié)議)、DNS(主域名稱系統(tǒng))、TFTP(通用文件傳輸協(xié)議)等。TCP的通信機制大體可如下圖所示UDP的通信機制大體可如下圖所示二 MiCOKit套接在MiCOKit中,有關(guān)Socket
    發(fā)表于 10-24 17:05

    UNIX域套接

    UNIX域套接用于在同一臺計算機上運行的進程之間的通信。雖然因特網(wǎng)域套接可用于同一目的,但UNIX域套接
    發(fā)表于 09-02 11:59

    命名UNIX域套接

    雖然socketpair函數(shù)能創(chuàng)建一對相互連接的套接,但是每一個套接都沒有名字。這意味著無關(guān)進程不能使用它們。如果我們試圖綁定同一地址時,該文件已經(jīng)存在,那么bind請求會失敗。當
    發(fā)表于 09-02 14:45

    交換機網(wǎng)絡(luò)從Soft_AP到Infrastructure后,套接始終返回無效

    與以下代碼的客戶端連接通過這個實現(xiàn),TCPPOEN函數(shù)返回一個有效的套接,但是在進入無限循環(huán)之后,我們通過在網(wǎng)頁中配置網(wǎng)絡(luò)來配置網(wǎng)絡(luò)處于基礎(chǔ)結(jié)構(gòu)模式。當
    發(fā)表于 04-24 09:57

    STM32例程能否與MFC網(wǎng)絡(luò)套接通信?

    如題。。想自己寫一個PC上的MFC界面。不要求太高的實時性和過大過高的傳輸數(shù)據(jù)量,偶爾一次傳輸幾十節(jié)即可,不知道STM32例程能否與MFC網(wǎng)絡(luò)套接通信。如果可以就入手一套了,另外,
    發(fā)表于 08-02 04:36

    Harmony堆棧為什么會立即終止套接嗎?

    配置了20個NET_PRES套接、8個BSD套接和20個TCPIP套接。TCPIP堆為64
    發(fā)表于 03-19 10:43

    如何通過socket系統(tǒng)調(diào)用創(chuàng)建一個套接

    。服務(wù)器端:首先服務(wù)器 應(yīng)用程序通過socket系統(tǒng)調(diào)用創(chuàng)建一個套接,他是系統(tǒng)分配給該服務(wù)器進程的類似文件描述符的資源,不能和其他進程分享
    發(fā)表于 12-24 06:38

    RTT網(wǎng)絡(luò)框架及SAL套接抽象層介紹

    基于自己對各層級的理解,作為劃分依據(jù)。應(yīng)用編程、協(xié)議棧與網(wǎng)卡驅(qū)動首先請允許我簡單粗暴地把所有基于協(xié)議棧應(yīng)用接口開發(fā)的相關(guān)代碼,都歸屬于應(yīng)用編程下,在帶操作系統(tǒng)的情況下,通常協(xié)議棧都會提供套接
    發(fā)表于 07-28 11:40

    如何在iMXRT1176上的LwIP中使用TCP套接

    使用原始 API) 2) OS模式可以使用Socket API和Raw API 3) lwip_ping_freertos 示例使用套接 API 我的問題是,在創(chuàng)建套接期間,它使用
    發(fā)表于 06-02 10:10

    Windows網(wǎng)絡(luò)編程的原始套接詳細說明

    利用“原始套接”(Raw Socket),我們可訪問位于基層的傳輸協(xié)議。本章專門講解如何運用這種原始套接,來模擬 IP的一些實用工具,比如 Tr a c e r o u t e和P
    發(fā)表于 03-21 08:00 ?1次下載
    Windows<b class='flag-5'>網(wǎng)絡(luò)</b>編程的原始<b class='flag-5'>套接</b><b class='flag-5'>字</b>詳細說明

    DN93-PCMCIA套接交換

    DN93-PCMCIA套接交換
    發(fā)表于 04-19 18:20 ?14次下載
    DN93-PCMCIA<b class='flag-5'>套接</b><b class='flag-5'>字</b>交換

    基于AT89C52單片機和LT8030實現(xiàn)套接規(guī)范的計算機通信設(shè)計

    網(wǎng)絡(luò)設(shè)置中有HTTP、SOCKET等類型。SOCKET是建立在傳輸層協(xié)議(主要是TCP和UDP)上的一種套接規(guī)范,它定義兩臺計算機間進行通信的規(guī)范(也是一種編程規(guī)范)。如果說兩臺計算機是利用一個
    的頭像 發(fā)表于 06-24 16:56 ?2383次閱讀
    基于AT89C52單片機和LT8030實現(xiàn)<b class='flag-5'>套接</b><b class='flag-5'>字</b>規(guī)范的計算機通信設(shè)計

    Socket套接的原理說明

    和連接,許多計算機操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了稱為套接 (Socket)的接口,區(qū)分不同應(yīng)用程序進程間的網(wǎng)絡(luò)通信和連接。 生成
    的頭像 發(fā)表于 06-18 19:16 ?1893次閱讀
    Socket<b class='flag-5'>套接</b><b class='flag-5'>字</b>的原理說明

    網(wǎng)絡(luò)系統(tǒng)調(diào)用網(wǎng)絡(luò)套接入口函數(shù)

    網(wǎng)絡(luò)套接入口函數(shù) //所有的網(wǎng)絡(luò)套接系統(tǒng)
    的頭像 發(fā)表于 07-24 11:02 ?490次閱讀

    套接socket包含哪些參數(shù)

    套接(Socket)是計算機網(wǎng)絡(luò)中最基本的通信抽象,它定義了兩個進程間通信的端點。在TCP/IP協(xié)議棧中,套接是實現(xiàn)
    的頭像 發(fā)表于 08-16 11:02 ?534次閱讀