吵吵   2011-09-09  阅读:3,615

记得当初能够开始写802.1x的港湾登陆器纯粹是因为loser自己改好了pcap.pas,所以我才能继续的把pcap的代码写下去。最近继续研究delphi和winpcap是因为现在rad平台是做的越来越漂亮了,其实用delphi的控件等等来做我们的界面,而用vc来写我们的主要功能模块不失为一个好的办法。

但是虽然delphi简单快速,可是我还是费了不少时间的,在vc中你很少去处理错误类,而在delphi中try expect 这些错误捕获的代码很多很多,从简单的理解来看,我认为是指针的多次释放,或者销毁对象的多次销毁而引起的,但是不管怎么说,原来我写了这个登陆器的时候,他还是不稳定的,所以虽然引起轰动,但是很快就没了,最后不得已而转向vc开发。
winpcap的几个函数相信你已经知道了,pcap.pas在我的博客中也找的到代码,那么剩下的就自己看看学学吧:

procedure recvThread(myconfig:pconfigini);stdcall;
const
cStartPacket:array[0..63] of Byte=($01, $80, $c2, $00, $00, $03,
                                             $ff, $ff, $ff, $ff, $ff, $ff,
                                             $88, $8e, $01, $01, $00, $00,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5);
cuserPacket :array[0..63] of Byte = ($01, $80, $c2, $00, $00, $03,
                                             $ff, $ff, $ff, $ff, $ff, $ff,
                                             $88, $8e, $01, $00, $00, $ff,
                                             $02, $01, $00, $ff, $01, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5);
cResponseMD5       :array[0..63] of Byte = ($01, $80, $c2, $00, $00, $03,
                                             $ff, $ff, $ff, $ff, $ff, $ff,
                                             $88, $8e, $01, $00, $00, $ff,
                                             $02, $02, $00, $ff, $04, $10,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5);
cLogoffPacket      :array[0..63] of Byte = ($01, $80, $c2, $00, $00, $03,
                                             $ff, $ff, $ff, $ff, $ff, $ff,
                                             $88, $8e, $01, $02, $00, $00,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5, $a5, $a5,
                                             $a5, $a5, $a5, $a5);
