1 17 package org.alfresco.filesys.netbios; 18 19 import java.io.DataInputStream ; 20 import java.io.DataOutputStream ; 21 import java.io.IOException ; 22 import java.net.DatagramPacket ; 23 import java.net.DatagramSocket ; 24 import java.net.InetAddress ; 25 import java.net.Socket ; 26 import java.net.SocketException ; 27 import java.net.UnknownHostException ; 28 import java.util.Vector ; 29 30 import org.alfresco.filesys.smb.NetworkSession; 31 import org.alfresco.filesys.util.DataPacker; 32 import org.alfresco.filesys.util.HexDump; 33 import org.alfresco.filesys.util.StringList; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 37 40 public final class NetBIOSSession implements NetworkSession 41 { 42 private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.netbios"); 43 44 48 public static final int MaxCallerNameTemplateLength = 8; 49 public static final char SessionIdChar = '#'; 50 public static final char JVMIdChar = '@'; 51 public static final String ValidTemplateChars = "@#_"; 52 53 55 private static final int FindNameBufferSize = 2048; 56 57 59 private static int _defTimeout = RFCNetBIOSProtocol.TMO; 60 61 63 private int m_remotePort; 64 65 67 private Socket m_nbSocket; 68 69 71 private DataInputStream m_nbIn; 72 private DataOutputStream m_nbOut; 73 74 76 private int m_tmo = _defTimeout; 77 78 80 private char m_locNameType = NetBIOSName.FileServer; 81 private char m_remNameType = NetBIOSName.FileServer; 82 83 85 private static int m_sessIdx = 0; 86 87 91 private static int m_jvmIdx = 0; 92 93 109 private static String m_callerTemplate = "_##"; 110 111 113 private static String m_localNamePart; 114 115 117 private static short m_tranIdx = 1; 118 119 121 private static DatagramSocket m_dgramSock = null; 122 123 125 private static boolean m_debug = false; 126 127 129 private static String m_subnetMask = null; 130 131 133 private static InetAddress m_winsServer; 134 135 137 public static final int DNSOnly = 1; 138 public static final int WINSOnly = 2; 139 public static final int WINSAndDNS = 3; 140 141 143 private static int m_lookupType = WINSAndDNS; 144 145 147 private static int m_lookupTmo = 500; 148 149 151 private static boolean m_useWildcardFileServer = true; 152 153 157 public NetBIOSSession() 158 { 159 m_remotePort = RFCNetBIOSProtocol.PORT; 160 m_nbSocket = null; 161 } 162 163 168 public NetBIOSSession(int tmo) 169 { 170 m_tmo = tmo; 171 m_remotePort = RFCNetBIOSProtocol.PORT; 172 m_nbSocket = null; 173 } 174 175 181 public NetBIOSSession(int tmo, int port) 182 { 183 m_tmo = tmo; 184 m_remotePort = port; 185 m_nbSocket = null; 186 } 187 188 193 public final String getProtocolName() 194 { 195 return "TCP/IP NetBIOS"; 196 } 197 198 203 public final boolean isConnected() 204 { 205 206 208 if (m_nbSocket == null) 209 return false; 210 return true; 211 } 212 213 219 public final boolean hasData() throws IOException 220 { 221 222 224 if (m_nbSocket == null || m_nbIn == null) 225 return false; 226 227 229 return m_nbIn.available() > 0 ? true : false; 230 } 231 232 238 public static String ConvertName(String hostName) 239 { 240 return ConvertName(hostName, NetBIOSName.FileServer); 241 } 242 243 250 public static String ConvertName(String hostName, char nameType) 251 { 252 253 256 StringBuffer hName = new StringBuffer (hostName.toUpperCase()); 257 258 if (hName.length() > 15) 259 hName.setLength(15); 260 261 263 while (hName.length() < 15) 264 hName.append(' '); 265 hName.append(nameType); 266 267 269 String convstr = new String ("ABCDEFGHIJKLMNOP"); 270 StringBuffer nameBuf = new StringBuffer (32); 271 272 int idx = 0; 273 274 while (idx < hName.length()) 275 { 276 277 279 char ch = hName.charAt(idx++); 280 281 if (ch == ' ') 282 { 283 284 286 nameBuf.append("CA"); 287 } 288 else 289 { 290 291 293 nameBuf.append(convstr.charAt((int) ch / 16)); 294 nameBuf.append(convstr.charAt((int) ch % 16)); 295 } 296 297 } 299 301 return nameBuf.toString(); 302 } 303 304 311 public static String DecodeName(byte[] buf, int off) 312 { 313 314 316 String convstr = new String ("ABCDEFGHIJKLMNOP"); 317 StringBuffer nameBuf = new StringBuffer (16); 318 319 int idx = 0; 320 char ch1, ch2; 321 322 while (idx < 32) 323 { 324 325 327 ch1 = (char) buf[off + idx]; 328 ch2 = (char) buf[off + idx + 1]; 329 330 if (ch1 == 'C' && ch2 == 'A') 331 { 332 333 335 nameBuf.append(' '); 336 } 337 else 338 { 339 340 342 int val = convstr.indexOf(ch1) << 4; 343 val += convstr.indexOf(ch2); 344 345 347 nameBuf.append((char) (val & 0xFF)); 348 } 349 350 352 idx += 2; 353 354 } 356 358 return nameBuf.toString(); 359 } 360 361 367 368 public static String DecodeName(String encnam) 369 { 370 371 373 if (encnam == null || encnam.length() != 32) 374 return ""; 375 376 378 String convstr = new String ("ABCDEFGHIJKLMNOP"); 379 StringBuffer nameBuf = new StringBuffer (16); 380 381 int idx = 0; 382 char ch1, ch2; 383 384 while (idx < 32) 385 { 386 387 389 ch1 = encnam.charAt(idx); 390 ch2 = encnam.charAt(idx + 1); 391 392 if (ch1 == 'C' && ch2 == 'A') 393 { 394 395 397 nameBuf.append(' '); 398 } 399 else 400 { 401 402 404 int val = convstr.indexOf(ch1) << 4; 405 val += convstr.indexOf(ch2); 406 407 409 nameBuf.append((char) (val & 0xFF)); 410 } 411 412 414 idx += 2; 415 416 } 418 420 return nameBuf.toString(); 421 } 422 423 432 public static int EncodeName(String hostName, char nameType, byte[] buf, int off) 433 { 434 435 438 StringBuffer hName = new StringBuffer (hostName.toUpperCase()); 439 440 if (hName.length() > 15) 441 hName.setLength(15); 442 443 445 while (hName.length() < 15) 446 hName.append(' '); 447 hName.append(nameType); 448 449 451 String convstr = new String ("ABCDEFGHIJKLMNOP"); 452 int idx = 0; 453 int bufpos = off; 454 455 457 buf[bufpos++] = 0x20; 458 459 461 while (idx < hName.length()) 462 { 463 464 466 char ch = hName.charAt(idx++); 467 468 if (ch == ' ') 469 { 470 471 473 buf[bufpos++] = (byte) 'C'; 474 buf[bufpos++] = (byte) 'A'; 475 } 476 else 477 { 478 479 481 buf[bufpos++] = (byte) convstr.charAt((int) ch / 16); 482 buf[bufpos++] = (byte) convstr.charAt((int) ch % 16); 483 } 484 485 } 487 489 buf[bufpos++] = 0; 490 return bufpos; 491 } 492 493 502 public static NetBIOSName FindName(String nbName, char nbType, int tmo) throws java.io.IOException 503 { 504 505 507 return FindName(new NetBIOSName(nbName, nbType, false), tmo); 508 } 509 510 518 public static NetBIOSName FindName(NetBIOSName nbName, int tmo) throws java.io.IOException 519 { 520 521 523 InetAddress locAddr = InetAddress.getLocalHost(); 524 525 527 if (m_dgramSock == null) 528 { 529 530 532 m_dgramSock = new DatagramSocket (); 533 } 534 535 537 m_dgramSock.setSoTimeout(tmo); 538 539 541 NetBIOSPacket nbpkt = new NetBIOSPacket(); 542 nbpkt.buildNameQueryRequest(nbName, m_tranIdx++); 543 544 546 String locIP = locAddr.getHostAddress(); 547 int dotIdx = locIP.indexOf('.'); 548 if (dotIdx == -1) 549 return null; 550 551 554 InetAddress destAddr = null; 555 556 if (hasWINSServer() == false) 557 { 558 559 561 if (getSubnetMask() == null) 562 GenerateSubnetMask(null); 563 564 566 destAddr = InetAddress.getByName(getSubnetMask()); 567 } 568 else 569 { 570 571 573 destAddr = getWINSServer(); 574 } 575 576 578 DatagramPacket dgram = new DatagramPacket (nbpkt.getBuffer(), nbpkt.getLength(), destAddr, 579 RFCNetBIOSProtocol.NAME_PORT); 580 581 583 byte[] rxbuf = new byte[FindNameBufferSize]; 584 DatagramPacket rxdgram = new DatagramPacket (rxbuf, rxbuf.length); 585 586 588 NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); 589 590 592 if (m_debug) 593 nbpkt.DumpPacket(false); 594 595 597 m_dgramSock.send(dgram); 598 599 601 boolean rxOK = false; 602 603 do 604 { 605 606 608 m_dgramSock.receive(rxdgram); 609 610 612 if (logger.isDebugEnabled() && m_debug) 613 { 614 logger.debug("NetBIOS: Rx Datagram"); 615 rxpkt.DumpPacket(false); 616 } 617 618 620 if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY) 621 rxOK = true; 622 623 } while (!rxOK); 624 625 627 NetBIOSNameList nameList = rxpkt.getAnswerNameList(); 628 if (nameList != null && nameList.numberOfNames() > 0) 629 return nameList.getName(0); 630 return null; 631 } 632 633 642 public static StringList FindNameList(String nbName, char nbType, int tmo) throws IOException 643 { 644 645 647 InetAddress locAddr = InetAddress.getLocalHost(); 648 649 651 if (m_dgramSock == null) 652 { 653 654 656 m_dgramSock = new DatagramSocket (); 657 } 658 659 661 m_dgramSock.setSoTimeout(tmo); 662 663 665 NetBIOSPacket nbpkt = new NetBIOSPacket(); 666 667 nbpkt.setTransactionId(m_tranIdx++); 668 nbpkt.setOpcode(NetBIOSPacket.NAME_QUERY); 669 nbpkt.setFlags(NetBIOSPacket.FLG_BROADCAST); 670 nbpkt.setQuestionCount(1); 671 nbpkt.setQuestionName(nbName, nbType, NetBIOSPacket.NAME_TYPE_NB, NetBIOSPacket.NAME_CLASS_IN); 672 673 675 String locIP = locAddr.getHostAddress(); 676 int dotIdx = locIP.indexOf('.'); 677 if (dotIdx == -1) 678 return null; 679 680 683 InetAddress destAddr = null; 684 685 if (hasWINSServer() == false) 686 { 687 688 690 if (getSubnetMask() == null) 691 GenerateSubnetMask(null); 692 693 695 destAddr = InetAddress.getByName(getSubnetMask()); 696 } 697 else 698 { 699 700 702 destAddr = getWINSServer(); 703 } 704 705 707 DatagramPacket dgram = new DatagramPacket (nbpkt.getBuffer(), nbpkt.getLength(), destAddr, 708 RFCNetBIOSProtocol.NAME_PORT); 709 710 712 byte[] rxbuf = new byte[FindNameBufferSize]; 713 DatagramPacket rxdgram = new DatagramPacket (rxbuf, rxbuf.length); 714 715 717 NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); 718 719 721 if (m_debug) 722 nbpkt.DumpPacket(false); 723 724 726 Vector <InetAddress > addrList = new Vector <InetAddress >(); 727 728 730 long endTime = System.currentTimeMillis() + tmo; 731 732 734 m_dgramSock.send(dgram); 735 736 738 do 739 { 740 741 743 try 744 { 745 m_dgramSock.receive(rxdgram); 746 747 749 if (logger.isDebugEnabled() && m_debug) 750 { 751 logger.debug("NetBIOS: Rx Datagram"); 752 rxpkt.DumpPacket(false); 753 } 754 755 757 if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY) 758 { 759 760 763 addrList.add(rxdgram.getAddress()); 764 } 765 } 766 catch (java.io.IOException ex) 767 { 768 769 771 if (logger.isDebugEnabled() && m_debug) 772 logger.debug(ex.toString()); 773 } 774 775 } while (System.currentTimeMillis() < endTime); 776 777 779 if (addrList.size() == 0) 780 return null; 781 782 784 StringList nameList = new StringList(); 785 786 788 for (int i = 0; i < addrList.size(); i++) 789 { 790 791 793 InetAddress addr = addrList.elementAt(i); 794 795 797 String name = NetBIOSName(addr.getHostName()); 798 799 801 if (!nameList.containsString(name)) 802 nameList.addString(name); 803 } 804 805 807 return nameList; 808 } 809 810 816 public static NetBIOSNameList FindNamesForAddress(String ipAddr) throws UnknownHostException , SocketException 817 { 818 819 821 if (m_dgramSock == null) 822 { 823 824 826 m_dgramSock = new DatagramSocket (); 827 } 828 829 831 m_dgramSock.setSoTimeout(2000); 832 833 835 NetBIOSPacket nbpkt = new NetBIOSPacket(); 836 837 nbpkt.setTransactionId(m_tranIdx++); 838 nbpkt.setOpcode(NetBIOSPacket.NAME_QUERY); 839 nbpkt.setFlags(NetBIOSPacket.FLG_BROADCAST); 840 nbpkt.setQuestionCount(1); 841 nbpkt.setQuestionName("*\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NetBIOSName.WorkStation, NetBIOSPacket.NAME_TYPE_NBSTAT, 842 NetBIOSPacket.NAME_CLASS_IN); 843 844 846 InetAddress destAddr = InetAddress.getByName(ipAddr); 847 DatagramPacket dgram = new DatagramPacket (nbpkt.getBuffer(), nbpkt.getLength(), destAddr, 848 RFCNetBIOSProtocol.NAME_PORT); 849 850 852 byte[] rxbuf = new byte[FindNameBufferSize]; 853 DatagramPacket rxdgram = new DatagramPacket (rxbuf, rxbuf.length); 854 855 857 NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); 858 859 861 if (logger.isDebugEnabled() && m_debug) 862 nbpkt.DumpPacket(false); 863 864 866 NetBIOSNameList nameList = null; 867 868 try 869 { 870 871 873 m_dgramSock.send(dgram); 874 875 877 m_dgramSock.receive(rxdgram); 878 879 881 if (logger.isDebugEnabled() && m_debug) 882 { 883 logger.debug("NetBIOS: Rx Datagram"); 884 rxpkt.DumpPacket(false); 885 } 886 887 889 if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY && rxpkt.getAnswerCount() >= 1) 890 { 891 892 894 nameList = rxpkt.getAdapterStatusNameList(); 895 896 898 if( nameList != null) 899 { 900 for ( int i = 0; i < nameList.numberOfNames(); i++) 901 { 902 NetBIOSName nbName = nameList.getName(i); 903 nbName.addIPAddress(destAddr.getAddress()); 904 } 905 } 906 } 907 } 908 catch (java.io.IOException ex) 909 { 910 911 913 if (logger.isDebugEnabled() && m_debug) 914 logger.debug(ex.toString()); 915 916 918 throw new UnknownHostException (ipAddr); 919 } 920 921 923 return nameList; 924 } 925 926 931 public static String GenerateSubnetMask(String addr) throws java.net.UnknownHostException 932 { 933 934 936 String localIP = addr; 937 938 940 if (localIP == null) 941 localIP = InetAddress.getLocalHost().getHostAddress(); 942 943 945 int dotPos = localIP.indexOf('.'); 946 if (dotPos != -1) 947 { 948 949 951 String ipStr = localIP.substring(0, dotPos); 952 int ipVal = Integer.valueOf(ipStr).intValue(); 953 954 956 if (ipVal <= 127) 957 { 958 959 961 m_subnetMask = "" + ipVal + ".255.255.255"; 962 } 963 else if (ipVal <= 191) 964 { 965 966 968 dotPos++; 969 while (localIP.charAt(dotPos) != '.' && dotPos < localIP.length()) 970 dotPos++; 971 972 if (dotPos < localIP.length()) 973 m_subnetMask = localIP.substring(0, dotPos) + ".255.255"; 974 } 975 else if (ipVal <= 223) 976 { 977 978 980 dotPos++; 981 int dotCnt = 1; 982 983 while (dotCnt < 3 && dotPos < localIP.length()) 984 { 985 986 988 if (localIP.charAt(dotPos++) == '.') 989 dotCnt++; 990 } 991 992 if (dotPos < localIP.length()) 993 m_subnetMask = localIP.substring(0, dotPos - 1) + ".255"; 994 } 995 } 996 997 1000 if (m_subnetMask == null) 1001 { 1002 1003 1006 m_subnetMask = "255.255.255.255"; 1007 } 1008 1009 1011 if (logger.isDebugEnabled() && m_debug) 1012 logger.debug("NetBIOS: Set subnet mask to " + m_subnetMask); 1013 1014 1016 return m_subnetMask; 1017 } 1018 1019 1024 public static int getLookupTimeout() 1025 { 1026 return m_lookupTmo; 1027 } 1028 1029 1035 public static int getLookupType() 1036 { 1037 return m_lookupType; 1038 } 1039 1040 1045 public static String getSubnetMask() 1046 { 1047 return m_subnetMask; 1048 } 1049 1050 1055 public final static boolean hasWINSServer() 1056 { 1057 return m_winsServer != null ? true : false; 1058 } 1059 1060 1065 public final static InetAddress getWINSServer() 1066 { 1067 return m_winsServer; 1068 } 1069 1070 1075 public static boolean isDebug() 1076 { 1077 return m_debug; 1078 } 1079 1080 1085 private final static synchronized int getSessionId() 1086 { 1087 return m_sessIdx++; 1088 } 1089 1090 1095 public final static int getJVMIndex() 1096 { 1097 return m_jvmIdx; 1098 } 1099 1100 1106 public static String NetBIOSName(String hostName) 1107 { 1108 1109 1111 String nbName = new String (hostName.toUpperCase()); 1112 int pos = nbName.indexOf("."); 1113 1114 if (pos != -1) 1115 { 1116 1117 1119 nbName = nbName.substring(0, pos); 1120 } 1121 1122 1124 return nbName; 1125 } 1126 1127 1132 public static void setDebug(boolean dbg) 1133 { 1134 m_debug = dbg; 1135 } 1136 1137 1142 public static void setLookupTimeout(int tmo) 1143 { 1144 if (tmo >= 250) 1145 m_lookupTmo = tmo; 1146 } 1147 1148 1154 public static void setLookupType(int typ) 1155 { 1156 if (typ >= DNSOnly && typ <= WINSAndDNS) 1157 m_lookupType = typ; 1158 } 1159 1160 1165 public static void setSubnetMask(String subnet) 1166 { 1167 m_subnetMask = subnet; 1168 } 1169 1170 1175 public final static void setWINSServer(InetAddress addr) 1176 { 1177 m_winsServer = addr; 1178 } 1179 1180 1186 private static Vector AdapterStatus(String nodeName) throws java.io.IOException 1187 { 1188 1189 1191 DatagramSocket nameSock = new DatagramSocket (); 1192 1193 1195 nameSock.setSoTimeout(2000); 1196 1197 1199 NetBIOSPacket nbpkt = new NetBIOSPacket(); 1200 1201 nbpkt.setTransactionId(9999); 1203 nbpkt.setOpcode(NetBIOSPacket.NAME_QUERY); 1204 nbpkt.setFlags(NetBIOSPacket.FLG_BROADCAST); 1205 nbpkt.setQuestionCount(1); 1206 nbpkt.setQuestionName(nodeName, NetBIOSName.WorkStation, NetBIOSPacket.NAME_TYPE_NBSTAT, 1207 NetBIOSPacket.NAME_CLASS_IN); 1208 1209 1211 InetAddress destAddr = InetAddress.getByName(nodeName); 1212 DatagramPacket dgram = new DatagramPacket (nbpkt.getBuffer(), nbpkt.getLength(), destAddr, 1213 RFCNetBIOSProtocol.NAME_PORT); 1214 1215 1217 byte[] rxbuf = new byte[512]; 1218 DatagramPacket rxdgram = new DatagramPacket (rxbuf, rxbuf.length); 1219 1220 1222 NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); 1223 1224 1226 if (logger.isDebugEnabled() && m_debug) 1227 nbpkt.DumpPacket(false); 1228 1229 1231 nameSock.send(dgram); 1232 1233 1235 boolean rxOK = false; 1236 1237 do 1238 { 1239 1240 1242 nameSock.receive(rxdgram); 1243 1244 1246 if (logger.isDebugEnabled() && m_debug) 1247 { 1248 logger.debug("NetBIOS: Rx Datagram"); 1249 rxpkt.DumpPacket(false); 1250 } 1251 1252 1254 if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY) 1255 rxOK = true; 1256 1257 } while (!rxOK); 1258 1259 1261 return null; 1262 } 1263 1264 1274 public void Open(String remHost, String locName, String remAddr) throws java.io.IOException , 1275 java.net.UnknownHostException 1276 { 1277 1278 1280 if (logger.isDebugEnabled() && m_debug) 1281 logger.debug("NetBIOS: Call " + remHost); 1282 1283 1285 boolean dnsLookup = false; 1286 InetAddress addr = null; 1287 1288 1290 if (remAddr != null) 1291 { 1292 1293 1295 addr = InetAddress.getByName(remAddr); 1296 } 1297 else 1298 { 1299 1300 1302 if (getLookupType() != DNSOnly) 1303 { 1304 try 1305 { 1306 NetBIOSName netName = FindName(remHost, NetBIOSName.FileServer, 500); 1307 if (netName != null && netName.numberOfAddresses() > 0) 1308 addr = InetAddress.getByName(netName.getIPAddressString(0)); 1309 } 1310 catch (Exception ex) 1311 { 1312 } 1313 } 1314 1315 1317 if (addr == null && getLookupType() != WINSOnly) 1318 { 1319 addr = InetAddress.getByName(remHost); 1320 dnsLookup = true; 1321 } 1322 } 1323 1324 1326 if (addr == null) 1327 throw new java.net.UnknownHostException (remHost); 1328 1329 1331 if (logger.isDebugEnabled() && m_debug) 1332 logger.debug("NetBIOS: Remote node hase address " + addr.getHostAddress() + " (" 1333 + (dnsLookup ? "DNS" : "WINS") + ")"); 1334 1335 1337 String remoteName = null; 1338 1339 if (getRemoteNameType() == NetBIOSName.FileServer && useWildcardFileServerName() == true) 1340 remoteName = "*SMBSERVER"; 1341 else 1342 remoteName = remHost; 1343 1344 1346 int resp = openSession(remoteName, addr); 1347 1348 1350 if (resp == RFCNetBIOSProtocol.SESSION_ACK) 1351 return; 1352 else if (resp == RFCNetBIOSProtocol.SESSION_REJECT) 1353 { 1354 1355 1357 if (remoteName.equals(remHost) == false) 1358 resp = openSession(remHost, addr); 1359 1360 1362 if (resp == RFCNetBIOSProtocol.SESSION_ACK) 1363 return; 1364 1365 1367 throw new java.io.IOException ("NetBIOS session reject"); 1368 } 1369 else if (resp == RFCNetBIOSProtocol.SESSION_RETARGET) 1370 throw new java.io.IOException ("NetBIOS ReTarget"); 1371 1372 1374 Close(); 1375 throw new java.io.IOException ("Invalid NetBIOS response, 0x" + Integer.toHexString(resp)); 1376 } 1377 1378 1386 private final int openSession(String remoteName, InetAddress addr) throws IOException 1387 { 1388 1389 1391 m_nbSocket = new Socket (addr, m_remotePort); 1392 1393 1395 m_nbSocket.setSoTimeout(m_tmo); 1396 m_nbSocket.setTcpNoDelay(true); 1397 1398 1400 m_nbIn = new DataInputStream (m_nbSocket.getInputStream()); 1401 m_nbOut = new DataOutputStream (m_nbSocket.getOutputStream()); 1402 1403 1405 byte[] inpkt = new byte[RFCNetBIOSProtocol.SESSRESP_LEN]; 1406 1407 1409 NetBIOSName fromName = createUniqueCallerName(); 1410 NetBIOSName toName = new NetBIOSName(remoteName, getRemoteNameType(), false); 1411 1412 1414 if (logger.isDebugEnabled() && m_debug) 1415 logger.debug("NetBIOS: Call from " + fromName + " to " + toName); 1416 1417 1419 NetBIOSPacket nbPkt = new NetBIOSPacket(); 1420 nbPkt.buildSessionSetupRequest(fromName, toName); 1421 1422 1424 m_nbOut.write(nbPkt.getBuffer(), 0, nbPkt.getLength()); 1425 1426 1428 int resp = -1; 1429 1430 if (m_nbIn.read(inpkt, 0, RFCNetBIOSProtocol.SESSRESP_LEN) >= RFCNetBIOSProtocol.HEADER_LEN) 1431 { 1432 1433 1435 resp = (int) (inpkt[0] & 0xFF); 1436 1437 1439 if (logger.isDebugEnabled() && m_debug) 1440 logger.debug("NetBIOS: Rx " + NetBIOSPacket.getTypeAsString(resp)); 1441 } 1442 1443 1445 if (resp != RFCNetBIOSProtocol.SESSION_ACK) 1446 { 1447 1448 1450 m_nbIn.close(); 1451 m_nbIn = null; 1452 1453 m_nbOut.close(); 1454 m_nbOut = null; 1455 1456 m_nbSocket.close(); 1457 m_nbSocket = null; 1458 } 1459 1460 1462 return resp; 1463 } 1464 1465 1470 public char getLocalNameType() 1471 { 1472 return m_locNameType; 1473 } 1474 1475 1480 public char getRemoteNameType() 1481 { 1482 return m_remNameType; 1483 } 1484 1485 1490 public int getTimeout() 1491 { 1492 return m_tmo; 1493 } 1494 1495 1500 public void Close() throws IOException 1501 { 1502 1503 1505 if (logger.isDebugEnabled() && m_debug) 1506 logger.debug("NetBIOS: HangUp"); 1507 1508 1510 if (m_nbSocket != null) 1511 { 1512 m_nbSocket.close(); 1513 m_nbSocket = null; 1514 } 1515 } 1516 1517 1525 public int Receive(byte[] buf, int tmo) throws java.io.IOException 1526 { 1527 1528 1530 if (tmo != m_tmo) 1531 { 1532 m_nbSocket.setSoTimeout(tmo); 1533 m_tmo = tmo; 1534 } 1535 1536 1538 int pkttyp; 1539 int rdlen; 1540 1541 do 1542 { 1543 1544 1546 rdlen = m_nbIn.read(buf, 0, RFCNetBIOSProtocol.HEADER_LEN); 1547 1548 1550 if (logger.isDebugEnabled() && m_debug) 1551 logger.debug("NetBIOS: Read " + rdlen + " bytes"); 1552 1553 1555 if (rdlen < RFCNetBIOSProtocol.HEADER_LEN) 1556 throw new java.io.IOException ("NetBIOS Short Read"); 1557 1558 1560 pkttyp = (int) (buf[0] & 0xFF); 1561 1562 } while (pkttyp == RFCNetBIOSProtocol.SESSION_KEEPALIVE); 1563 1564 1566 if (logger.isDebugEnabled() && m_debug) 1567 logger.debug("NetBIOS: Rx Pkt Type = " + pkttyp + ", " + Integer.toHexString(pkttyp)); 1568 1569 1571 if (pkttyp != RFCNetBIOSProtocol.SESSION_MESSAGE) 1572 throw new java.io.IOException ("NetBIOS Unknown Packet Type, " + pkttyp); 1573 1574 1576 int pktlen = (int) DataPacker.getShort(buf, 2); 1577 if (logger.isDebugEnabled() && m_debug) 1578 logger.debug("NetBIOS: Rx Data Len = " + pktlen); 1579 1580 1582 if (buf.length < (pktlen + RFCNetBIOSProtocol.HEADER_LEN)) 1583 { 1584 1585 1587 logger.debug("NetBIOS: Rx Pkt Type = " + pkttyp + ", " + Integer.toHexString(pkttyp)); 1588 logger.debug("NetBIOS: Rx Buf Too Small pkt=" + pktlen + " buflen=" + buf.length); 1589 HexDump.Dump(buf, 16, 0); 1590 1591 throw new java.io.IOException ("NetBIOS Recv Buffer Too Small (pkt=" + pktlen + "/buf=" + buf.length + ")"); 1592 } 1593 1594 1597 int totlen = 0; 1598 int offset = RFCNetBIOSProtocol.HEADER_LEN; 1599 1600 while (pktlen > 0) 1601 { 1602 1603 1605 rdlen = m_nbIn.read(buf, offset, pktlen); 1606 1607 1609 totlen += rdlen; 1610 pktlen -= rdlen; 1611 1612 1615 offset += rdlen; 1616 1617 } 1619 1621 return totlen; 1622 } 1623 1624 1632 public boolean Send(byte[] data, int siz) throws java.io.IOException 1633 { 1634 1635 1637 if (m_nbSocket == null) 1638 return false; 1639 1640 1642 if (logger.isDebugEnabled() && m_debug) 1643 logger.debug("NetBIOS: Tx " + siz + " bytes"); 1644 1645 1648 data[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE; 1649 data[1] = (byte) 0; 1650 1651 DataPacker.putShort((short) siz, data, 2); 1652 1653 1655 int bufSiz = siz + RFCNetBIOSProtocol.HEADER_LEN; 1656 m_nbOut.write(data, 0, bufSiz); 1657 return true; 1658 } 1659 1660 1665 public void setLocalNameType(char nameType) 1666 { 1667 m_locNameType = nameType; 1668 } 1669 1670 1675 public void setRemoteNameType(char nameType) 1676 { 1677 m_remNameType = nameType; 1678 } 1679 1680 1685 public void setTimeout(int tmo) 1686 { 1687 m_tmo = tmo; 1688 } 1689 1690 1697 public final static void setCallerNameTemplate(String template) throws NameTemplateException 1698 { 1699 1700 1702 if (template == null || template.length() == 0 || template.length() > MaxCallerNameTemplateLength) 1703 throw new NameTemplateException("Invalid template string, " + template); 1704 1705 1707 if (template.indexOf(SessionIdChar) == -1) 1708 throw new NameTemplateException("No session id character in template"); 1709 1710 1712 for (int i = 0; i < template.length(); i++) 1713 { 1714 if (ValidTemplateChars.indexOf(template.charAt(i)) == -1) 1715 throw new NameTemplateException("Invalid character in template, '" + template.charAt(i) + "'"); 1716 } 1717 1718 1720 m_callerTemplate = template; 1721 1722 1725 m_localNamePart = null; 1726 } 1727 1728 1734 public final static void setJVMIndex(int jvmIdx) 1735 { 1736 if (jvmIdx >= 0) 1737 m_jvmIdx = jvmIdx; 1738 } 1739 1740 1746 private final NetBIOSName createUniqueCallerName() 1747 { 1748 1749 1751 if (m_localNamePart == null) 1752 { 1753 1754 String localName = null; 1755 1756 try 1757 { 1758 localName = InetAddress.getLocalHost().getHostName(); 1759 } 1760 catch (Exception ex) 1761 { 1762 } 1763 1764 1766 int pos = localName.indexOf("."); 1767 1768 if (pos != -1) 1769 localName = localName.substring(0, pos); 1770 1771 1773 int nameLen = 16 - m_callerTemplate.length(); 1774 1775 if (localName.length() > nameLen) 1776 localName = localName.substring(0, nameLen - 1); 1777 1778 1780 m_localNamePart = localName.toUpperCase(); 1781 } 1782 1783 1785 int sessId = getSessionId(); 1786 int jvmId = getJVMIndex(); 1787 1788 1790 StringBuffer nameBuf = new StringBuffer (16); 1791 1792 nameBuf.append(m_localNamePart); 1793 1794 1796 int idx = 0; 1797 int len = -1; 1798 1799 while (idx < m_callerTemplate.length()) 1800 { 1801 1802 1804 char ch = m_callerTemplate.charAt(idx++); 1805 1806 switch (ch) 1807 { 1808 1809 1811 case SessionIdChar: 1812 len = findRepeatLength(m_callerTemplate, idx, SessionIdChar); 1813 appendZeroPaddedHexValue(sessId, len, nameBuf); 1814 idx += len - 1; 1815 break; 1816 1817 1819 case JVMIdChar: 1820 len = findRepeatLength(m_callerTemplate, idx, JVMIdChar); 1821 appendZeroPaddedHexValue(jvmId, len, nameBuf); 1822 idx += len - 1; 1823 break; 1824 1825 1827 default: 1828 nameBuf.append(ch); 1829 break; 1830 } 1831 } 1832 1833 1835 return new NetBIOSName(nameBuf.toString(), getLocalNameType(), false); 1836 } 1837 1838 1846 private final int findRepeatLength(String str, int pos, char ch) 1847 { 1848 int len = 1; 1849 1850 while (pos < str.length() && str.charAt(pos++) == ch) 1851 len++; 1852 return len; 1853 } 1854 1855 1862 private final void appendZeroPaddedHexValue(int val, int len, StringBuffer str) 1863 { 1864 1865 1867 String hex = Integer.toHexString(val); 1868 1869 1871 for (int i = 0; i < len - hex.length(); i++) 1872 str.append("0"); 1873 str.append(hex); 1874 } 1875 1876 1881 public static final int getDefaultTimeout() 1882 { 1883 return _defTimeout; 1884 } 1885 1886 1891 public static final void setDefaultTimeout(int tmo) 1892 { 1893 _defTimeout = tmo; 1894 } 1895 1896 1902 public static final boolean useWildcardFileServerName() 1903 { 1904 return m_useWildcardFileServer; 1905 } 1906 1907 1913 public static final void setWildcardFileServerName(boolean useWildcard) 1914 { 1915 m_useWildcardFileServer = useWildcard; 1916 } 1917 1918 1921 protected void finalize() 1922 { 1923 1924 1926 if (m_nbSocket != null) 1927 { 1928 try 1929 { 1930 m_nbSocket.close(); 1931 } 1932 catch (java.io.IOException ex) 1933 { 1934 } 1935 m_nbSocket = null; 1936 } 1937 } 1938} | Popular Tags |