一、Socket 框图
二、socket help
man socket
三、socket接口
int socket(int domain, int type, int protocol);
四、通信协议族(通信域)
/* Supported address families. */
#define AF_UNSPEC 0
#define AF_UNIX 1 /* Unix domain sockets */
#define AF_LOCAL 1 /* POSIX name for AF_UNIX */
#define AF_INET 2 /* Internet IP Protocol */
#define AF_AX25 3 /* Amateur Radio AX.25 */
#define AF_IPX 4 /* Novell IPX */
#define AF_APPLETALK 5 /* AppleTalk DDP */
#define AF_NETROM 6 /* Amateur Radio NET/ROM */
#define AF_BRIDGE 7 /* Multiprotocol bridge */
#define AF_ATMPVC 8 /* ATM PVCs */
#define AF_X25 9 /* Reserved for X.25 project */
#define AF_INET6 10 /* IP version 6 */
#define AF_ROSE 11 /* Amateur Radio X.25 PLP */
#define AF_DECnet 12 /* Reserved for DECnet project */
#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/
#define AF_SECURITY 14 /* Security callback pseudo AF */
#define AF_KEY 15 /* PF_KEY key management API */
#define AF_NETLINK 16
#define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */
#define AF_PACKET 17 /* Packet family */
#define AF_ASH 18 /* Ash */
#define AF_ECONET 19 /* Acorn Econet */
#define AF_ATMSVC 20 /* ATM SVCs */
#define AF_RDS 21 /* RDS sockets */
#define AF_SNA 22 /* Linux SNA Project (nutters!) */
#define AF_IRDA 23 /* IRDA sockets */
#define AF_PPPOX 24 /* PPPoX sockets */
#define AF_WANPIPE 25 /* Wanpipe API Sockets */
#define AF_LLC 26 /* Linux LLC */
#define AF_IB 27 /* Native InfiniBand address */
#define AF_MPLS 28 /* MPLS */
#define AF_CAN 29 /* Controller Area Network */
#define AF_TIPC 30 /* TIPC sockets */
#define AF_BLUETOOTH 31 /* Bluetooth sockets */
#define AF_IUCV 32 /* IUCV sockets */
#define AF_RXRPC 33 /* RxRPC sockets */
#define AF_ISDN 34 /* mISDN sockets */
#define AF_PHONET 35 /* Phonet sockets */
#define AF_IEEE802154 36 /* IEEE802154 sockets */
#define AF_CAIF 37 /* CAIF sockets */
#define AF_ALG 38 /* Algorithm sockets */
#define AF_NFC 39 /* NFC sockets */
#define AF_VSOCK 40 /* vSockets */
#define AF_MAX 41 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
#define PF_UNIX AF_UNIX
#define PF_LOCAL AF_LOCAL
#define PF_INET AF_INET
#define PF_AX25 AF_AX25
#define PF_IPX AF_IPX
#define PF_APPLETALK AF_APPLETALK
#define PF_NETROM AF_NETROM
#define PF_BRIDGE AF_BRIDGE
#define PF_ATMPVC AF_ATMPVC
#define PF_X25 AF_X25
#define PF_INET6 AF_INET6
#define PF_ROSE AF_ROSE
#define PF_DECnet AF_DECnet
#define PF_NETBEUI AF_NETBEUI
#define PF_SECURITY AF_SECURITY
#define PF_KEY AF_KEY
#define PF_NETLINK AF_NETLINK
#define PF_ROUTE AF_ROUTE
#define PF_PACKET AF_PACKET
#define PF_ASH AF_ASH
#define PF_ECONET AF_ECONET
#define PF_ATMSVC AF_ATMSVC
#define PF_RDS AF_RDS
#define PF_SNA AF_SNA
#define PF_IRDA AF_IRDA
#define PF_PPPOX AF_PPPOX
#define PF_WANPIPE AF_WANPIPE
#define PF_LLC AF_LLC
#define PF_IB AF_IB
#define PF_MPLS AF_MPLS
#define PF_CAN AF_CAN
#define PF_TIPC AF_TIPC
#define PF_BLUETOOTH AF_BLUETOOTH
#define PF_IUCV AF_IUCV
#define PF_RXRPC AF_RXRPC
#define PF_ISDN AF_ISDN
#define PF_PHONET AF_PHONET
#define PF_IEEE802154 AF_IEEE802154
#define PF_CAIF AF_CAIF
#define PF_ALG AF_ALG
#define PF_NFC AF_NFC
#define PF_VSOCK AF_VSOCK
#define PF_MAX AF_MAX
名字 | 描述 |
---|---|
AF_UNIX, AF_LOCAL | 本地通信 |
AF_INET | IPv4互联网协议 |
AF_INET6 | IPv6互联网协议 |
AF_IPX | IPX - Novell协议 |
AF_NETLINK | 内核用户接口设备 |
AF_X25 | ITU-T X.25 / ISO-8208协议 |
AF_AX25 | 业余无线电AX.25协议 |
AF_ATMPVC | 获取原始的ATM pvc |
AF_APPLETALK | Mac机所用的网络协议之一 |
AF_PACKET | 低级数据包接口 |
AF_ALG | 内核加密 API 接口 |
五、套接字类型
* enum sock_type - Socket types
* @SOCK_STREAM: stream (connection) socket
* @SOCK_DGRAM: datagram (conn.less) socket
* @SOCK_RAW: raw socket
* @SOCK_RDM: reliably-delivered message
* @SOCK_SEQPACKET: sequential packet socket
* @SOCK_DCCP: Datagram Congestion Control Protocol socket
* @SOCK_PACKET: linux specific way of getting packets at the dev level.
* For writing rarp and other similar things on the user level.
*
* When adding some new socket type please
* grep ARCH_HAS_SOCKET_TYPE include/asm-* /socket.h, at least MIPS
* overrides this enum for binary compat reasons.
*/
enum sock_type {
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
SOCK_DCCP = 6,
SOCK_PACKET = 10,
};
类型 | 描述 |
---|---|
SOCK_STREAM | 提供有序的、可靠的、双向的、基于连接的字节流。可以支持带外数据传输机制。 |
SOCK_DGRAM | 支持数据报(无连接、固定最大长度的不可靠消息)。 |
SOCK_SEQPACKET | 为固定最大长度的数据报提供有序、可靠、基于双向连接的数据传输路径; 用户需要在每次输入系统调用时读取整个数据包。 |
SOCK_RAW | 提供原始网络协议访问。 |
SOCK_RDM | 提供不保证排序的可靠数据报层。 |
SOCK_PACKET | 已过时 |
类型 | 描述 |
---|---|
SOCK_NONBLOCK | 在新打开的文档描述上设置O_NONBLOCK文档状态标志。 使用此标志可以节省对 fcntl(2) 的额外调用, 以达到相同的结果。 |
SOCK_CLOEXEC | 在新文档描述符上设置执行时关闭 (FD_CLOEXEC) 标志。 |
六、协议类型
/* Standard well-defined IP protocols. */
enum {
IPPROTO_IP = 0, /* Dummy protocol for TCP */
#define IPPROTO_IP IPPROTO_IP
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
#define IPPROTO_ICMP IPPROTO_ICMP
IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
#define IPPROTO_IGMP IPPROTO_IGMP
IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
#define IPPROTO_IPIP IPPROTO_IPIP
IPPROTO_TCP = 6, /* Transmission Control Protocol */
#define IPPROTO_TCP IPPROTO_TCP
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
#define IPPROTO_EGP IPPROTO_EGP
IPPROTO_PUP = 12, /* PUP protocol */
#define IPPROTO_PUP IPPROTO_PUP
IPPROTO_UDP = 17, /* User Datagram Protocol */
#define IPPROTO_UDP IPPROTO_UDP
IPPROTO_IDP = 22, /* XNS IDP protocol */
#define IPPROTO_IDP IPPROTO_IDP
IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
#define IPPROTO_TP IPPROTO_TP
IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
#define IPPROTO_DCCP IPPROTO_DCCP
IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
#define IPPROTO_IPV6 IPPROTO_IPV6
IPPROTO_RSVP = 46, /* RSVP Protocol */
#define IPPROTO_RSVP IPPROTO_RSVP
IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
#define IPPROTO_GRE IPPROTO_GRE
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
#define IPPROTO_ESP IPPROTO_ESP
IPPROTO_AH = 51, /* Authentication Header protocol */
#define IPPROTO_AH IPPROTO_AH
IPPROTO_MTP = 92, /* Multicast Transport Protocol */
#define IPPROTO_MTP IPPROTO_MTP
IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
#define IPPROTO_BEETPH IPPROTO_BEETPH
IPPROTO_ENCAP = 98, /* Encapsulation Header */
#define IPPROTO_ENCAP IPPROTO_ENCAP
IPPROTO_PIM = 103, /* Protocol Independent Multicast */
#define IPPROTO_PIM IPPROTO_PIM
IPPROTO_COMP = 108, /* Compression Header Protocol */
#define IPPROTO_COMP IPPROTO_COMP
IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
#define IPPROTO_SCTP IPPROTO_SCTP
IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
#define IPPROTO_UDPLITE IPPROTO_UDPLITE
IPPROTO_RAW = 255, /* Raw IP packets */
#define IPPROTO_RAW IPPROTO_RAW
IPPROTO_MAX
};
/*
* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
* and FCS/CRC (frame check sequence).
*/
#define ETH_ALEN 6 /* Octets in one ethernet addr */
#define ETH_HLEN 14 /* Total octets in header. */
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
#define ETH_DATA_LEN 1500 /* Max. octets in payload */
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
/*
* These are the defined Ethernet Protocol ID's.
*/
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_X25 0x0805 /* CCITT X.25 */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
#define ETH_P_LAT 0x6004 /* DEC LAT */
#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
#define ETH_P_CUST 0x6006 /* DEC Customer use */
#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
#define ETH_P_ATALK 0x809B /* Appletalk DDP */
#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
#define ETH_P_IPX 0x8137 /* IPX over DIX */
#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
* over Ethernet
*/
/*
* Non DIX types. Won't clash for 1500 types.
*/
#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
#define ETH_P_802_2 0x0004 /* 802.2 frames */
#define ETH_P_SNAP 0x0005 /* Internal only */
#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
#define ETH_P_ECONET 0x0018 /* Acorn Econet */
七、总结
AF_INET:能看到网络层数据。
AF_PACKET:能看到链路层数据。
AF_INET + SOCK_STREAM:获取基于TCP协议的应用层数据(不能获取TCP头部信息)。
AF_INET + SOCK_DGRAM:获取基于UDP协议的应用层数据(不能获取UDP头部信息)。
AF_INET + SOCK_RAW:获取基于IP协议的传输层数据(不能获取IP头部信息),获取IP头部信息需要开启IP_HDRINCL特性。
AF_PACKET + SOCK_DGRAM:获取基于链路层的网络层数据(不能获取链路层头部信息)。
AF_PACKET + SOCK_RAW:获取基于链路层的网络层数据(可以获取链路层头部信息)。
如果 raw socket 没有使用 connect 函数绑定对方地址时,则应使用 sendto 或 sendmsg 函数来发送数据包,在函数参数中指定对方地址。如果使用了 connect 函数,则可以直接使用 send、write 或 writev 函数来发送数据包。
如果 raw socket 调用了 bind 函数,则发送数据包的源 IP 地址将是 bind 函数指定的地址。否则,内核将以发接口的主 IP 地址填充;如果设置了 IP_HDRINCL 选项,则必须手工填充每个发送数据包的源 IP 地址。
八、网络层socket测试
1、main.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <string.h>
#include <stdlib.h>
#define BUF_LEN 1024
void print_data(char *buf,ssize_t len);
/*
* 特别说明:一下函数可以提取接收到的ICMP报文,但报文依旧会交给Linux内核网络协议栈处理,只是将接收的ICMP报文拷贝一份到当前程序
*/
int main(int argc, char* argv[])
{
int fd = 0;
struct sockaddr_in tmpin;
socklen_t teminlen = 0;
unsigned char buf[1024] = "";
ssize_t ret = 0;
// AF_INET:可以看到网络层数据
// SOCK_RAW:获取原始报文
// IPPROTO_ICMP:指定传输层协议(可以获得传输层协议报文头)
fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
// 循环接收数据
while(1){
memset(buf,0,BUF_LEN);
ret = recvfrom(fd,(void*)buf,BUF_LEN,0,(struct sockaddr*)&tmpin,&teminlen);
print_data(buf,ret);
}
return 0;
}
void print_data(char *buf,ssize_t len)
{
int i = 0;
for(i=0;i<len;i++){
printf("%02x ",(buf[i]&0xff));
}
printf("\r\n");
}
2、makefile
networkSocket: main.c
gcc main.c -o networkSocket
.PHONY : clean
clean:
rm -rf networkSocket
九、数据链路层socke测试
1、main.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define BUF_LEN 1024
void print_data(char *buf,ssize_t len);
/*
* 特别说明:一下函数可以提取接收到的ICMP报文,但报文依旧会交给Linux内核网络协议栈处理,只是将接收的ICMP报文拷贝一份到当前程序
*/
int main(int argc, char* argv[])
{
int fd = 0;
struct sockaddr_ll tmpin;
socklen_t teminlen = 0;
unsigned char buf[1024] = "";
ssize_t ret = 0;
// AF_PACKET:可以看到网络层数据
// SOCK_DGRAM:不获取报文头;SOCK_RAW:获取原始报文(包括报文头)
// ETH_P_ARP:指定协议类型
fd = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ARP));
// 循环接收数据
while(1){
memset(buf,0,BUF_LEN);
ret = recvfrom(fd,(void*)buf,BUF_LEN,0,(struct sockaddr*)&tmpin,&teminlen);
print_data(buf,ret);
}
return 0;
}
void print_data(char *buf,ssize_t len)
{
int i = 0;
for(i=0;i<len;i++){
printf("%02x ",(buf[i]&0xff));
}
printf("\r\n");
}
2、makefile
dataLinkSocket: main.c
gcc main.c -o dataLinkSocket
.PHONY : clean
clean:
rm -rf dataLinkSocket
十、库
1、libpcap
Unix/Linux平台下的网络数据包捕获函数库。它是一个独立于系统的用户层包捕获的API接口,为底层网络监测提供了一个可移植的框架。
libpcap提供的接口函数主要实现和封装了与数据包截获有关的过程。
2、libnet
libnet是一个小型的接口函数库,主要用C语言写成,提供了低层网络数据报的构造、处理和发送功能。
libnet提供的接口函数主要实现和封装了数据包的构造和发送过程。
3、libnids
libnids提供的接口函数主要实现了开发网络入侵监测系统所必须的一些结构框架。
4、libicmp
libicmp等相对较为简单,它封装的是ICMP数据包的主要处理过程构造、发送、接收等。