📄 nbtstat.pas
字号:
procedure TNbt.RecvNbMsg(buffer: array of byte;len:integer;IP:string);
var
str:string;
i,j,pos,name_num: integer;
item : TListItem;
begin
item:=MyListView.Items.Insert(0);
item.Caption := IP;
for i:=0 to 4 do item.SubItems.Add(''); // attention: we do like item.SubItems[3]:=str;
{
RFC1002: " PROTOCOL STANDARD FOR A NetBIOS SERVICE ON A TCP/UDP TRANSPORT:
DETAILED SPECIFICATIONS "
4.2.18. NODE STATUS RESPONSE
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NAME_TRN_ID |1| 0x0 |1|0|0|0|0 0|0| 0x0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x0000 | 0x0001 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x0000 | 0x0000 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
/ RR_NAME /
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NBSTAT (0x0021) | IN (0x0001) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x00000000 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RDLENGTH | NUM_NAMES | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
+ +
/ NODE_NAME ARRAY /
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
/ STATISTICS /
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
of NODE_NAME records. Each NODE_NAME entry represents an active
name in the same NetBIOS scope as the requesting name in the
local name table of the responder. RR_NAME is the requesting
name.
NODE_NAME Entry:
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+--- ---+
| |
+--- NETBIOS FORMAT NAME ---+
| |
+--- ---+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NAME_FLAGS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The NAME_FLAGS field:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| G | ONT |DRG|CNF|ACT|PRM| RESERVED |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
The NAME_FLAGS field is defined as:
Symbol Bit(s) Description:
RESERVED 7-15 Reserved for future use. Must be zero (0).
PRM 6 Permanent Name Flag. If one (1) then entry
is for the permanent node name. Flag is zero
(0) for all other names.
ACT 5 Active Name Flag. All entries have this flag
set to one (1).
CNF 4 Conflict Flag. If one (1) then name on this
node is in conflict.
DRG 3 Deregister Flag. If one (1) then this name
is in the process of being deleted.
ONT 1,2 Owner Node Type:
00 = B node
01 = P node
10 = M node
11 = Reserved for future use
G 0 Group Name Flag.
If one (1) then the name is a GROUP NetBIOS
name.
If zero (0) then it is a UNIQUE NetBIOS name.
STATISTICS Field of the NODE STATUS RESPONSE:
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UNIT_ID (Unique unit ID) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UNIT_ID,continued | JUMPERS | TEST_RESULT |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VERSION_NUMBER | PERIOD_OF_STATISTICS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NUMBER_OF_CRCs | NUMBER_ALIGNMENT_ERRORS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NUMBER_OF_COLLISIONS | NUMBER_SEND_ABORTS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NUMBER_GOOD_SENDS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NUMBER_GOOD_RECEIVES |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NUMBER_RETRANSMITS | NUMBER_NO_RESOURCE_CONDITIONS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NUMBER_FREE_COMMAND_BLOCKS | TOTAL_NUMBER_COMMAND_BLOCKS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|MAX_TOTAL_NUMBER_COMMAND_BLOCKS| NUMBER_PENDING_SESSIONS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MAX_NUMBER_PENDING_SESSIONS | MAX_TOTAL_SESSIONS_POSSIBLE |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SESSION_DATA_PACKET_SIZE |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
}
name_num:=0;
for i:=1 to len do
begin
if((buffer[i]=$21)and(buffer[i+1]=$00)and(buffer[i+2]=$01))
then
begin
name_num:=buffer[i+9];
break;
end;
end;
if name_num=0 then exit;
pos:=i+10;
str:='';
for i:=pos to (pos+18*name_num-1) do
begin
if (((i-pos)mod 18) =0) then
begin
for j:=0 to 14 do
begin
if trim(char(buffer[i+j]))='' then buffer[i+j]:=ord(' ');
str:=str+char(buffer[i+j]);
end;
if (buffer[i+16] and $80)=$80 then
begin
if buffer[i+15]=$0 then item.SubItems[0]:=str;
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<GROUP>';
end
else
begin
if buffer[i+15]=$20 then item.SubItems[1]:=str
else
if buffer[i+15]=$3 then item.SubItems[2]:=str;
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<UNIQUE>';
end;
//ListBox1.Items.Add(str);
str:='';
end;
end;
for i:=0 to 5 do
begin
str:=str+format('%.2x.',[buffer[i+pos+18*name_num]]);
end;
delete(str,length(str),1);
item.SubItems[3]:=str;
//----------------------------------------------------
if assigned(OnAddNodeEvent) then OnAddNodeEvent(TObject(IP));
end;
procedure TNbt.ReadData(var Message: TMessage);
var
buffer: Array [1..500] of byte;
flen,len: integer;
Event: word;
IP:string;
begin
if Message.msg<>WM_SOCK then exit;
//Windows.Beep(2000,200);
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
if len> 0 then
begin
//FSockAddrIn.sin_addr.S_un_b.s_b1
with FSockAddrIn.sin_addr.S_un_b
do IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]);
RecvNbMsg(buffer,len,IP);
end;
SetEvent(WAIT_ACK_EVENT);
end;
end;
procedure TNbt.SendData(b:array of byte;IP:string);
var
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(IP));
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
len := sendto(s, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
//if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then showmessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then
if Application.MessageBox(
'SOCKET错误,可能是你网线没接好或网络设置有问题,是否中断扫描?',
'SOCKET ERROR',
MB_OKCANCEL + MB_DEFBUTTON1) = IDOK then exit_nbt_thread := true;
{if len <> 50 then
showmessage('Not Send all');}
end;
procedure TNbt.start;
begin
exit_nbt_thread := false;
SendDataThread := TSendDataThread.Create(true);
SendDataThread.FreeOnTerminate := true;
SendDataThread.Resume;
end;
procedure TNbt.Stop;
begin
exit_nbt_thread := true;
SendDataThread.Terminate;
end;
procedure TNbt.Pause;
begin
SendDataThread.Suspend;
end;
procedure TNbt.Restart;
begin
SendDataThread.Resume;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -