⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp.dpr

📁 IPHlpAPI delphi源码
💻 DPR
📖 第 1 页 / 共 2 页
字号:
  Size := 0;
  if GetAdaptersInfo(nil, Size) <> ERROR_BUFFER_OVERFLOW then Exit;
  Adapters := AllocMem(Size);
  try
    if GetAdaptersInfo(Adapters, Size) = NO_ERROR then
    begin
      Adapter := Adapters;
      while Adapter <> nil do
      begin
        IpAddrString := @Adapter^.IpAddressList;
        while IpAddrString <> nil do
        begin
          if CompareText(IpAddrString^.IpAddress.S, Intf) = 0 then
          begin
            Result := Adapter^.Index;
            Exit;
          end;
          IpAddrString := IpAddrString^.Next;
        end;
        Adapter := Adapter^.Next;
      end;
    end;
  finally
    FreeMem(Adapters);
  end;
end;

function IpAddressToAdapterIndex(const Intf: DWORD): Integer; overload;
var
  Size: ULONG;
  AddrTable: PMibIpAddrTable;
  AddrRow: TMibIpAddrRow;
  I: Integer;
begin
  Result := -1;
  Size := 0;
  if GetIpAddrTable(nil, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
  AddrTable := AllocMem(Size);
  try
    if GetIpAddrTable(AddrTable, Size, True) = NO_ERROR then
    begin
      for I := 0 to AddrTable^.dwNumEntries - 1 do
      begin
        {$R-}AddrRow := AddrTable^.Table[I];{$R+}
        if AddrRow.dwAddr = Intf then
        begin
          Result := AddrRow.dwIndex;
          Break;
        end;
      end;
    end;
  finally
    FreeMem(AddrTable);
  end;
end;

procedure DeleteArpEntry(const Host, Intf: string);
var
  Entry: TMibIpNetRow;
  HostAddr, IntfAddr: DWORD;
  Size: ULONG;
  Adapters, Adapter: PIpAdapterInfo;
begin
  FillChar(Entry, SizeOf(Entry), 0);

  HostAddr := 0; // shuts up the compiler
  if Host <> '*' then
  begin
    HostAddr := inet_addr(PChar(Host));
    if HostAddr = DWORD(INADDR_NONE) then Exit;
  end;
  if Intf <> '' then
  begin
    IntfAddr := inet_addr(PChar(Intf));
    if IntfAddr = DWORD(INADDR_NONE) then Exit;
  end;

  { delete address from interface }

  if (Host <> '*') and (Intf <> '') then
  begin
    Entry.dwIndex := IpAddressToAdapterIndex(Intf);
    Entry.dwAddr := HostAddr;
    if DeleteIpNetEntry(Entry) = NO_ERROR then
      WriteLn('Deleted')
    else
      WriteLn('Failed');
    Exit;
  end;

  { delete all addresses from an interface }

  if (Host = '*') and (Intf <> '') then
  begin
    FlushIpNetTable(IpAddressToAdapterIndex(Intf));
    Exit;
  end;


  Size := 0;
  if GetAdaptersInfo(nil, Size) <> ERROR_BUFFER_OVERFLOW then Exit;
  Adapters := AllocMem(Size);
  try
    if GetAdaptersInfo(Adapters, Size) = NO_ERROR then
    begin
      Adapter := Adapters;
      while Adapter <> nil do
      begin

        { delete all addresses from each interface }

        if (Host = '*') and (Intf = '') then
        begin
          FlushIpNetTable(Adapter.Index);
        end;

        { delete address from each interface }

        if (Host <> '*') and (Intf = '') then
        begin
          FillChar(Entry, SizeOf(Entry), 0);
          Entry.dwIndex := Adapter.Index;
          Entry.dwAddr := HostAddr;
          DeleteIpNetEntry(Entry);
        end;

        Adapter := Adapter^.Next;
      end;
    end;
  finally
    FreeMem(Adapters);
  end;

end;

//------------------------------------------------------------------------------

// Returns the interface index of the first ...

function FirstNetworkAdapter(IpAddrTable: PMibIpAddrTable): Integer;
var
  I: Integer;
  IfInfo: TMibIfRow;
begin
  // TODO this is a "stupid" implementation, can be done much easier by using
  // enumerating the interface table directly
  Result := -1;
  for I := 0 to IpAddrTable^.dwNumEntries - 1 do
  begin
    {$R-}IfInfo.dwIndex := IpAddrTable^.table[I].dwIndex;{$R+}
    if GetIfEntry(@IfInfo) = NO_ERROR then
    begin
      if IfInfo.dwType in [MIB_IF_TYPE_ETHERNET, MIB_IF_TYPE_TOKENRING] then
      begin
        Result := IfInfo.dwIndex;
        Break;
      end;
    end;
  end;
end;

//------------------------------------------------------------------------------

// Adds an entry to the ARP table. InetAddr is the IP address to add, EtherAddr
// is the ethernet address to associate with the InetAddr and IntfAddr is the
// index of the adapter to add this ARP entry to. If IntfAddr is an empty string
// the function uses the first network adapter (tokenring or ethernet) it can
// find.

procedure SetArpEntry(const InetAddr, EtherAddr, IntfAddr: string);
var
  Entry: TMibIpNetRow;
  IpAddrTable: PMibIpAddrTable;
begin
  FillChar(Entry, SizeOf(Entry), 0);
  Entry.dwAddr := StringToIpAddr(InetAddr);
  Assert(Entry.dwAddr <> DWORD(INADDR_NONE));
  Entry.dwPhysAddrLen := 6;
  StringToPhysAddr(EtherAddr, TPhysAddrByteArray(Entry.bPhysAddr));
  Entry.dwType := MIB_IPNET_TYPE_STATIC;
  if IntfAddr <> '' then
    Entry.dwIndex := StrToInt(IntfAddr)
  else
  begin
    IpAddrTable := GetIpAddrTableWithAlloc;
    Assert(IpAddrTable <> nil);
    Entry.dwIndex := FirstNetworkAdapter(IpAddrTable);
    FreeMem(IpAddrTable);
  end;
  WriteLn(SysErrorMessage(SetIpNetEntry(Entry)));
end;

//------------------------------------------------------------------------------

// How is this program to be used by the end user?

procedure Usage;
begin
  WriteLn('Displays and modifies the IP-to-Physical address translation table used by');
  WriteLn('the address resolution protocol (ARP).');
  WriteLn;
  WriteLn('ARP -s inet_addr eth_addr [if_addr]');
  WriteLn('ARP -d inet_addr [if_addr]');
  WriteLn('ARP -a inet_addr [-N if_addr]');
  WriteLn;
  WriteLn('  -a         Displays current ARP entries by interrogating the current protocol');
  WriteLn('             data. If inet_addr is specified, the IP and physical addresses for');
  WriteLn('             only the specified computer are displayed. If more than one network');
  WriteLn('             interface uses ARP, entries for each for each ARP table are displayed.');
  WriteLn('  -g         Same as -a');
  WriteLn('  inet_addr  Specifies an internet address.');
  WriteLn('  -N if_addr Displays the ARP entries for the network interface specified by if_addr.');
  WriteLn('  -d         Deletes the host specified by inet_addr. inet_addr may be wildcarded');
  WriteLn('             with * to delete all hosts.');
  WriteLn('  -s         Adds the host and associates the internet address inet_addr with the');
  WriteLn('             physical address eth_addr. The physical address is given as 6');
  WriteLn('             hexadecimal bytes separated by hyphens.  The entry is permanent.');
  WriteLn('  eth_addr   Specifies a physical address.');
  WriteLn('  if_addr    If present, this specifies the index of the interface whose address');
  WriteLn('             translation tables should be modified. If not present the first found');
  WriteLn('             applicable interface will be used.');
  WriteLn('Example:');
  WriteLn('  > arp -s 157.55.85.212 00-aa-00-62-c6-09  .... Adds a static entry');
  WriteLn('  > arp -a                                  .... Displays the ARP table');
  WriteLn('  > arp -d *                                .... Flushes the ARP table'); 
end;

begin

  WriteLn('');
  WriteLn('Windows 2000 Arp');
  WriteLn('Copyright (C) 2000 Marcel van Brakel');
  WriteLn('');

  if (ParamCount = 0) or FindCmdLineSwitch('?', ['/', '-'], True) then
  begin
    Usage;
    Exit;
  end;

  // Case statement (in disquise) on the command line switches which dispatches
  // to the appropriate subroutine for further processing.

  if FindCmdLineSwitch('a', ['/', '-'], True) or FindCmdLineSwitch('g', ['/', '-'], True) then
    DisplayArpTable(ParamStr(2))
  else if FindCmdLineSwitch('d', ['/', '-'], True) then
    DeleteArpEntry(ParamStr(2), ParamStr(3))
  else if FindCmdLineSwitch('s', ['/', '-'], True) then
    SetArpEntry(ParamStr(2), ParamStr(3), ParamStr(4))
  else
    Usage;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -