免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: yangchaohi
打印 上一主题 下一主题

关于Perl进行Socket编程 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-02-09 14:35 |只看该作者
这个跟我想要的效果不一样咯..我是想能够获取到内网其他机器的IP之类的,,通过本机网卡的数据应该不需要我ping一次才有啊...怎么样才能获取到内网数据信息呢~?

论坛徽章:
0
12 [报告]
发表于 2009-02-09 14:38 |只看该作者
原帖由 lin_wang 于 2009-2-9 14:31 发表
先前用过recv接收ICMP回应数据,但没反应,好象是recv不支持ICMP协议

原来是这个原因?那你用什么办法获取数据的呢?

论坛徽章:
0
13 [报告]
发表于 2009-02-09 14:44 |只看该作者
用C实现的一个sniffer,我看到里面的代码是用recv函数的..我再去具体看下里面代码怎么实现的..如果C能用的话..PERL里应该也能用的吧..

论坛徽章:
0
14 [报告]
发表于 2009-02-09 15:06 |只看该作者
原帖由 yangchaohi 于 2009-2-9 14:44 发表
用C实现的一个sniffer,我看到里面的代码是用recv函数的..我再去具体看下里面代码怎么实现的..如果C能用的话..PERL里应该也能用的吧..



我也不解,把C代码那部分贴出来看看吧

论坛徽章:
0
15 [报告]
发表于 2009-02-09 15:07 |只看该作者
原帖由 yangchaohi 于 2009-2-9 14:38 发表

原来是这个原因?那你用什么办法获取数据的呢?




我用的笨方法,用Net:cap获取ICMP数据包

论坛徽章:
0
16 [报告]
发表于 2009-02-09 15:16 |只看该作者
C的代码很多哦...哈哈...

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <Winsock2.h>
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
//#include <mstcpip.h>
//#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")

#define STATUS_FAILED 0xFFFF
#define MAX_PACK_LEN 65535
#define MAX_ADDR_LEN 16
#define MAX_PROTO_TEXT_LEN 16
#define MAX_PROTO_NUM 12
#define MAX_HOSTNAME_LAN 255
#define CMD_PARAM_HELP true

typedef struct _iphdr
{
        unsigned char h_lenver;
        unsigned char tos;
        unsigned short total_len;
        unsigned short ident;
        unsigned short frag_and_flags;
        unsigned char ttl;
        unsigned char proto;
        unsigned short checksum;
        unsigned int sourceIP;
        unsigned int destIP;
}IP_HEADER;

typedef struct _tcphdr
{
        USHORT th_sport;
        USHORT th_dport;
        unsigned int th_seq;
        unsigned int th_ack;
        unsigned char th_lenres;
        unsigned char th_flag;
        USHORT th_win;
        USHORT th_sum;
        USHORT th_urp;
}TCP_HEADER;

typedef struct _udphdr
{
        unsigned short uh_sport;
        unsigned short uh_dport;
        unsigned short uh_len;
        unsigned short uh_sum;
}UDP_HEADER;

typedef struct _icmphdr
{
        BYTE i_type;
        BYTE i_code;
        USHORT i_cksum;
        USHORT i_id;
        USHORT i_seq;
        ULONG timestamp;
}ICMP_HEADER;

typedef struct _protomap
{
        int ProtoNum;
        char ProtoText[MAX_PROTO_TEXT_LEN];
}PROTOMAP;

