LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 735|回复: 0

高手请进(关于raw socket编程问题的请教)

[复制链接]
发表于 2003-12-23 16:44:34 | 显示全部楼层 |阅读模式
下面的程序本意是我想截获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");
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表