www.pudn.com > Unit1.rar > Unit1.pas


unit Unit1; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, 
  IdTelnet, StdCtrls, ComCtrls,Commctrl,ScktComp, RzListVw,strtools, ImgList, 
  AppEvnts, ToolWin, ExtCtrls,ShellAPI,winSock2; 
 
type 
  TIpMacRec=record  //如果修改了TIpRec结构,TGate.dat必须删除之后重新运行. 
      ip:integer; 
      macS:string[65]; 
      hostName:String[40]; 
  end; 
 
  TForm1 = class(TForm) 
    IdTelnet1: TIdTelnet; 
    ListView1: TRzListView; 
    ImageList1: TImageList; 
    StatusBar1: TStatusBar; 
    EchoSocket9999: TClientSocket; 
    ToolBar1: TToolBar; 
    tbStart: TToolButton; 
    tbSave: TToolButton; 
    tmFlashHost: TTimer; 
    tbMerge: TToolButton; 
    tbOpenIpMac: TToolButton; 
    reIPMAC: TRichEdit; 
    ToolButton1: TToolButton; 
    Panel1: TPanel; 
    reMemo1: TRichEdit; 
    procedure WMASyncSMBEcho(var msg: TMessage); message UM_SMBEcho; 
    procedure IdTelnet1DataAvailable(Sender: TIdTelnet;const Buffer: String); 
    procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn); 
    procedure ListView1Compare(Sender: TObject; Item1, Item2: TListItem;Data: Integer; var Compare: Integer); 
    procedure IdTelnet1Status(ASender: TObject; const AStatus: TIdStatus;const AStatusText: String); 
    procedure EchoSocket9999Error(Sender: TObject; Socket: TCustomWinSocket;ErrorEvent: TErrorEvent; var ErrorCode: Integer); 
    procedure FormCreate(Sender: TObject); 
    procedure tbStartClick(Sender: TObject); 
    procedure ListView1DblClick(Sender: TObject); 
    procedure tbSaveClick(Sender: TObject); 
    procedure tmFlashHostTimer(Sender: TObject); 
    procedure tbOpenIpMacClick(Sender: TObject); 
    procedure FormShow(Sender: TObject); 
    procedure tbMergeClick(Sender: TObject); 
    procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
    procedure reMemo1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); 
  private 
    procedure mySendCommand(cmd: String); 
    procedure ciscoOk; 
    { Private declarations } 
  public 
    { Public declarations } 
  end; 
 
var 
   Form1: TForm1; 
   ColumnToSortR:integer; 
   SMBCount,telnetStatus,conputerCount:integer; 
   textSY:String; 
   inFlashHost:boolean; 
   ht:PLVHitTestInfo;//得到鼠标点击的 listView 上的行号、列号用. 
implementation 
 
{$R *.dfm} 
procedure TForm1.mySendCommand(cmd:String); 
var 
   i:integer; 
