socket的精妙之处在于协议族的横向转换和地址族的纵向转换.我们也可在更底层实现对流经host的数据流的监督和修改.尤其是监察数据,十分简单.
这里是混杂模式实现对ip数据流的监察与对tcp数据流的简单查看,需要root权限.这里忽略了tcp/ip的options选项.进一步感兴趣的同学可以查看wareshark的源码实现.
尊重原创,转载的同学,一定要注明来自DNA出处哦!
#pragma once
#ifdef __linux__
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>
#include <unistd.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <sys/ioctl.h>
#include <alloca.h>
#endif
#define false 0
#define true 1
#define ETH_ALEN 6
#define isHumanized 0
#pragma pack(1)
//链路层MAC头部部分
struct ethHeader
{
unsigned char dst[6];//目的mac地址
unsigned char src[6];//源mac地址
unsigned short protocol;//上层(网络层)协议
};
struct ipHeader
{
unsigned char headerLen : 4;//0x45 0100 0101
unsigned char version :4;
unsigned char toservice:8;
unsigned short ipLen:16;
unsigned short sequence:16;
unsigned short segmentflag:16;
unsigned char time2live:8;
unsigned char protocol:8;
unsigned short checksum:16;
unsigned long sorceIp:32;
unsigned long destIp:32;
//unsigned char options[];
};
#ifdef BIGEND
//大端对齐的方式没试过,姑且按tcp表排序.
struct tcpHeader
{
unsigned short sorcePort:16;
unsigned short destPort:16;
unsigned long sequence:32;
unsigned long ack_seq:32;
unsigned char headerLen:4;
unsigned char residuum:6;
unsigned char urgent:1;
unsigned char acknowledge:1;
unsigned char push:1;
unsigned char reset:1;
unsigned char synchronize:1;
unsigned char final:1;
unsigned short window:16;
unsigned short checksum:16;
unsigned short urgentPoint:16;
unsigned char options[];
};
#else
struct tcpHeader
{
unsigned short sorcePort : 16;
unsigned short destPort : 16;
unsigned long sequence : 32;
unsigned long ack_seq : 32;
//网络:0100 ---- --00 0010
//主机:--00 0010 0100.
unsigned char residuum1 : 4; //----
unsigned char headerLen : 4; //0100
unsigned char final : 1; //0
unsigned char synchronize : 1; //1
unsigned char reset : 1; //0
unsigned char push : 1; //0
unsigned char acknowledge : 1; //0
unsigned char urgent : 1; //0
unsigned char residuum2 : 2; //--
unsigned short window : 16;
unsigned short checksum : 16;
unsigned short urgentPoint : 16;
unsigned char options[];
};
#endif
#pragma pack()
extern unsigned char print(unsigned char *buff,int len);
extern void printMyInfo(void);
struct ifreq ifstruct;
//网络字节序/大端对齐则true 小端对齐则false0x1234 低地址0x34-->高地址0x12
void testEnd()
{
union test_end
{
unsigned int get1;
unsigned char is1;
};
union test_end t;
t.get1 = 1;
if (t.is1)
{
printf("is1是低地址,在低位得到1,因此是小端对齐\n");
}
else
{
printf("is1是低地址,在低位没得1,因此是大端对齐\n");
}
}
int main(int argc,char *argv[])
{
//int socket(int domain,int type, int protocol)
//dom