var
outnetbyte,innetbyte:int64;
StartPacket,userPacket,ResponseMD5,LogoffPacket:array[0..63] of Byte;
szMd5Buffer: Md5Buffer;
nLen: Integer;
md5Ctx: MD5Context;
md5Dig: MD5Digest;
mmcount:string;
pcap:ppcap;
mac:TMacAddr;//物理网卡地址
user:string;
ErrStr:string;
errbuf:array[0..PCAP_ERRBUF_SIZE] of Char;
userlength,i:integer;
buftoint : array[0..3] of byte;
bufint:integer;
headlen2:integer;
pRecvBuf :array of Byte;
pRecvHeaderBuf :ppcap_pkthdr;
q_MD5Source:array[0..15] of byte;
f:TextFile;
textstring:string;
begin
  assignfile(f,'test.txt');

  for i:=0 to 63 do
  begin
  StartPacket[i]:=cStartPacket[i];
  userPacket[i]:=cuserPacket[i];
  ResponseMD5[i]:=cResponseMD5[i];
  LogoffPacket[i]:=cLogoffPacket[i];
  end;
  buftoint[2]:=0;
  buftoint[3]:=0;
  try
    pcap := pcap_open_live(PChar(myconfig^.ethname),
                         65535, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf);
  except
    showmessage('打开网卡失败');
    isloop:=false;
    exit;
  end;
 // end;
  if pcap<>nil then
  begin

      mac:=Pcap_GetMacAddress (Pcap, ErrStr) ;

   end;
   //填写mac地址
  for i:=0 to 5 do
  begin
    StartPacket[i+6] := mac[i];
    userPacket[i+6] := mac[i];
    ResponseMD5[i+6] := mac[i];
    LogoffPacket[i+6] := mac[i];
  end;
  //填写账号
  user:=myconfig^.username;
  userlength:=5+length(user);

  userPacket[17]:=byte(userlength);
  userPacket[21]:=byte(userlength);
  for i:= 23 to length(user)+22 do
  begin

      userpacket[i] := Str_HexToInt(InttoHex( ord(user[i-22]) ,2));
  end;
  //发送开始认证包
  pcap_sendpacket(pcap, @StartPacket, SizeOf(StartPacket)) ;
  mmcount:=formatdatetime('ss',now());
   while isloop=true do
   begin
      //
      if (formatdatetime('ss',now()) <>mmcount) then
      begin
          try
            PostMessage(myconfig^.formhandle, WM_THREAD_MSG, 4, outnetbyte);
            PostMessage(myconfig^.formhandle, WM_THREAD_MSG, 5, innetbyte);
          except
            showmessage('子线程发送流量数据出错');
          end;
            mmcount:=formatdatetime('ss',now());
      end;
      //开始抓包
      try
        i:= pcap_next_ex(pcap, @pRecvHeaderBuf, @pRecvBuf);
      except
        showmessage('抓包函数出错');
      end;
      if(  i>0 ) then
      begin

        if (pRecvBuf[12] = $88) and (pRecvBuf[13] = $8e) then
        begin

          case precvbuf[18] of
          $01:
          begin
            if (pRecvBuf[22] = $01) then //Request Identity
            begin
                  //form1.Lab_login_state.Caption:='发送账号包';
                  try
                    pcap_sendpacket(pcap, @userpacket, SizeOf(userpacket)) ;
                  except
                    showmessage('发送账号包出错');
                  end;
            end
            else
            begin

              for i:=0 to 15 do
              begin
                    q_MD5Source[i] := pRecvBuf[i + 24];
              end;

              PostMessage(myconfig^.formhandle, WM_THREAD_MSG, 0, 0);

              szMd5Buffer[0] := $02;
              nLen := 1;
              CopyMemory(@szMd5Buffer[nLen], PChar(Trim(myconfig^.userpass)), Length(Trim(myconfig^.userpass)));  // 用户密码
              nLen := nLen + Length(Trim(myconfig^.userpass));
              CopyMemory(@szMd5Buffer[nLen], @q_MD5Source, 16); // 服务器返回密钥
              nLen := nLen + 16;

              for i:=0 to nlen-1 do
              begin
                  textstring:=textstring+inttohex(szMd5Buffer[i],2)+' ';
              end;
              textstring:=textstring+#13#10;





              MD5Init(md5Ctx);
              MD5Update(md5Ctx, @szMd5Buffer, nLen);
              MD5Final(md5Ctx, md5Dig);
              for i:= 24 to 39 do
              begin
                  ResponseMD5[i] := md5dig[i-24];
                  textstring:=textstring+inttohex(md5dig[i-24],2)+' ';
              end;
              textstring:=textstring+#13#10;
              rewrite(f);

              writeln(f,textstring);
              responsemd5[17]:=byte(length(myconfig^.username)+22);
              responsemd5[21]:=byte(length(myconfig^.username)+22);

              for i:= 40 to length(user)+39 do
              begin

                  ResponseMD5[i] := Str_HexToInt(InttoHex( ord(user[i-39]) ,2));

              end;


              pcap_sendpacket(pcap, @ResponseMD5, SizeOf(ResponseMD5)) ;


              end;
            end;
          $03:
          begin
            PostMessage(myconfig^.formhandle, WM_THREAD_MSG, 1, 0);



          end;
          $04:
          begin
            PostMessage(myconfig^.formhandle, WM_THREAD_MSG, 3, 0);
            isloop:=false;
          end;
          end;


        end;


        if (pRecvBuf[12] = $08) and (pRecvBuf[13] = $00) then
        begin
           if (pRecvBuf[23] = $06) then   //tcp包
           begin
              try
                buftoint[0]:= pRecvBuf[17];
                buftoint[1]:= pRecvBuf[16];

                Bufint := integer(buftoint);
              except
                showmessage('tcp字节转化错误');
              end;
              headlen2:=20;
              case  pRecvBuf[46] of
              $50:headlen2:=20;
              $60:headlen2:=24;
              $70:headlen2:=28;
              $80:headlen2:=32;
              $90:headlen2:=36;
              $a0:headlen2:=40;
              $b0:headlen2:=44;
              $c0:headlen2:=48;

              end;
              //if totalbyte<3000000000 then totalbyte:=totalbyte+abuf^ - 20 -headlen2;
              if ((pRecvBuf[26] = $c0) or (pRecvBuf[26] = $ac) ) and  ((pRecvBuf[30] = $c0) or (pRecvBuf[30] = $ac) ) then
              begin
                try
                innetbyte:=innetbyte+ bufint - 20 -headlen2;
                except
                showmessage('tcp计算出错in');
                end;
              end
              else
              begin
                try
                outnetbyte:=outnetbyte+ bufint - 20 -headlen2;
                except
                showmessage('tcp计算出错out');
                end;
              end;
              //if (pRecvBuf[26] = $c0) and ( pRecvBuf[30] <> $c0 ) and (pRecvBuf[30] <> $ac) then outnetbyte:=outnetbyte+ abuf^ - 20 -headlen2;
              //if (pRecvBuf[30] = $c0) and ( pRecvBuf[26] <> $c0 ) and (pRecvBuf[26] <> $ac) then outnetbyte:=outnetbyte+ abuf^ - 20 -headlen2;
              //if (pRecvBuf[26] = $ac) and ( pRecvBuf[30] <> $c0 ) and (pRecvBuf[30] <> $ac) then outnetbyte:=outnetbyte+ abuf^ - 20 -headlen2;
              //if (pRecvBuf[30] = $ac) and ( pRecvBuf[26] <> $c0 ) and (pRecvBuf[26] <> $ac) then outnetbyte:=outnetbyte+ abuf^ - 20 -headlen2;
           end;
           if (pRecvBuf[23] = $11) then  //udp包
           begin
              try
                buftoint[0]:= pRecvBuf[17];
                buftoint[1]:= pRecvBuf[16];

                Bufint := integer(buftoint);
              except
                showmessage('udp字节转化错误');
              end;
              if ((pRecvBuf[26] = $c0) or (pRecvBuf[26] = $ac) ) and  ((pRecvBuf[30] = $c0) or (pRecvBuf[30] = $ac) ) then
              begin
                try
                innetbyte:=innetbyte+ bufint - 28;
                except
                showmessage('udp计算出错in');
                end;
              end
              else
              begin
                try
                outnetbyte:=outnetbyte+ bufint - 28;
                except
                showmessage('udp计算出错out');
                end;
              end;

           end;

        end;
      end;
   end;
   pcap_sendpacket(pcap, @LogoffPacket, SizeOf(LogoffPacket)) ;
end;

你如果耐心看完的话,其实还有内外网流量统计的代码,但是我怀疑就是这一段有问题所以导致经常的出错退出。

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

发表评论

电子邮件地址不会被公开。 必填项已用*标注