begin 
   for i:=1 to length(cmd) do IdTelnet1.SendCh(cmd[i]); //发送用户名 
   IdTelnet1.SendCh(#13); 
end; 
 
procedure TForm1.IdTelnet1DataAvailable(Sender: TIdTelnet;const Buffer: String); 
var 
   i,pos0:integer; 
   haveDataLine:boolean; 
   s,sLine,text,IPs:string; 
   item:TListItem; 
begin 
   text:=Buffer;     
   if pos('Username:',text)>0 then 
   begin 
      mySendCommand('cisco6509e'); //发送用户名 
      exit; 
   end; 
   if (pos('Password:',text)>0) and (telnetStatus=0) then 
   begin 
      sleep(100); 
      mySendCommand('dqcy7xxzx'); //发送密码 
      telnetStatus:=1; 
      exit; 
   end; 
 
   if (pos('CY7-C6509E-01>',text)>0) and (telnetStatus=1) then 
   begin 
      mySendCommand('enable');//进入特权用户 
      telnetStatus:=2; 
      exit; 
   end; 
 
   if telnetStatus=2 then 
   begin 
      mySendCommand('hunter_fan'); //发送密码 
      telnetStatus:=3; 
      exit; 
   end; 
    
   if telnetStatus=3 then 
   begin 
      mySendCommand('show arp'); 
      telnetStatus:=4; 
   end; 
 
   EchoSocket9999.Socket.SendText(text+'<<<<<'#13#10); 
   if textSy<>'' then begin text:=textSy+text;textSy:='';end;//把上一行没有解释完的补到前面. 
   haveDataLine:=false; 
   while pos('Internet  ',text)>0 do 
   begin 
      pos0:=pos('Internet  ',text);     haveDataLine:=true; 
      delete(text,1,pos0-1);  //Internet  10.64.194.173          25   0013.d38d.4900  ARPA   Vlan3........ 
      sLine:=cutStrWithStr(text,#13#10); 
      if sLine='' then 
      begin 
         textSY:=text; 
         text:=' --More-- '; 
         break; 
      end; 
      item:=ListView1.Items.Add;     item.ImageIndex:=-1; 
      conputerCount:=conputerCount+1; 
      s:=cutString(sLine,' '); item.Caption:=format('%4d',[conputerCount]);//Internet 
      s:=cutString(sLine,' '); item.SubItems.Add(s);IPS:=S;//IP 
      s:=cutString(sLine,' '); item.SubItems.Add(s);//Age 
      s:=cutString(sLine,' '); item.SubItems.Add(s);//MAC 
      s:=cutString(sLine,' '); item.SubItems.Add(s);//Type 
                               item.SubItems.Add(sLine);//InterFase 
                               item.SubItems.Add('');//HostName 
                               item.SubItems.Add('');//存放 HostName 解析请求是否发送成功. 
      sLine:='';//该行已经解析完了,没有剩余. 
   end; 
   if not haveDataLine then exit;//没有真正的数据,仅仅是telenet 键盘字母的echo. 
   if (pos(' --More-- ',text)=0) and (text<>'') then textSY:=text else textSY:=''; //'Internet  10.64.195.62          223   0013.d38d.053b  ARPA   Vlan4'#$D#$A'I' 的情况 
   if pos(' --More-- ',textSy)=1 then begin textSY:='';text:=' --More-- ';end; //'Internet  10.64.195.62          223   0013.d38d.053b  ARPA   Vlan4'#$D#$A'I' 的情况 
 
   EchoSocket9999.Socket.SendText('text='+text+#13#10); 
   if (copy(text,1,10)=' --More-- ') then begin sleep(100);IdTelnet1.SendCmd(' ');end 
   else 
   try 
      EchoSocket9999.Socket.SendText('text1='+text+#13#10); 
      EchoSocket9999.Socket.SendText('textSy1='+textSy+#13#10); 
      if pos('CY7-C6509E-01#',textSy)=0 then //真正的结束! 
      begin 
         if (textSy<>'') or (sLine='') then exit;//文本剩半截,或者一点没有剩,并且后面不是--more--,直接退出,等待后续数据的到来. 
      end else if pos('cisco6509>exit',textSy)>0 then exit;//结束,一点也没有用上! 
 
      IdTelnet1.WriteLn('exit'); 
      IdTelnet1.WriteLn(''); 
      statusbar1.Panels[1].Text:=format('line=%d  ---End!',[ListView1.Items.Count]); 
      ciscoOk(); 
   except 
   end; 
end; 
 
procedure TForm1.ciscoOk; 
var 
   i,j,count:integer; 
   isErr:boolean; 
   item:TListItem; 
   ipS,macS,ageS:String; 
begin 
   ColumnToSortR:=3; 
   ListView1.AlphaSort;//按照MAC排序. 
 
   isErr:=false;  //与上行重复标志. 
   reMemo1.Clear; 
   i:=0; 
   while i'-') and (pos('.',macS)<>0) then //不是网关,不是'Incomplete' 
      begin 
         count:=1; 
         for j:=i+1 to ListView1.Items.Count-1 do  
         begin 
            with ListView1.Items[j] do 
            if SubItems[2]<>macS then break 
            else 
            begin 
               ImageIndex:=0;         //当前行加图标 
               item.ImageIndex:=0;    //上行加图标 
               count:=count+1; 
               i:=j; 
            end; 
         end; 
         if count>3 then reMemo1.Lines.Add(format('%-15s %15s(%d)',[ipS,macS,count])); 
      end; 
      i:=i+1; 
   end; 
   tmFlashHost.Enabled:=true;//启动Host解析时钟. 
end; 
 
procedure TForm1.ListView1ColumnClick(Sender: TObject;Column: TListColumn); 
begin 
   ColumnToSortR:=Column.Index; 
   (Sender as TCustomListView).AlphaSort; 
end; 
 
procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;Data: Integer; var Compare: Integer); 
var 
   m,n:integer; 
   s1,s2:String; 
begin 
case ColumnToSortR of 
  -1:Compare:=0; 
  0:Compare:=CompareText(TListItem(Item1).Caption,TListItem(Item2).Caption); 
  1:begin 
       s1:=TListItem(Item1).SubItems[0]; 
       s2:=TListItem(Item2).SubItems[0];   
       Compare:=ntohl(inet_Addr(pChar(s2)))-ntohl(inet_Addr(pchar(s1))); 
    end;    
  else //子列排序 
      begin 
         try 
            m:=StrToIntDef(TListItem(Item1).SubItems[ColumnToSortR-1],0); 
            n:=StrToIntDef(TListItem(Item2).SubItems[ColumnToSortR-1],0); 
            Compare:=m-n; 
            if ((m=0) and (TListItem(Item1).SubItems[ColumnToSortR-1]<>'0')) or 
               ((n=0) and (TListItem(Item2).SubItems[ColumnToSortR-1]<>'0')) then 
            Compare:=CompareText(TListItem(Item1).SubItems[ColumnToSortR-1],TListItem(Item2).SubItems[ColumnToSortR-1]); 
         except 
            Compare:=CompareText(TListItem(Item1).Caption,TListItem(Item2).Caption); 
         end; 
      end; 
  end; 
 
  if ColumnToSortR<>0 then Compare:=-Compare; 
end; 
 
procedure TForm1.IdTelnet1Status(ASender: TObject;const AStatus: TIdStatus; const AStatusText: String); 
begin 
   statusBar1.Panels[0].Text:=AStatusText; 
end; 
 
procedure TForm1.WMASyncSMBEcho(var msg: TMessage); 
var 
   i:integer; 
   item:TListItem; 
   ips,workGroup,HostName,userName,macAddress:String; 
begin 
   SMBCount:=SMBCount+1;   
   ansSMBEcho(ips,workGroup,HostName,userName,macAddress); 
   for i:=0 to listView1.Items.Count-1 do 
   begin 
      item:=ListView1.Items[i]; 
      if item.SubItems[0]=ips then 
      begin 
         item.SubItems[5]:=format('%s|%s|%s',[workGroup,HostName,userName]); 
      end; 
   end; 
end; 
 
procedure TForm1.EchoSocket9999Error(Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer); 
begin 
   ErrorCode:=0; 
end; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
   new(ht); 
   initSMB(handle,0,6969);//初始化,用于得到主机名,网卡地址用 
end; 
 
procedure TForm1.tbStartClick(Sender: TObject); 
begin 
   EchoSocket9999.Active:=true;       inFlashHost:=false; 
   telnetStatus:=0; 
   conputerCount:=0;   SMBCount:=0;ListView1.Clear; 
   if IdTelnet1.Connected then IdTelnet1.Disconnect; 
   IdTelnet1.Host:='10.64.192.1';    IdTelnet1.Port:=23; 
   IdTelnet1.Terminal:='';  textSY:=''; 
   IdTelnet1.Connect(); 
end; 
 
procedure TForm1.ListView1DblClick(Sender: TObject); 
var 
   row,pos0:integer; 
   MACS:String; 
begin 
   row:=ListView1.ItemIndex;//点击的行数. 
   if row<0 then exit;//非行点击 
   MACS:=ListView1.Selected.SubItems.Strings[2]+' ';//得到MAC地址. 
   //匹配用户点击的IP或者MAC地址,在reIpMac文本中 
   pos0:=pos(MACS,reIPMAC.Text);        if pos0<0 then pos0:=0; 
   reIPMAC.SelStart := pos0; 
   SendMessage(reIPMAC.Handle, EM_SCROLLCARET, 0, 0); //滚动到光标处(只能保证光标出现在窗口中) 
   row:= SendMessage(reIPMAC.Handle, EM_LINEFROMCHAR, reIPMAC.SelStart, 0);//得到当前行 
   SendMessage(reIPMAC.Handle, EM_LINESCROLL, 0, row - SendMessage(reIPMAC.Handle, EM_GETFIRSTVISIBLELINE, 0, 0)); 
end; 
 
procedure TForm1.tbSaveClick(Sender: TObject); 
var 
   i:integer; 
   item:TListItem; 
   ss:TStrings; 
   cc,sn:string; 
begin 
   ss:=TStringList.Create; 
   //  389  10.64.194.11     51   0800.20fe.d74c    ARPA   Vlan3  || 
   ss.add('  No.      IP           Age       MAC          type Interface  Name'); 
   for i:=0 to ListView1.Items.Count-1 do 
   begin 
      item:=ListView1.Items[i]; if item.ImageIndex<>-1 then cc:='*' else cc:=' '; 
      if item.SubItems[2]='Incomplete' then continue;//没有网卡地址,忽略. 
      ss.Add(format('%s%4s  %-15s  %-4s %-15s   %-4s %-8s %-s',[cc,item.Caption,item.SubItems[0],item.SubItems[1],item.SubItems[2],item.SubItems[3],item.SubItems[4],item.SubItems[5]])); 
   end; 
   sn:=formatDateTime('YYYYMMDD hhmmss',now); 
   ss.Add(sn+'   '+statusbar1.Panels[1].Text);      //20070301 072942   line=971  ---End! 
   ss.SaveToFile(sn+'.out'); 
   if not FileExists('Ip_MAC.TXT') then ss.SaveToFile('Ip_MAC.TXT'); 
end; 
 
procedure TForm1.tmFlashHostTimer(Sender: TObject); 
var 
   i,waitCount:integer; 
   item:TListItem; 
begin 
   if inFlashHost then exit; 
   inFlashHost:=true;      waitCount:=0; 
   for i:=0 to ListView1.Items.Count-1 do 
   begin 
      item:=ListView1.Items[i]; 
      if item.SubItems[2]='Incomplete' then continue;//没有网卡地址,忽略. 
      if item.SubItems[6]<>'v' then 
      begin 
         waitCount:=waitCount+1; 
         if not SendMacReqOk(item.SubItems[0]) then break else item.SubItems[6]:='v'; 
         if waitCount mod 25=0 then break;  //发送多了就会丢失. 
      end; 
   end; 
   inFlashHost:=false; 
   if waitCount=0 then 
   begin 
      tmFlashHost.Enabled:=false; 
      IdTelnet1.Disconnect; 
   end; 
end; 
 
procedure TForm1.tbOpenIpMacClick(Sender: TObject); 
begin 
   ShellExecute(Handle,   'open',   'notepad.exe',   'IP_MAC.txt',   nil,   SW_SHOW); 
end; 
 
function Compare(ip:LongInt;port:word;Item:Pointer):integer; 
var 
   pp:^TIpMacRec; 
   ul1,ul2:u_long; 
begin 
   pp:=Item;       ul1:=ntohl(ip); 
   ul2:=ntohl(pp.ip);//-StrLComp(PChar(@key),PChar(@pp.ip),4); 
   if ul1=ul2 then result:=0 
   else if ul1>ul2 then result:=-1 
   else result:=1; 
end; 
 
procedure TForm1.FormShow(Sender: TObject); 
begin 
   if fileExists('IP_MAC.txt') then reIPMAC.Lines.LoadFromFile('IP_MAC.txt'); 
end; 
 
procedure TForm1.tbMergeClick(Sender: TObject); 
var 
   i,pos0,count:integer; 
   item:TListItem; 
   theMac:string; 
   cc:Char; 
begin 
   statusBar1.Panels[0].Text:='资料保存,稍等......'; 
   Application.ProcessMessages; 
   count:=0; 
   for i:=0 to ListView1.Items.Count-1 do //遍历每一行,与内存中的reIpMAcList对比,没有该ip,就在reIpMAC后面插入一行. 
   begin 
      item:=ListView1.Items[i]; 
      theMac:=item.SubItems[2]+' '; 
      if theMac='Incomplete ' then continue;//没有网卡地址,忽略. 
      pos0:=pos(theMAC,reIPMac.Text); 
      if (pos0<=0) then //不是重复的网卡,在ip_MAC.txt中没有登记! 
      begin 
         if (item.ImageIndex<>0) then cc:=' ' else cc:='*'; 
         reIPMAC.lines.Add(format('%s%4s  %-15s  %-4s %-15s   %-4s %-8s %-s',[cc,item.Caption,item.SubItems[0],item.SubItems[1],item.SubItems[2],item.SubItems[3],item.SubItems[4],item.SubItems[5]])); 
         count:=count+1; 
      end; 
   end; 
   reIPMAC.lines.SaveToFile('ip_mac.txt');//?????????????写  ipMacLists===>ipmac.txt 
   statusBar1.Panels[0].Text:=format('新增 %d 个记录!',[count]); 
end; 
 
procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); 
begin 
   ht.pt.x   :=   X;    ht.pt.Y   :=   Y; 
   ListView_SubItemHitTest(ListView1.Handle,   ht); 
   //ShowMessage(IntToStr(ht.iItem));                                     //行号 
   //ShowMessage(IntToStr(ht.iSubItem));                               //列号 
end; 
 
procedure TForm1.reMemo1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); 
var 
   i,line:integer; 
   ipS:String; 
begin 
   line:=SendMessage(reMemo1.Handle, EM_LINEFROMCHAR, reMemo1.SelStart, 0); 
   ips:=reMemo1.Lines[line]; 
   ipS:=cutString(ips,' '); 
   for i:=0 to listView1.Items.Count-1 do 
   if TListItem(listView1.Items[i]).SubItems[0]=ipS then 
   begin 
      listView1.SetFocus; 
      listView1.ItemIndex:=i; 
      listView1.Items[i].MakeVisible(true); 
      break; 
   end; 
end; 
 
end.