PROTOMAP ProtoMap[MAX_PROTO_NUM]={
        {IPPROTO_IP,"IP "},
        {IPPROTO_ICMP,"ICMP"},
        {IPPROTO_IGMP,"IGMP"},
        {IPPROTO_GGP,"GGP"},
        {IPPROTO_TCP,"TCP"},
        {IPPROTO_PUP,"PUP"},
        {IPPROTO_UDP,"UDP"},
        {IPPROTO_IDP,"IDP"},
        {IPPROTO_ND,"ND "},
        {IPPROTO_RAW,"RAW"},
        {IPPROTO_MAX,"MAX"},
        {NULL,""}};
       
        SOCKET SockRaw;
        char TcpFlag[6]={'F','R','S','P','A','U'};
        bool ParamTcp =false;
        bool ParamUdp =false;
        bool ParamIcmp =false;
        bool ParamDecode =false;
        char *strFromIpFilter=NULL;
        char *strDestIpFilter=NULL;
        char *strSensitive=NULL;
        int iPortFilter=0;
        int iProtocol,iTTL;
        char szProtocol[MAX_PROTO_TEXT_LEN];
        char szSourceIP[MAX_ADDR_LEN],szDestIP[MAX_ADDR_LEN];
        int DecodeIpPack(char *,int);
        int DecodeTcpPack(char *,int);
        int DecodeUdpPack(char *,int);
        int DecodeIcmpPack(char *,int);
        void CheckSockError(int,char *);
        char *CheckProtocol(int);
        void usage(void);
        bool GetCmdLine(int,char **);
       
       
        int DecodeTcpPack(char *TcpBuf,int iBufSize)
        {
                TCP_HEADER *pTcpHeader;
                int i;
                int iSourcePort,iDestPort;
                pTcpHeader=(TCP_HEADER *)TcpBuf;
                int TcpHeaderLen =pTcpHeader->th_lenres>>4;
                TcpHeaderLen *=sizeof(unsigned long);
                char *TcpData=TcpBuf+TcpHeaderLen;
                if(strSensitive)
                        if((strstr(TcpData,strSensitive))==NULL)return true;
                        iSourcePort=ntohs(pTcpHeader->th_sport);
                        iDestPort=ntohs(pTcpHeader->th_dport);
                        if((iPortFilter)&&(iSourcePort!=iPortFilter)&&(iDestPort!=iPortFilter))
                                return true;
                        printf("%s",szProtocol);
                        printf("%15s:%d->%15s:%5d ",szSourceIP,iSourcePort,szDestIP,iDestPort);
                        printf("TTL=%3d  ",iTTL);
                        //判断TCP标志位
                       
                       
                        unsigned char FlagMask=1;
                        for(i=0;i<6;i++)
                        {
                                if((pTcpHeader->th_flag)&FlagMask)printf("%c",TcpFlag[i]);
                                else printf("-");
                                FlagMask=FlagMask<<1;
                        }
                        printf("bytes=%4d",iBufSize);
                        printf("\n");
                        //对于长度大雨40字节的包进行数据分析(IP_HEADER+TCP_HEADER=40)
                        {
                                //分析TCP数据段
                                if((!strSensitive)||(strstr(TcpData,strSensitive)))
                                {
                                        printf("[DATA]\n");
                                        printf("%s",TcpData);
                                        printf("\n[DATA END]\n\n\n");
                                }
                        }
                        return true;
        }
        //////////////////////////////////////////////////udp协议头分析函数
        int DecodeUdpPack(char*UdpBuf,int iBufSize)
        {
                UDP_HEADER *pUdpHeader;
                pUdpHeader=(UDP_HEADER*)UdpBuf;
                int iSourcePort=ntohs(pUdpHeader->uh_sport);
                int iDestPort=ntohs(pUdpHeader->uh_dport);
                //对端口进行过滤
                if(iPortFilter)
                        if((iSourcePort!=iPortFilter)&&(iDestPort!=iPortFilter))
                                return true;
                        printf("%s",szProtocol);
                        printf("%15s:%5d->%15s:%5d ",szSourceIP,iSourcePort,szDestIP,iDestPort);
                        printf("TTL=%3d  ",iTTL);
                        printf("Len=%4d  ",ntohs(pUdpHeader->uh_len));
                        printf("bytes=%4d",iBufSize);
                        printf("\n");
                       
                       
                        if((ParamDecode)&&(iBufSize>28))
                        {
                                printf("[DATA]\n");                       
                                char *UdpData=UdpBuf+8;                //UDP首部长度为8
                                //分析UDP数据报
                                for(unsigned int i=0;i<(iBufSize-sizeof(UDP_HEADER));i++)
                                {
                                        if(!(i%8))
                                                printf("\n");
                                        if((UdpData[i]>33)&&(UdpData[i]<122))
                                                printf("%3c[%3x]",UdpData[i],UdpData[i]);
                                        else
                                                printf("  [%3x]",abs(UdpData[i]));
                                }
                                printf("\n[DATA END]\n\n\n");
                        }
                        return true;
        }
        ////////////////ICMP协议头分析函数
        int DecodeIcmpPack(char *IcmpBuf,int iBufSize)
        {
                ICMP_HEADER *pIcmpHeader;
                pIcmpHeader=(ICMP_HEADER*)IcmpBuf;
                int iIcmpType=pIcmpHeader->i_type;
                int iIcmpCode=pIcmpHeader->i_code;
                if((iPortFilter)&&(iIcmpType!=iPortFilter))
                        return true;
                printf("%s",szProtocol);
                //printf("%15s Type %sd->%15s Code %d ",szSourceIP,iIcmpType,szDestIP,iIcmpCode);
                printf("%15s  ->%15s    ",szSourceIP,szDestIP);
                printf("TTL=%3d   ",iTTL);
                printf("Type%2d,%d   ",iIcmpType,iIcmpCode);
                printf("bytes=%4d",iBufSize);
                printf("\n");
                if((ParamDecode)&&(iBufSize>28))
                {
                        char *IcmpData=IcmpBuf+4;
                       
                        printf("[DATA]");
                        for(unsigned int i=0;i<(iBufSize-sizeof(ICMP_HEADER));i++)
                        {
                                if(!(i%8))printf("\n");
                                if((IcmpData[i]>33)&&(IcmpData[i]<122))
                                        printf("%3c[%3x]",IcmpData[i],IcmpData[i]);
                                else printf("   [%3x]",abs(IcmpData[i]));
                        }
                        printf("\n[DATA END]\n\n\n");
                }
                return true;
        }
        ////////////////////////////////////////////////////IP协议头分析函数
        int DecodeIpPack(char *buf,int iBufSize)
        {
                IP_HEADER *pIpheader;
                SOCKADDR_IN saSource,saDest;
                pIpheader=(IP_HEADER *)buf;
                //协议甄别
                iProtocol=pIpheader->proto;
                strncpy(szProtocol,CheckProtocol(iProtocol),MAX_PROTO_TEXT_LEN);
                if((iProtocol==IPPROTO_TCP)&&(!ParamTcp))return true;
                if((iProtocol==IPPROTO_UDP)&&(!ParamTcp))return true;
                if((iProtocol==IPPROTO_ICMP)&&(!ParamTcp))return true;
                //源地址
                saSource.sin_addr.s_addr=pIpheader->sourceIP;
                strncpy(szSourceIP,inet_ntoa(saSource.sin_addr),MAX_ADDR_LEN);
       
                if(strFromIpFilter)
                        if(strcmp(strFromIpFilter,szSourceIP))return true;
                        //目的地址
                        saDest.sin_addr.s_addr=pIpheader->destIP;
                        strncpy(szDestIP,inet_ntoa(saDest.sin_addr),MAX_ADDR_LEN);
                        if(strDestIpFilter)
                                if(strcmp(strDestIpFilter,szDestIP))return true;
                                iTTL=pIpheader->ttl;
                                //计算IP首部的长度
                                int iIphLen=sizeof(unsigned long)*(pIpheader->h_lenver&0xf);
                                //根据协议类型分别调用相应的函数
                                switch(iProtocol)
                                {
                                case IPPROTO_TCP :DecodeTcpPack(buf+iIphLen,iBufSize);break;
                                case IPPROTO_UDP :DecodeUdpPack(buf+iIphLen,iBufSize);break;
                                case IPPROTO_ICMP :DecodeIcmpPack(buf+iIphLen,iBufSize);break;
                                default                          :break;
                                }
                                //printf("\n");
                                return true;
        }
        //////////////////////////////协议识别函数
        char *CheckProtocol(int iProtocol)
        {
                for(int i=0;i<MAX_PROTO_NUM;i++)
                        if(ProtoMap[i].ProtoNum==iProtocol)
                                return ProtoMap[i].ProtoText;
                        return "";
        }
        //////最后,编写程序主题部分。......................
        //命令行参数处理
        bool GetCmdLine(int argc,char **argv)
        {
                if(argc<2)return CMD_PARAM_HELP;
                for(int i=1;i<argc;i++)
                {
                        if(argv[i][0]!='/')return CMD_PARAM_HELP;
                        else switch(argv[i][1])
                        {
                        case 't':
                        case 'T':ParamTcp=true;break;
                        case 'u':
                        case 'U':ParamUdp=true;break;
                        case 'i':
                        case 'I':ParamIcmp=true;break;
                        case 'p':
                        case 'P':ParamDecode=true;break;
                        case 'f':
                        case 'F':
                                {
                                        strFromIpFilter=(char*)malloc(16*sizeof(char));
                                        memset(strFromIpFilter,0,16*sizeof(char));
                                        strcpy(strFromIpFilter,argv[i]+3);
                                        break;
                                }
                        case 'd':
                        case 'D':
                                {
                                        strDestIpFilter=(char*)malloc(16*sizeof(char));
                                        memset(strDestIpFilter,0,16*sizeof(char));
                                        strcpy(strDestIpFilter,argv[i]+3);
                                        break;
                                }
                        case 's':
                        case 'S':
                                {
                                        strSensitive=(char*)malloc(255*sizeof(char));
                                        memset(strSensitive,0,255*sizeof(char));
                                        strcpy(strSensitive,argv[i]+3);
                                        break;
                                }
                        case 'o':
                        case 'O':
                                {
                                        iPortFilter=atoi(argv[i]+3);
                                        break;
                                }
                        }
                }
                printf("\nWill Sniffer");
                if(ParamTcp)printf("TCP");
                if(ParamUdp)printf("UDP");
                if(ParamIcmp)printf("ICMP");
                if(strFromIpFilter)
                        printf("FromIp:%s",strFromIpFilter);
                if(strDestIpFilter)
                        printf("DestIp:%s",strDestIpFilter);
                if(ParamDecode)
                        printf("DECODE ON");
                if(strSensitive)
                        printf("Sensitive String:%s",strSensitive);
                printf("\n\tCTRL+C to quit\nStart:\n");
                return(!CMD_PARAM_HELP);
        }
        //使用说明
       
        void usage(void)
        {
                //printf("GUNiffer\n");
                //printf("\tSinffer for Win2K By Shotgun(Ver 0.3)\n");
                //printf("\tShotgun@Xici.net\n");
                //printf("\thttp://It.Xici.Net\n");
                //printf("\thttp://www.Patching.Net\n\n");
                printf("USAGE:\n");
                printf("\t/t                        Output TCP Packets\n");
                printf("\t/u                        Output TCP Packets\n");
                printf("\t/i                        Output ICMP Packets\n");
                printf("\t/p                        Decode Packets(default OFF)\n");
                printf("\t/f:fromIP                Output Packets FromIp=fromIP(default ALL)\n");
                printf("\t/d:destIP                Output Packets DestIp=destIP(default ALL)\n");
                printf("\t/s:string                Output Packets Include sensitive String(TCP only)\n");
                printf("\t/o:port                Output Packets from or to the port(ICMP is TYPE)\n");
                printf("Example:\n");
                printf("\tGUNiffer.exe/d>GUNiffer.log\n");
                printf("\tGUNiffer.exe /t/u/f:192.168.15.231\n");
                printf("\tGUNiffer.exe/t/p/s:PASS\n");
        }
        //SOCK错误处理程序
        void CheckSockError(int iErrorCode,char *pErrorMsg)
        {
                if(iErrorCode==SOCKET_ERROR)
                {
                        printf("%s Error:%d\n",pErrorMsg,GetLastError());
                        closesocket(SockRaw);
                        exit(0);
                }
        }
        void main(int argc,char **argv)//主函数
        {
                int iErrorCode;
                char RecvBuf[MAX_PACK_LEN]={0};
                usage();
                if(GetCmdLine(argc,argv)==CMD_PARAM_HELP)
                        exit(0);
                //初始化SOCKET
                WSADATA wsaData;
                iErrorCode=WSAStartup(MAKEWORD(2,2),&wsaData);
                CheckSockError(iErrorCode,"WSAStartup");
                SockRaw=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
                CheckSockError(SockRaw,"socket");
                //获取本机IP地址
                char /*FAR*/ name[MAX_HOSTNAME_LAN];
                iErrorCode=gethostname(name,MAX_HOSTNAME_LAN);
                CheckSockError(iErrorCode,"gethostname");
                struct hostent FAR *pHostent;
                pHostent=(struct hostent*)malloc(sizeof(struct hostent));
                pHostent=gethostbyname(name);
                SOCKADDR_IN sa;
                sa.sin_family=AF_INET;
                sa.sin_port=htons(6000);
                memcpy(&sa.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length);
//                free(pHostent);
                //将套接字与本机6000端口绑定
                iErrorCode=bind(SockRaw,(PSOCKADDR)&sa,sizeof(sa));
                CheckSockError(iErrorCode,"bind");
                //设置SOCK_RAW为SIQ_RCVALL,以便接收所有的IP包
                DWORD dwBufferLen[10];
                DWORD dwBufferInLen=1;
                DWORD dwBytesReturned=0;
                iErrorCode=WSAIoctl(SockRaw,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
                CheckSockError(iErrorCode,"Ioctl");
                //侦听IP报文
                while(1)
                {
                        memset(RecvBuf ,0,sizeof(RecvBuf));
                        iErrorCode=recv(SockRaw,RecvBuf,sizeof(RecvBuf),0);// 截获数举包
                        CheckSockError(iErrorCode,"recv");
                        iErrorCode=DecodeIpPack(RecvBuf,iErrorCode);
                        CheckSockError(iErrorCode,"Decode");
                }
        }

论坛徽章:
0
17 [报告]
发表于 2009-02-09 15:19 |只看该作者
[quote]原帖由 [i]lin_wang[/i] 于 2009-2-9 15:07 发表 [url=http://bbs3.chinaunix.net/redirect.php?goto=findpost&pid=10033108&ptid=1365841][img]http://bbs3.chinaunix.net/images/common/back.gif[/img][/url]



:em17:
我用的笨方法,用Net::Pcap获取ICMP数据包 [/quote]



能不能把你实现的代码发出来看下咯....我来学习一下....

论坛徽章:
0
18 [报告]
发表于 2009-02-09 17:33 |只看该作者

抱歉,商业应用的代码

你可以看看CPAN

论坛徽章:
0
19 [报告]
发表于 2009-02-10 08:10 |只看该作者
原帖由 lin_wang 于 2009-2-9 17:33 发表

抱歉,商业应用的代码

你可以看看CPAN

汗你~~....好的好的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP