int socket(int domain, int type, int protocol);
socket系统调用为什么能建立那么多种socket
小记
domain | type | protocol | 描述 | 应用层操作收发buff | 源/目的 |
---|---|---|---|---|---|
AF_INET | SOCK_DGRAM | IPPROTO_UDP | UDP收发socket | UDP荷载开始 | 荷载从IP头后面开始的socket, |
– | – | 0 | 收:所有IP包;发:? | IP荷载开始 | 用sockaddr_in绑定IP |
– | SOCK_STREAM | IPPROTO_TCP/0 | TCP收发socket | TCP荷载 | 荷载从UDP/TCP头后面开始的socket, |
– | SOCK_RAW | IPPROTO_IGMP等 | 收发IP层的对应协议包/ | IP头开始 | 还要绑定port |
– | – | IPPROTO_TCP | 只能发;不能收 | IP头开始 | |
PF_PACKET | SOCK_DGRAM | ETH_P_IP等 | 链路层对应协议 | ETH荷载开始 | 收包绑端口 |
– | – | ETH_P_ALL | 收发所有协议 | – | 发包绑sll地址 |
– | SOCK_RAW | ETH_P_ARP | 链路层对应协议 | ETH头开始 | |
– | – | ETH_P_ALL | 收发所有协议 |
接收实例
1.dhcps收发往本机的(广播/本机IP)特定端口的udp
- socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
- bind sockaddr_in
.sin_family = AF_INET;
.sin_port = htons(Port); 指定port
.sin_addr.s_addr = htonl(IPAddr); alladdr - setsockopt( SO_BROADCAST/SO_BINDTODEVICE)
允许发送广播包/指定设备 - 接收buff—UDP荷载数据
2.接收任意IP包
- socket(AF_INET, SOCK_DGRAM, 0)
- buff为 ip后的协议部分,且校验和应用自己完成
3.dhcpc 收offer(dmac广播地址)
- socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
- bind((struct sockaddr*))
sockaddr_ll
->sll_family = AF_PACKET;
->sll_protocol = htons(ETH_P_IP);
->sll_ifindex = index; //绑设备
->sll_halen = MAC_LEN;
->sll_addr //这个应该管发送
->sll_pkttype PACK_HOST包地址为本地主机地址。
PACK_BROADCAST物理层广播包。 - 接收buff从ip荷载开始
4.igmprouter socket 收组播包
- socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
- buff从ip头开始
5.收arp
- socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ARP))
- bind sockaddr_ll
.sll_family = PF_PACKET;
.sll_protocol=htons(ETH_P_ARP);
.sll_hatype=ARPHRD_ETHER;
.sll_pkttype=PACKET_HOST;
.sll_halen=ETH_ALEN;
.sll_addr srcmac - 接收的buf从eth头开始,smac,dmac…
发送实例
1.dhcpc bond状态发续租
-
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
bind sockaddr_in 本机
->sin_family = AF_INET;
->sin_addr.s_addr = htonl(ip);
->sin_port = htons(port); -
connect/sendto 目的sockaddr_in
-
发送buff为 UDP负载开始
- socket (AF_INET, SOCK_RAW, IPPROTO_TCP) 不能收包
- socket(AF_INET,SOCK_RAW,IPPROTO_TCP))
- 开启IP_HDRINCL
- 发送buff为 从ip头开始
3.dhcpc 发disc
- socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
- bind sockaddr_ll
->sll_family = AF_PACKET;
->sll_protocol = htons(ETH_P_IP); mac下一层用ip
->sll_ifindex = index //这个应该管接收
->sll_halen = MAC_LEN;
->sll_addr //源mac/广播mac - sendto指定 目的mac地址 ->sll_addr
- 发送buff为从ip的头开始 组装ip头/UDP协议头/UDP负载
4.dhcps发offer dmac广播
- socket(PF_PACKET, SOCK_DGRAM, ETH_P_IP))
- bind(struct sockaddr*)
sockaddr_ll
.sll_family = AF_PACKET;
.sll_protocol = htons(ETH_P_IP);
.sll_ifindex = htonl(index);
.sll_halen = 6; - sendto( .sll_addr=dmac)
- 从ip头开始组装 sip dip ipprot…
5.发arp
- socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))
- sendto(struct sockaddr)
.sll_ifindex 指定接口就行了/和组装的要对应 - buff从eth头开始 组装dmac smac ethprot。。。。
6.发arp2
- socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))
- sendto(struct sockaddr)
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ARP);
addr.sll_ifindex = ifdex; //这个应该管收
addr.sll_halen = MAC_LEN;
addr.sll_addr=macAddr - buff从eth开始组装
7.igmp interface socket 发query等
- socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
- sendto(sockaddr_in(dip))
- buff从ip荷载 igmp协议头开始
unix域socket收发
- socket(AF_UNIX, SOCK_DGRAM, 0);
- bind(sockaddr_un.sun_path)管收
- sendto(sockaddr_un.sun_path)管发