|
下面的程序本意是我想截获TCP3次握手的第一个报文,程序逻辑应该没有什么问题,因为我在windows下已经实现了。但在linux下怎么也截不到,而且网卡的混杂工作方式也设置成功了,但就是进不了Decode函数,当客户端连接请求(connect)之后,本服务器端直接到了NodeAccept,为什么?请高手赐教!谢谢!
#include "iptest.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
typedef unsigned int DWORD;
typedef unsigned short UINT;
typedef unsigned char UCHAR;
fd_set Recvmsk,Tmpmsk;
char ctrl=0;
void Decode(SOCKET s,char *tos,char *offset);
void NodeAccept(SOCKET s,SOCKET *sock);
void Recvdata(SOCKET s);
unsigned long GetLocalIP();
int WSAGetLastError();
void closesocket(SOCKET s);
void Set_Promisc(char *interface,SOCKET s);
void Set_unpromisc(char *interface,SOCKET s);
int WSAGetLastError()
{
return errno;
}
void closesocket(SOCKET s)
{
close(s);
}
void Set_Promisc(char *interface,SOCKET s)
{
struct ifreq ifr;
strncpy(ifr.ifr_name,interface,strlen(interface)+1);
if(ioctl(s,SIOCGIFFLAGS, &ifr)== -1)
{
printf("Retrive interface %s flag error.\n",ifr.ifr_name);
return;
}
else
{
ifr.ifr_flags |= IFF_PROMISC;
if(ioctl(s,SIOCSIFFLAGS,&ifr)== -1)
{
printf("Set interface %s flag error.\n",ifr.ifr_name);
return;
}
}
}
void Set_unpromisc(char *interface,SOCKET s)
{
struct ifreq ifr;
strncpy(ifr.ifr_name,interface,strlen(interface)+1);
if (ioctl(s,SIOCGIFFLAGS,&ifr)== -1)
{
printf("Retrive interface %s flags error.\n",ifr.ifr_name);
return;
}
ifr.ifr_flags |= ~IFF_PROMISC;
if(ioctl(s,SIOCSIFFLAGS,&ifr)== -1)
{
printf("Set interface error.\n");
return;
}
}
int main()
{
DWORD sockopt;
int Ret,CtrlFlag=1;
struct sockaddr_in addr;
struct timeval tWait;
char Tos=0,Offset=0;
memset(&addr,0,sizeof(struct sockaddr_in));
rawsock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
if (rawsock == -1)
{
Ret= WSAGetLastError();
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = INADDR_ANY;
addr.sin_addr.s_addr = GetLocalIP();
Ret = bind(rawsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in));
if (Ret < 0)
{
Ret= WSAGetLastError();
return -1;
}
sockopt = 1;
if (setsockopt(rawsock,SOL_SOCKET,SO_REUSEADDR,(char *)&sockopt,sizeof(sockopt)))
{
Ret= WSAGetLastError();
return -1;
}
FD_SET(rawsock,&Recvmsk);
Set_Promisc("eth0",rawsock);
lsnsock = socket(AF_INET,SOCK_STREAM,0);
if (lsnsock == -1)
{
Ret= WSAGetLastError();
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(6677);
addr.sin_addr.s_addr = GetLocalIP();
if (bind(lsnsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)))
{
Ret= WSAGetLastError();
/* Set_unpromisc("eth0",rawsock);*/
return -1;
}
FD_SET(lsnsock,&Recvmsk);
listen(lsnsock,5);
while (CtrlFlag)
{
memcpy(&Tmpmsk,&Recvmsk,sizeof(Recvmsk));
tWait.tv_sec = 5;
tWait.tv_usec = 0;
Ret = select(8,(fd_set *)&Tmpmsk,NULL,NULL,&tWait);
if (Ret > 0)
{
if (FD_ISSET(rawsock,&Tmpmsk))
{
Decode(rawsock,&Tos,&Offset);
if (ctrl == 1)
{
printf("TOS is %d\n",Tos);
ctrl =0;
}
}
if (FD_ISSET(lsnsock,&Tmpmsk))
{
NodeAccept(lsnsock,&datasock);
}
if (FD_ISSET(datasock,&Tmpmsk))
{
Recvdata(datasock);
}
}
}
Set_unpromisc("eth0",rawsock);
return 0;
}
void Decode(SOCKET s,char *Tos,char *offset)
{
int Recvlen;
PIP_HEADER pIPHeader = NULL;
PTCP_HEADER pTCPHeader = NULL;
unsigned short shortval;
Recvlen = recv(s,(char *)&TosBuffer,sizeof(TosBuffer),0);
if (Recvlen <= 0)
return;
else if (Recvlen < MIN_PACK)
{
*offset+=Recvlen;
return;
}
*offset = 0;
pIPHeader = (PIP_HEADER)TosBuffer;
if (*((char *)pIPHeader+9) != IPPROTO_TCP)
return;
pTCPHeader = (PTCP_HEADER)(TosBuffer + sizeof(IP_HEADER));
memcpy(&shortval,((char *)pTCPHeader +12),2);
shortval=ntohs(shortval)&0x3f;
if ((shortval&0x2) == 2)
{
*Tos = *((char *)pIPHeader+1)&0x0f;
memset(&TosBuffer,0,sizeof(TosBuffer));
/* ctrl =1;*/
return;
}
else
{
memset((char *)&TosBuffer,0,sizeof(TosBuffer));
return;
}
}
void NodeAccept(SOCKET s,SOCKET *sock)
{
SOCKET acpsock;
int Ret;
acpsock =accept(s,NULL,0);
if (acpsock <0)
{
Ret = WSAGetLastError();
return;
}
*sock = acpsock;
FD_SET(*sock,&Recvmsk);
return;
}
void Recvdata(SOCKET s)
{
int Ret,len;
char Buffer[64];
len = recv(s,(char *)&Buffer,sizeof(Buffer),0);
if (len <= 0)
{
Ret= WSAGetLastError();
FD_CLR(s,&Recvmsk);
closesocket(s);
return;
}
else
{
printf("%s\n",Buffer);
return;
}
}
unsigned long GetLocalIP()
{
return inet_addr("10.40.48.66");
} |
|