File Coverage

blib/lib/Net/NetSend.pm
Criterion Covered Total %
statement 18 303 5.9
branch 0 86 0.0
condition 0 16 0.0
subroutine 6 25 24.0
pod 0 19 0.0
total 24 449 5.3


line stmt bran cond sub pod time code
1             package Net::NetSend;
2            
3 1     1   12374 use 5.006;
  1         5  
  1         232  
4 1     1   8 use strict;
  1         2  
  1         43  
5 1     1   7 use warnings;
  1         6  
  1         44  
6 1     1   1288 use POSIX;
  1         12654  
  1         10  
7 1     1   5949 use Socket qw(:DEFAULT :crlf);
  1         23659  
  1         1512  
8 1     1   1595 use IO::Handle;
  1         24385  
  1         12930  
9            
10             require Exporter;
11            
12             our @ISA = qw(Exporter);
13            
14             # Items to export into callers namespace by default. Note: do not export
15             # names by default without a very good reason. Use EXPORT_OK instead.
16             # Do not simply export all your public functions/methods/constants.
17            
18             # This allows declaration use Net::NetSend ':all';
19             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
20             # will save memory.
21             our %EXPORT_TAGS = ( 'all' => [ qw( sendMsg getNbName ) ] );
22            
23             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
24            
25             our @EXPORT = qw();
26             our $VERSION = '0.12';
27            
28             # Preloaded methods go here.
29            
30            
31             my $SESSION_REQUEST = chr(0x81);
32             my $INIT_SESSION_FLAGS = "\0";
33             my $NB_SESSION_MESSAGE = "\0";
34             my $NB_SESSION_ESTABLISHED = chr(0x82);
35             my %NB_ERROR_TEXT = ( 0x83 => "Called Name Not Present" );
36             my %NB_ERROR_HELP = ( 0x83 => 'Probably the Messenger Service ("Nachrichtendienst") '
37             ."on the remote machine is switched off." );
38            
39             #SMB Header
40             my $SMB_HEADER_SERVER_COMPONENT_SMB = chr(0xFF).chr(0x53).chr(0x4D).chr(0x42);
41             my $SMB_HEADER_SEND_SINGLE_BLOCK_MSG = chr(0xD0);
42             my $SMB_HEADER_SEND_MULTI_BLOCK_MSG_START = chr(0xD5);
43             my $SMB_HEADER_SEND_MULTI_BLOCK_MSG_TEXT = chr(0xD7);
44             my $SMB_HEADER_SEND_MULTI_BLOCK_MSG_END = chr(0xD6);
45             my $SMB_HEADER_ERROR_CLASS_SUCCESS = "\0";
46             my $SMB_HEADER_RESERVED = "\0";
47             my $SMB_HEADER_ERRORCODE_NO_ERROR = "\0"."\0";
48             my $SMB_HEADER_FLAGS_DEFAULT = "\0";
49             my $SMB_HEADER_FLAGS2_DEFAULT = "\0"."\0";
50             my $SMB_HEADER_PROCESS_ID_HIGH_FALSE = "\0"."\0";
51             my $SMB_HEADER_SIGNATURE = "\0"x 8;
52             my $SMB_HEADER_RESERVED2 = "\0"."\0";
53             my $SMB_HEADER_TREE_ID = "\0"."\0";
54             my $SMB_HEADER_PROCESS_ID = "\0"."\0";
55             my $SMB_HEADER_USER_ID = "\0"."\0";
56             my $SMB_HEADER_MULTIPLEX_ID = "\0"."\0";
57            
58             my $MBM_MESSAGE_GROUP_ID;
59            
60             #SSMBR = Send Single Block Message Request
61             my $SMB_SSBMR_BUFFER_ASCII = chr(0x04);
62             my $SMB_SSBMR_BUFFER_DATA_BLOCK = chr(0x01);
63            
64             my $init_response_success = chr(0x82).("\0"x3);
65            
66            
67             my $overall_succes=1; #Status
68             my $error_texts=""; #Error information storage
69            
70            
71             sub sendMsg($$$$;$){
72 0     0 0   $@='';
73 0           $error_texts='';
74             # if(@_ < 4){
75             # $@ .= "Not enough arguments.\n";
76             # return 0;
77             # }
78 0           my $target_netbios_name_cleartext=uc(shift); # "Called Name"
79 0           my $source_netbios_name_cleartext=uc(shift); # "Calling Name", can be faked here
80 0           my $target_ip=shift; # target ip.
81 0           my $target_port=139;
82 0           my $message=shift; #The message to send
83 0           my $debug=shift;
84            
85 0 0         if(length($message) <128){
86 0           send_single_block_message(
87             $message, $target_ip, $target_port,
88             $target_netbios_name_cleartext,
89             $source_netbios_name_cleartext,
90             $debug
91             );
92             #print $error_texts if $error_texts;
93 0           $@ = $error_texts;
94 0           return $overall_succes;
95             }
96 0 0         if(length($message) > 4000){
97 0           $error_texts .= "Warning! Message size exceeds 4000 chars. Truncated message will be delivered.\n";
98 0           $message=substr($message, 0, 4000);
99 0           $overall_succes=0;
100             }
101             # print "Error: Message exceeds 128 Bytes.\n";
102             # exit(-1);
103             send_multi_block_message(
104 0           $message, $target_ip, $target_port,
105             $target_netbios_name_cleartext,
106             $source_netbios_name_cleartext,
107             $debug
108             );
109 0           $@ = $error_texts;
110 0           return $overall_succes;
111             }
112            
113            
114             sub getNbName($;$){
115 0     0 0   (my $target_ip, my $debug) = @_;
116 0           my $target_port = 137;
117 0 0         print "Looking for a netbios name for $target_ip...\n" if $debug;
118            
119             #####################################
120             # Create Query Packet #
121             #####################################
122            
123 0           my $nbq=''; #nbq = netbios name query
124             #first 2 bytes = random transaction id
125 0           $nbq .= chr(rand(142)+1);
126 0           $nbq .= chr(rand(142)+1);
127             # then: 2 bytes for flags (none set)
128 0           $nbq .= chr(0)x2;
129             # then: 2 bytes for the number of questions (one)
130 0           $nbq .= chr(0).chr(0x01);
131             # then: 2 bytes each for answer, authority and additional RRs (none)
132 0           $nbq .= chr(0)x6;
133             # then: the actual query. name first
134 0           $nbq .= " CK".("A"x30).chr(0);
135             # then: type (NBSTAT)
136 0           $nbq .= chr(0).chr(0x21);
137             # then: class (inet)
138 0           $nbq .= chr(0).chr(0x01);
139             # packet is now ready for delivery
140            
141            
142             #####################################
143             # Create Socket #
144             #####################################
145 0           my $proto = getprotobyname("udp");
146 0 0         my $host = inet_aton($target_ip) or die "Unknown host: $target_ip\n";
147 0           my $sock;
148 0 0         socket($sock, AF_INET, SOCK_DGRAM, $proto) or die "Could not create socket. Socket() failed: $!\n";
149 0           my $dest_addr = sockaddr_in($target_port, $host);
150 0 0         connect($sock, $dest_addr)
151             or die "connect() of socket to target IP $target_ip failed: $!\n";
152 0           $sock->autoflush(1);
153            
154             #####################################
155             # Send Name Query #
156             #####################################
157            
158 0           print $sock $nbq;
159            
160             #####################################
161             # Receive & Check Answer #
162             #####################################
163 0           my $nbanswer;
164            
165 0           my $answer_received=0;
166 0           my $inmask = '';
167 0           vec($inmask, fileno($sock), 1) = 1;
168 0           while (select(my $outmask = $inmask, undef, undef, 0.8)) {
169 0           recv($sock, $nbanswer, 1000, 0);
170 0           $answer_received = 1;
171             }
172            
173 0 0         if(!$answer_received){
174 0           $@="Timeout while waiting for answer from $target_ip.\n";
175 0 0         print $@ if $debug;
176 0           return 0;
177             }
178            
179 0 0         if(length($nbanswer) == 0){
180 0           $@ = "Zero length answer received. Often this caused".
181             " by an ICMP destination unreacheable packet.\n";
182 0 0         print $@ if $debug;
183 0           return 0;
184             }
185            
186 0 0         if(length($nbanswer) < 20){
187 0           $@ = "Too short answer (" . length($nbanswer) .
188             " chars) received:\n" . hexdump($nbanswer);
189 0 0         print $@ if $debug;
190 0           return 0;
191             }
192             # strip header
193 0           $nbanswer = substr($nbanswer, 12);
194             # counting from 0
195             # 42/43: data length
196             # 44: number of names
197             # now n 18-byte-steps, the wanted name ends with 0x03 0x04 0x00
198            
199 0           my $num_answers = ord(substr($nbanswer, 44, 1));
200            
201 0           my @names03=();
202            
203 0           for(my $i = 0; $i < $num_answers; $i++){
204 0           my $service = substr($nbanswer, 44+ 16+ $i*18, 1);
205 0           my $typeflags = substr($nbanswer, 44+ 17+ $i*18, 2);
206 0 0         if($debug){
207 0           print "\nCandidate $i\n";
208 0           print hexdump(substr($nbanswer, 44+ $i*18, 16));
209 0           print "\tService ".hexdump($service);
210 0           print "\n\tTypeflags ".hexdump($typeflags)."\n\n";
211             }
212             # we got our target?
213 0 0         if($service eq chr(0x03)){
214             # && ($typeflags eq chr(0x04).chr(0) || $typeflags eq chr(0x44).chr(0))){
215             # we got it!
216             # service 0x03 is the messenger service / main name
217             # typeflags 0x04 0x00 means B-node, unique, active
218 0           my $target_name = substr($nbanswer, 44+$i*18+1, 16);
219 0           $target_name =~ /^(\S+)( )*/;
220 0           push @names03, $1;
221             }
222             }
223 0 0         return $names03[0] if @names03 > 0;
224             # @names[0] is the machine name
225             # @names[1..n] are the users that are logged on
226 0           $@ = "Sorry, you cannot send messages to this IP. " .
227             "There is no messenger service running on the remote machine\n" .
228             "The complete answer was: " . hexdump($nbanswer) . "\n";
229 0 0         print $@ if $debug;
230            
231             # print $num_answers;
232            
233 0           return 0;
234            
235             }
236            
237            
238             sub send_multi_block_message{
239 0     0 0   my $mbmessage = shift;
240 0           my $mbtarget_ip = shift;
241 0           my $mbtarget_port = shift;
242 0           my $mbtarget_netbios_name_cleartext = shift;
243 0           my $mbsource_netbios_name_cleartext = shift;
244 0           my $confirm_packets = shift;
245            
246             #Create Socket
247 0           my $sock;
248 0           my $proto = getprotobyname("tcp");
249 0 0         my $host = inet_aton($mbtarget_ip) or die "Unknown host: $mbtarget_ip.\n";
250 0 0         socket($sock, AF_INET, SOCK_STREAM, $proto) or die "Could not create socket. Socket() failed: $!\n";
251 0           my $dest_addr = sockaddr_in($mbtarget_port, $host);
252 0 0         connect($sock, $dest_addr)
253             or die "connect() of socket to $mbtarget_netbios_name_cleartext (IP: $mbtarget_ip) failed: $!\n";
254 0           $sock->autoflush(1);
255            
256             #Compute Encoding for Source and Target NETBIOS Names
257 0           my $target_netbios_name_cipher = get_nb_string($mbtarget_netbios_name_cleartext);
258 0           my $source_netbios_name_cipher = get_nb_string($mbsource_netbios_name_cleartext);
259            
260             #Create Netbios Session Request Packet
261 0           my $init_packet = $SESSION_REQUEST . $INIT_SESSION_FLAGS .
262             get_2bytes_length($target_netbios_name_cipher.$source_netbios_name_cipher) .
263             $target_netbios_name_cipher . $source_netbios_name_cipher;
264            
265             #Send Netbios Session Request Packet
266 0           print $sock $init_packet;
267            
268             #Receive Session Request Response
269 0           my $init_resp="";
270 0           my $inmask='';
271 0           vec($inmask, fileno($sock), 1)=1;
272 0           select(my $outmask = $inmask, undef, undef, 0.25); #0.25 sec timeout
273 0           recv($sock, $init_resp,1024, 0);
274             #print "received data: $init_resp\n";
275             #print_to_file("c:\\test.log", $init_resp);
276            
277            
278             #Check Session Request Response for Success
279 0 0         if( $init_resp !~ /^$NB_SESSION_ESTABLISHED/){
280 0           my $error = ord(substr($init_resp,0,1));
281 0           $error_texts .= "Warning! Session request failed.\n";
282 0           $error_texts .= "Opcode: ".$error." (0x".sprintf("%.0x", $error).")\n";
283 0           $error_texts .= "Reason: " . $NB_ERROR_TEXT{$error} . ".\n\n";
284 0           $error_texts .= $NB_ERROR_HELP{$error} . "\n";
285 0           $overall_succes=0;
286 0           return;
287             # $error_texts .= "Warning: Session request failed.\nOpcode: 0x".sprintf("%.0x", ord(substr($init_resp, 0, 1)))."\n";
288             # $overall_succes = 0;
289             # return;
290             }
291             else{
292 0 0         print "Session established.\n" if $confirm_packets;
293             }
294            
295             #Create "Start of Multi-Block Message" Packet
296 0           my $smbmrs_header = get_SMB_header($SMB_HEADER_SEND_MULTI_BLOCK_MSG_START);
297 0           my $smbmrs_body = get_SMB_body(
298             $mbsource_netbios_name_cleartext, #source
299             $mbtarget_netbios_name_cleartext, #target
300             undef, #message
301             $SMB_HEADER_SEND_MULTI_BLOCK_MSG_START #type
302             );
303            
304             #Netbios - Encapsulate "Start of Multi-Block Message" Request
305 0           my $ssbmr_packet = netbios_session_encaps($smbmrs_header.$smbmrs_body, $NB_SESSION_MESSAGE);
306            
307             #Send "Start of Multi-Block Message" Request
308 0           print $sock $ssbmr_packet;
309            
310 0           $MBM_MESSAGE_GROUP_ID = receive_and_check_answer_packet($sock,
311             "Start of Multi Block Message failed",
312             "MBM start",
313             $confirm_packets,
314             0);
315            
316             # print "\n\nGroup id: ". ord($MBM_MESSAGE_GROUP_ID) . "\n\n";
317            
318             #split message into parts
319 0           my @messageparts;
320 0           for(my $start =0; $start < length($mbmessage); $start+=128){
321 0           push @messageparts, substr($mbmessage, $start, 128);
322             }
323            
324            
325             #send each part of the message
326 0           my $teilcounter = @messageparts;
327 0           for(my $i = 0; $i < $teilcounter; $i++){
328 0           send_part_mbm($messageparts[$i], $teilcounter, $sock, $confirm_packets);
329             }
330             #$teilcounter=4;
331 0           send_mbm_end($teilcounter, $sock, $confirm_packets);
332            
333             }
334            
335             sub send_mbm_end{
336 0     0 0   my $msg_group_id = shift;
337 0           my $sock = shift;
338 0           my $confirm_packets = shift;
339            
340 0           my $smb_body = chr(0x01)
341             # . chr($msg_group_id)
342             . $MBM_MESSAGE_GROUP_ID
343             . ("\0"x3)
344             ;
345 0           my $smb_header=get_SMB_header($SMB_HEADER_SEND_MULTI_BLOCK_MSG_END);
346 0           my $mbm_packet = netbios_session_encaps($smb_header.$smb_body, $NB_SESSION_MESSAGE);
347 0           print $sock $mbm_packet;
348 0           receive_and_check_answer_packet($sock, "End of multi block message request failed", "MBM end", $confirm_packets, 0);
349             }
350            
351             sub send_part_mbm{
352 0     0 0   my ($msg, $teilcounter, $sock, $confirm_packets) = @_;
353 0           my $smb_multi_header = get_SMB_header($SMB_HEADER_SEND_MULTI_BLOCK_MSG_TEXT);
354 0           my $smb_multi_body =
355             chr(0x01) #Word Count
356             . $MBM_MESSAGE_GROUP_ID . "\0" #Group ID alias "Byte Count"
357             . chr(length($msg)+3) #Not "Buffer format" but message length plus 3!
358             . "\0" . chr(0x01) #Message Length??? = 256???
359             . chr(length($msg)) #Not "Buffer format" but exact message length!
360             . "\0" #unknown
361             . $msg #Message text
362             ;
363            
364 0           my $mbm_packet = netbios_session_encaps($smb_multi_header.$smb_multi_body, $NB_SESSION_MESSAGE);
365 0           select(undef, undef, undef, 0.05); #0.05 sec sleep
366 0           print $sock $mbm_packet;
367            
368 0           receive_and_check_answer_packet($sock, "Part of multi block message request failed", "MBM text", $confirm_packets, 0);
369            
370             }
371            
372             sub receive_and_check_answer_packet{
373            
374 0     0 0   my $sock = shift;
375 0           my $warning = shift;
376 0           my $packet_desc = shift;
377 0           my $confirm_success = shift;
378 0           my $die = shift;
379            
380 0           my $resp="";
381 0           my $inmask='';
382 0           vec($inmask, fileno($sock), 1)=1;
383 0           select(my $outmask = $inmask, undef, undef, 0.25);
384 0           recv($sock, $resp,1024, 0);
385            
386 0 0         if (length($resp) < 10){
387             # crippled or no answer received
388 0           my $error = "No answer from remote Host";
389 0           $error_texts .= "Warning: $warning.\n$error\n";
390 0           $overall_succes=0;
391 0 0         die if $die;
392 0           return -1;
393             }
394            
395 0 0         if(substr($resp,9,1) ne $SMB_HEADER_ERROR_CLASS_SUCCESS){
396 0           my $error = ord(substr($resp,9,1));
397 0           $error_texts .= "Warning: $warning.\n";
398 0           $error_texts .= "Opcode: ". $error ." (0x".sprintf("%.0x", $error).")\n";
399 0           $overall_succes=0;
400 0 0         die if $die;
401             }
402             else{
403 0 0         print "$packet_desc ACKed.\n" if $confirm_success;
404             }
405            
406 0           return substr($resp, -4, 1);
407             #return Message Group ID (needed for all MBM packets except start)
408             }
409            
410             sub send_single_block_message{
411 0     0 0   my $sbmessage = shift;
412 0           my $target_ip = shift;
413 0           my $target_port = shift;
414 0           my $target_netbios_name_cleartext = shift;
415 0           my $source_netbios_name_cleartext = shift;
416 0           my $confirm_packets = shift;
417            
418            
419 0           my $target_netbios_name_cipher = get_nb_string($target_netbios_name_cleartext);
420 0           my $source_netbios_name_cipher = get_nb_string($source_netbios_name_cleartext);
421            
422            
423 0           my $init_packet = $SESSION_REQUEST . $INIT_SESSION_FLAGS .
424             get_2bytes_length($target_netbios_name_cipher.$source_netbios_name_cipher) .
425             $target_netbios_name_cipher . $source_netbios_name_cipher;
426            
427             #send $init_packet
428             #receive answer
429 0           my $ssbmr_header = get_SMB_header($SMB_HEADER_SEND_SINGLE_BLOCK_MSG);
430 0           my $ssbmr_body = get_SMB_body($source_netbios_name_cleartext,
431             $target_netbios_name_cleartext,
432             $sbmessage,
433             $SMB_HEADER_SEND_SINGLE_BLOCK_MSG);
434 0           my $ssbmr_packet = $ssbmr_header . $ssbmr_body;
435 0           $ssbmr_packet = netbios_session_encaps($ssbmr_packet, $NB_SESSION_MESSAGE);
436             #print_to_file("c:\\test.log", $ssbmr_header.$ssbmr_body);
437             #send ssbmr
438            
439            
440             #####################################
441             # Create Socket #
442             #####################################
443 0           my $proto = getprotobyname("tcp");
444 0 0         my $host = inet_aton($target_ip) or die "Unknown host: $target_ip\n";
445 0           my $sock;
446 0 0         socket($sock, AF_INET, SOCK_STREAM, $proto) or die "Could not create socket. Socket() failed: $!\n";
447 0           my $dest_addr = sockaddr_in($target_port, $host);
448            
449 0 0         connect($sock, $dest_addr)
450             or die "connect() of socket to $target_netbios_name_cleartext (IP: $target_ip) failed: $!\n";
451 0           $sock->autoflush(1);
452            
453             #####################################
454             # Send Session Request (init_packet)#
455             #####################################
456            
457 0           print $sock $init_packet;
458            
459             #####################################
460             # Receive & Check Answer #
461             #####################################
462            
463            
464 0           my $init_resp="";
465 0           my $answer_received=0;
466 0           my $inmask = '';
467 0           vec($inmask, fileno($sock), 1) = 1;
468 0           while (select(my $outmask = $inmask, undef, undef, 0.4)) {
469 0           recv($sock, $init_resp, 1024, 0);
470 0           $answer_received = 1;
471             }
472            
473 0 0         if(!$answer_received){
474 0 0         if($confirm_packets){
475 0           print "Timeout while waiting for answer from $target_ip.\n"
476             }
477 0           return 0;
478             }
479            
480            
481            
482            
483             # my $init_resp="";
484             # my $inmask='';
485             # vec($inmask, fileno($sock), 1)=1;
486             # select(my $outmask = $inmask, undef, undef, 0.25);
487             # recv($sock, $init_resp,1024, 0);
488             #print "Daten empfangen: $init_resp\n";
489             #print_to_file("c:\\test.log", $init_resp);
490            
491 0 0         if( $init_resp !~ /^$NB_SESSION_ESTABLISHED/){
492 0           my $error = ord(substr($init_resp,0,1));
493 0           $error_texts .= "Warning! Session request failed.\n";
494 0           $error_texts .= "Opcode: ".$error." (0x".sprintf("%.0x", $error).")\n";
495 0           $error_texts .= "Reason: " . $NB_ERROR_TEXT{$error} . ".\n";
496 0           $error_texts .= $NB_ERROR_HELP{$error} . "\n";
497 0           $overall_succes=0;
498 0           return;
499             }
500             else{
501 0 0         print "Session established.\n" if $confirm_packets;
502             }
503            
504             #####################################
505             # Send Single Block Message (ssbmr) #
506             #####################################
507            
508 0           print $sock $ssbmr_packet;
509            
510 0           receive_and_check_answer_packet($sock, "Single block message request failed", "SBM Message", $confirm_packets, 0);
511            
512             #################################
513             # END OF SUB :-D #
514             #################################
515             }
516            
517             sub netbios_session_encaps{
518 0     0 0   my $smb_packet=shift;
519 0           my $enctype=shift;
520 0 0         die "Unsupported encoding type in netbios_session_encaps()" if $enctype ne $NB_SESSION_MESSAGE;
521 0           return $enctype . $INIT_SESSION_FLAGS . get_2bytes_length($smb_packet) . $smb_packet;
522             }
523            
524            
525             sub get_SMB_body{
526 0     0 0   my $source=shift;
527 0           my $target=shift;
528 0           my $message=shift;
529 0           my $type = shift;
530            
531 0           my $body;
532 0           $body .= $SMB_SSBMR_BUFFER_ASCII;
533 0           $body .= $source."\0";
534 0           $body .= $SMB_SSBMR_BUFFER_ASCII;
535 0           $body .= $target . "\0";
536 0 0         if($type eq $SMB_HEADER_SEND_SINGLE_BLOCK_MSG){
537             #add a buffer with the message to packet
538             #not needed for a multi-msg start or end packet
539 0           $body .= $SMB_SSBMR_BUFFER_DATA_BLOCK;
540 0           $body .= swap_bytes(get_2bytes_length($message));
541 0           $body .= $message;
542             }
543             #now prepend the body with Word Count (WCT) and Byte Count (BCC)
544             #ONLY VALID for single block messages and start of multi block messages
545 0           my $wordcount = "\0";
546 0           my $bytecount = swap_bytes(get_2bytes_length($body));
547 0           $body=$wordcount . $bytecount . $body;
548             }
549            
550            
551            
552            
553            
554             sub get_nb_string{
555 0     0 0   return ms_adjust_fle(first_level_encode(shift));
556             }
557            
558             sub ms_adjust_fle{
559             #chr(0x20) is at position -1
560 0     0 0   my $fle=shift;
561 0           chop $fle;
562 0           chop $fle;
563 0           $fle.=chr(0x41).chr(0x44)."\0";
564 0           return chr(0x20) . $fle;
565             }
566            
567             sub print_to_file{
568 0     0 0   my $path = shift;
569 0           my $string = shift;
570 0 0         if(shift){
571 0           open OUT, ">>$path";
572 0           print OUT $string;
573 0           close OUT;
574             }
575             else{
576 0           open OUT, ">$path";
577 0           print OUT $string;
578 0           close OUT;
579             }
580             }
581            
582             sub get_2bytes_length{
583 0     0 0   my $string=shift;
584 0 0         if (length($string) > 0xFF){
585 0           my $first = floor(length($string)/0x100);
586 0           my $second = length($string)-$first;
587 0           return chr($first).chr($second);
588             }
589 0           return "\0".chr(length($string));
590             }
591            
592             sub swap_bytes{
593 0     0 0   my $count = shift;
594 0           my $first = substr($count, 0, 1);
595 0           my $second = substr($count, 1, 1);
596 0           return ($second.$first);
597             }
598            
599             sub print_hex{
600 0     0 0   my $string = shift;
601 0           print "\nph:\n";
602 0           for(my $i=-1; $i
603 0           print substr($string, $i, 1), " ", sprintf("%.0x", ord(substr($string, $i, 1))), "\n";
604             }
605 0           print "\nende ph\n";
606             }
607            
608             sub first_level_encode{ #see RFC 1001, Section 14.1.
609 0   0 0 0   my $net_name = uc(shift) || die "first_level_encode called without params.\n";
610 0   0       my $debug=shift || 0;
611 0           my $encoded_name="";
612             #size < 16 => pad with blanks
613 0           $net_name .= " "x 16;
614 0           $net_name=substr($net_name, 0, 16);
615 0           my $char;
616 0           for(my $i=0; $i<16; $i++){
617 0           $char=substr($net_name, $i, 1);
618 0 0         if($debug){print "Char: ".$char." ";}
  0            
619 0           my $first =floor(ord($char)/16);
620 0           my $second=ord($char) - 16*$first;
621 0           $first =chr($first+0x41);
622 0           $second =chr($second+0x41);
623 0           $encoded_name.=$first.$second;
624 0 0         if($debug){print "$first$second\n";}
  0            
625             }
626 0           return $encoded_name;
627             }
628            
629             sub get_SMB_header{
630 0     0 0   my $type=shift;
631 0 0 0       die("Unknown SMB Header Type requested") if (
      0        
      0        
632             $type ne $SMB_HEADER_SEND_SINGLE_BLOCK_MSG &&
633             $type ne $SMB_HEADER_SEND_MULTI_BLOCK_MSG_START &&
634             $type ne $SMB_HEADER_SEND_MULTI_BLOCK_MSG_TEXT &&
635             $type ne $SMB_HEADER_SEND_MULTI_BLOCK_MSG_END
636             );
637 0           my $header = $SMB_HEADER_SERVER_COMPONENT_SMB .
638             $type .
639             $SMB_HEADER_ERROR_CLASS_SUCCESS .
640             $SMB_HEADER_RESERVED .
641             $SMB_HEADER_ERRORCODE_NO_ERROR .
642             $SMB_HEADER_FLAGS_DEFAULT .
643             $SMB_HEADER_FLAGS2_DEFAULT .
644             $SMB_HEADER_PROCESS_ID_HIGH_FALSE .
645             $SMB_HEADER_SIGNATURE .
646             $SMB_HEADER_RESERVED2 .
647             $SMB_HEADER_TREE_ID .
648             $SMB_HEADER_PROCESS_ID .
649             $SMB_HEADER_USER_ID .
650             $SMB_HEADER_MULTIPLEX_ID;
651 0           return $header;
652             }
653            
654             sub hexdump{
655 0     0 0   my $text = shift;
656 0           my $hexdump = "";
657 0           for(my $i = 1; $i <= length($text); $i++){
658 0           $hexdump .= two(sprintf("%.0x", ord(substr($text, $i-1, 1))));
659 0 0         $hexdump .= "00" if substr($text, $i-1, 1) eq chr(0x00);
660 0           $hexdump .= " ";
661 0 0 0       $hexdump .= "\n" if ($i % 8 == 0 && $i != 0);
662             }
663 0           return $hexdump;
664             }
665            
666             sub two{
667 0     0 0   my $param = shift;
668 0 0         return "0".$param if length($param)==1;
669 0           return $param;
670             }
671            
672             #END{
673             # print $error_texts;
674             #}
675            
676            
677            
678             1;
679             __END__