1 17 package org.alfresco.filesys.netbios.server; 18 19 import java.io.IOException ; 20 import java.net.DatagramPacket ; 21 import java.net.DatagramSocket ; 22 import java.net.InetAddress ; 23 import java.net.SocketException ; 24 import java.util.Enumeration ; 25 import java.util.Hashtable ; 26 import java.util.Vector ; 27 28 import org.alfresco.filesys.netbios.NetBIOSName; 29 import org.alfresco.filesys.netbios.NetBIOSPacket; 30 import org.alfresco.filesys.netbios.NetworkSettings; 31 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; 32 import org.alfresco.filesys.server.NetworkServer; 33 import org.alfresco.filesys.server.ServerListener; 34 import org.alfresco.filesys.server.config.ServerConfiguration; 35 import org.apache.commons.logging.Log; 36 import org.apache.commons.logging.LogFactory; 37 38 41 public class NetBIOSNameServer extends NetworkServer implements Runnable 42 { 43 private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.netbios"); 44 45 47 private static final String ServerVersion = "3.5.0"; 48 49 51 public static final int AddNameSize = 256; 52 public static final int DeleteNameSize = 256; 53 public static final int RefreshNameSize = 256; 54 55 57 private static final int AddNameInterval = 2000; private static final int AddNameRetries = 5; 60 private static final int AddNameWINSInterval = 250; 62 64 private static final int DeleteNameInterval = 200; private static final int DeleteNameRetries = 1; 67 69 public static final int RefreshNameRetries = 2; 71 73 public static final int GroupName = 0x8000; 74 75 77 public static final int DefaultTTL = 10800; 79 81 public static final long NameRefreshWakeupInterval = 180000L; 83 85 private static int m_tranId; 86 87 89 private DatagramSocket m_socket; 90 91 93 private boolean m_shutdown; 94 95 97 private InetAddress m_bindAddress; 98 99 101 private InetAddress m_bcastAddr; 102 103 105 private int m_port = RFCNetBIOSProtocol.NAME_PORT; 106 107 109 private InetAddress m_winsPrimary; 110 private InetAddress m_winsSecondary; 111 112 114 private Vector <AddNameListener> m_addListeners; 115 116 118 private Vector <QueryNameListener> m_queryListeners; 119 120 122 private Vector <RemoteNameListener> m_remoteListeners; 123 124 126 private Vector <NetBIOSName> m_localNames; 127 128 130 private Hashtable <NetBIOSName, byte[]> m_remoteNames; 131 132 134 private Vector <NetBIOSRequest> m_reqList; 135 136 138 private NetBIOSRequestHandler m_reqHandler; 139 private NetBIOSNameRefresh m_refreshThread; 140 141 143 private Thread m_srvThread; 144 145 147 class NetBIOSRequestHandler extends Thread 148 { 149 150 152 private boolean m_hshutdown = false; 153 154 157 public NetBIOSRequestHandler() 158 { 159 setDaemon(true); 160 setName("NetBIOSRequest"); 161 } 162 163 166 public final void shutdownRequest() 167 { 168 m_hshutdown = true; 169 170 synchronized (m_reqList) 171 { 172 m_reqList.notify(); 173 } 174 } 175 176 179 public void run() 180 { 181 182 184 while (m_hshutdown == false) 185 { 186 187 try 188 { 189 190 192 NetBIOSRequest req = null; 193 194 synchronized (m_reqList) 195 { 196 197 199 if (m_reqList.size() == 0) 200 { 201 202 204 if (logger.isDebugEnabled() && hasDebug()) 205 logger.debug("NetBIOS handler waiting for request ..."); 206 207 209 m_reqList.wait(); 210 } 211 212 214 if (m_reqList.size() > 0) 215 req = m_reqList.get(0); 216 else if (m_hshutdown == true) 217 break; 218 } 219 220 222 int reqRetry = req.getRetryCount(); 223 if (hasPrimaryWINSServer()) 224 reqRetry = 1; 225 226 228 boolean txsts = true; 229 int retry = 0; 230 231 while (req.hasErrorStatus() == false && retry++ < reqRetry) 232 { 233 234 236 if (logger.isDebugEnabled()) 237 logger.debug("NetBIOS handler, processing " + req); 238 239 241 switch (req.isType()) 242 { 243 244 246 case NetBIOSRequest.AddName: 247 248 250 if (hasPrimaryWINSServer()) 251 txsts = sendAddName(req, getPrimaryWINSServer(), false); 252 else 253 txsts = sendAddName(req, getBroadcastAddress(), true); 254 break; 255 256 258 case NetBIOSRequest.DeleteName: 259 260 262 if (hasPrimaryWINSServer()) 263 txsts = sendDeleteName(req, getPrimaryWINSServer(), false); 264 else 265 txsts = sendDeleteName(req, getBroadcastAddress(), true); 266 break; 267 268 270 case NetBIOSRequest.RefreshName: 271 272 274 if (hasPrimaryWINSServer()) 275 txsts = sendRefreshName(req, getPrimaryWINSServer(), false); 276 else 277 txsts = sendRefreshName(req, getBroadcastAddress(), true); 278 break; 279 } 280 281 283 if (txsts == true && req.getRetryInterval() > 0) 284 { 285 286 288 sleep(req.getRetryInterval()); 289 } 290 } 291 292 294 if (req.hasErrorStatus() == false) 295 { 296 297 299 if (logger.isDebugEnabled()) 300 logger.debug("NetBIOS handler successful, " + req); 301 302 304 NetBIOSName nbName = req.getNetBIOSName(); 305 306 switch (req.isType()) 307 { 308 309 311 case NetBIOSRequest.AddName: 312 313 315 if (m_localNames.contains(nbName) == false) 316 m_localNames.addElement(nbName); 317 318 320 nbName.setExpiryTime(System.currentTimeMillis() + (nbName.getTimeToLive() * 1000L)); 321 322 324 fireAddNameEvent(nbName, NetBIOSNameEvent.ADD_SUCCESS); 325 break; 326 327 329 case NetBIOSRequest.DeleteName: 330 331 333 m_localNames.remove(req.getNetBIOSName()); 334 break; 335 336 338 case NetBIOSRequest.RefreshName: 339 340 342 nbName.setExpiryTime(System.currentTimeMillis() + (nbName.getTimeToLive() * 1000L)); 343 break; 344 } 345 } 346 else 347 { 348 349 351 switch (req.isType()) 352 { 353 354 356 case NetBIOSRequest.AddName: 357 358 360 m_localNames.remove(req.getNetBIOSName()); 361 break; 362 } 363 } 364 365 367 synchronized (m_reqList) 368 { 369 m_reqList.remove(0); 370 } 371 } 372 catch (InterruptedException ex) 373 { 374 } 375 376 378 if (m_hshutdown == true) 379 break; 380 } 381 } 382 383 391 private final boolean sendAddName(NetBIOSRequest req, InetAddress dest, boolean bcast) 392 { 393 394 try 395 { 396 397 399 byte[] buf = new byte[AddNameSize]; 400 NetBIOSPacket addPkt = new NetBIOSPacket(buf); 401 402 404 for (int i = 0; i < req.getNetBIOSName().numberOfAddresses(); i++) 405 { 406 407 409 int len = addPkt.buildAddNameRequest(req.getNetBIOSName(), i, req.getTransactionId()); 410 if (bcast == false) 411 addPkt.setFlags(0); 412 413 415 DatagramPacket pkt = new DatagramPacket (buf, len, dest, getPort()); 416 417 419 if (m_socket != null) 420 m_socket.send(pkt); 421 422 424 if (logger.isDebugEnabled()) 425 logger.debug(" Add name " + (bcast ? "broadcast" : "WINS") + ", " + req); 426 } 427 } 428 catch (IOException ex) 429 { 430 fireAddNameEvent(req.getNetBIOSName(), NetBIOSNameEvent.ADD_IOERROR); 431 req.setErrorStatus(true); 432 return false; 433 } 434 435 437 return true; 438 } 439 440 448 private final boolean sendRefreshName(NetBIOSRequest req, InetAddress dest, boolean bcast) 449 { 450 451 try 452 { 453 454 456 byte[] buf = new byte[RefreshNameSize]; 457 NetBIOSPacket refreshPkt = new NetBIOSPacket(buf); 458 459 461 for (int i = 0; i < req.getNetBIOSName().numberOfAddresses(); i++) 462 { 463 464 466 int len = refreshPkt.buildRefreshNameRequest(req.getNetBIOSName(), i, req.getTransactionId()); 467 if (bcast == false) 468 refreshPkt.setFlags(0); 469 470 472 DatagramPacket pkt = new DatagramPacket (buf, len, dest, getPort()); 473 474 476 if (m_socket != null) 477 m_socket.send(pkt); 478 479 481 if (logger.isDebugEnabled()) 482 logger.debug(" Refresh name " + (bcast ? "broadcast" : "WINS") + ", " + req); 483 } 484 } 485 catch (IOException ex) 486 { 487 req.setErrorStatus(true); 488 return false; 489 } 490 491 493 return true; 494 } 495 496 504 private final boolean sendDeleteName(NetBIOSRequest req, InetAddress dest, boolean bcast) 505 { 506 507 try 508 { 509 510 512 byte[] buf = new byte[DeleteNameSize]; 513 NetBIOSPacket delPkt = new NetBIOSPacket(buf); 514 515 517 for (int i = 0; i < req.getNetBIOSName().numberOfAddresses(); i++) 518 { 519 520 522 int len = delPkt.buildDeleteNameRequest(req.getNetBIOSName(), i, req.getTransactionId()); 523 if (bcast == false) 524 delPkt.setFlags(0); 525 526 528 DatagramPacket pkt = new DatagramPacket (buf, len, dest, getPort()); 529 530 532 if (m_socket != null) 533 m_socket.send(pkt); 534 535 537 if (logger.isDebugEnabled()) 538 logger.debug(" Delete name " + (bcast ? "broadcast" : "WINS") + ", " + req); 539 } 540 } 541 catch (IOException ex) 542 { 543 req.setErrorStatus(true); 544 return false; 545 } 546 547 549 return true; 550 } 551 }; 552 553 555 class NetBIOSNameRefresh extends Thread 556 { 557 558 560 private boolean m_hshutdown = false; 561 562 565 public NetBIOSNameRefresh() 566 { 567 setDaemon(true); 568 setName("NetBIOSRefresh"); 569 } 570 571 574 public final void shutdownRequest() 575 { 576 m_hshutdown = true; 577 578 580 this.interrupt(); 581 } 582 583 586 public void run() 587 { 588 589 591 while (m_hshutdown == false) 592 { 593 594 try 595 { 596 597 599 sleep(NameRefreshWakeupInterval); 600 601 603 if (m_hshutdown == true) 604 break; 605 606 608 if (logger.isDebugEnabled()) 609 logger.debug("NetBIOS name refresh wakeup ..."); 610 611 613 synchronized (m_localNames) 614 { 615 616 618 long expireTime = System.currentTimeMillis() + NameRefreshWakeupInterval; 619 620 622 for (int i = 0; i < m_localNames.size(); i++) 623 { 624 625 627 NetBIOSName nbName = m_localNames.get(i); 628 629 632 if (nbName.getExpiryTime() < expireTime) 633 { 634 635 637 if (logger.isDebugEnabled()) 638 logger.debug("Queuing name refresh for " + nbName); 639 640 642 NetBIOSRequest nbReq = new NetBIOSRequest(NetBIOSRequest.RefreshName, nbName, 643 getNextTransactionId()); 644 nbReq.setRetryCount(RefreshNameRetries); 645 646 648 synchronized (m_reqList) 649 { 650 651 653 m_reqList.addElement(nbReq); 654 655 657 m_reqList.notify(); 658 } 659 } 660 } 661 } 662 } 663 catch (Exception ex) 664 { 665 666 668 if ( m_hshutdown == false) 669 logger.error("NetBIOS Name refresh thread exception", ex); 670 } 671 } 672 } 673 }; 674 675 682 public NetBIOSNameServer(ServerConfiguration config) throws SocketException 683 { 684 super("NetBIOS", config); 685 686 commonConstructor(); 688 } 689 690 695 private final void commonConstructor() throws SocketException 696 { 697 698 700 setVersion(ServerVersion); 701 702 704 m_localNames = new Vector <NetBIOSName>(); 705 m_remoteNames = new Hashtable <NetBIOSName, byte[]>(); 706 707 709 if (getConfiguration().hasNetBIOSDebug()) 710 setDebug(true); 711 712 714 setBindAddress(getConfiguration().getNetBIOSBindAddress()); 715 setServerPort(RFCNetBIOSProtocol.NAME_PORT); 716 717 719 setPrimaryWINSServer(getConfiguration().getPrimaryWINSServer()); 720 setSecondaryWINSServer(getConfiguration().getSecondaryWINSServer()); 721 722 724 if (hasPrimaryWINSServer() == false) 725 { 726 727 try 728 { 729 m_bcastAddr = InetAddress.getByName(getConfiguration().getBroadcastMask()); 730 } 731 catch (Exception ex) 732 { 733 } 734 } 735 } 736 737 742 public final InetAddress getBindAddress() 743 { 744 return m_bindAddress; 745 } 746 747 752 protected final synchronized int getNextTransactionId() 753 { 754 return m_tranId++; 755 } 756 757 762 public final int getPort() 763 { 764 return m_port; 765 } 766 767 772 public final boolean hasBindAddress() 773 { 774 return m_bindAddress != null ? true : false; 775 } 776 777 782 public final Hashtable <NetBIOSName, byte[]> getNameTable() 783 { 784 return m_remoteNames; 785 } 786 787 792 public final InetAddress getBroadcastAddress() 793 { 794 return m_bcastAddr; 795 } 796 797 802 public final boolean hasPrimaryWINSServer() 803 { 804 return m_winsPrimary != null ? true : false; 805 } 806 807 812 public final InetAddress getPrimaryWINSServer() 813 { 814 return m_winsPrimary; 815 } 816 817 822 public final boolean hasSecondaryWINSServer() 823 { 824 return m_winsSecondary != null ? true : false; 825 } 826 827 832 public final InetAddress getSecondaryWINSServer() 833 { 834 return m_winsSecondary; 835 } 836 837 843 public final synchronized void AddName(NetBIOSName name) throws IOException 844 { 845 846 848 if (m_socket == null) 849 throw new IOException ("NetBIOS name socket not initialized"); 850 851 853 NetBIOSRequest nbReq = new NetBIOSRequest(NetBIOSRequest.AddName, name, getNextTransactionId()); 854 855 857 if (hasPrimaryWINSServer()) 858 nbReq.setRetryInterval(AddNameWINSInterval); 859 else 860 nbReq.setRetryInterval(AddNameInterval); 861 862 864 m_localNames.addElement(name); 865 866 868 synchronized (m_reqList) 869 { 870 871 873 m_reqList.addElement(nbReq); 874 875 877 m_reqList.notify(); 878 } 879 } 880 881 887 public final synchronized void DeleteName(NetBIOSName name) throws IOException 888 { 889 890 892 if (m_socket == null) 893 throw new IOException ("NetBIOS name socket not initialized"); 894 895 897 NetBIOSRequest nbReq = new NetBIOSRequest(NetBIOSRequest.DeleteName, name, getNextTransactionId(), 898 DeleteNameRetries); 899 nbReq.setRetryInterval(DeleteNameInterval); 900 901 synchronized (m_reqList) 902 { 903 904 906 m_reqList.addElement(nbReq); 907 908 910 m_reqList.notify(); 911 } 912 } 913 914 919 public final synchronized void addAddNameListener(AddNameListener l) 920 { 921 922 924 if (m_addListeners == null) 925 m_addListeners = new Vector <AddNameListener>(); 926 m_addListeners.addElement(l); 927 } 928 929 934 public final synchronized void addQueryListener(QueryNameListener l) 935 { 936 937 939 if (m_queryListeners == null) 940 m_queryListeners = new Vector <QueryNameListener>(); 941 m_queryListeners.addElement(l); 942 } 943 944 949 public final synchronized void addRemoteListener(RemoteNameListener l) 950 { 951 952 954 if (m_remoteListeners == null) 955 m_remoteListeners = new Vector <RemoteNameListener>(); 956 m_remoteListeners.addElement(l); 957 } 958 959 965 protected final synchronized void fireAddNameEvent(NetBIOSName name, int sts) 966 { 967 968 970 if (m_addListeners == null || m_addListeners.size() == 0) 971 return; 972 973 975 NetBIOSNameEvent evt = new NetBIOSNameEvent(name, sts); 976 977 979 for (int i = 0; i < m_addListeners.size(); i++) 980 { 981 AddNameListener addListener = m_addListeners.get(i); 982 addListener.netbiosNameAdded(evt); 983 } 984 } 985 986 992 protected final synchronized void fireQueryNameEvent(NetBIOSName name, InetAddress addr) 993 { 994 995 997 if (m_queryListeners == null || m_queryListeners.size() == 0) 998 return; 999 1000 1002 NetBIOSNameEvent evt = new NetBIOSNameEvent(name, NetBIOSNameEvent.QUERY_NAME); 1003 1004 1006 for (int i = 0; i < m_queryListeners.size(); i++) 1007 { 1008 QueryNameListener queryListener = m_queryListeners.get(i); 1009 queryListener.netbiosNameQuery(evt, addr); 1010 } 1011 } 1012 1013 1019 protected final synchronized void fireNameRegisterEvent(NetBIOSName name, InetAddress addr) 1020 { 1021 1022 1024 if (m_remoteListeners == null || m_remoteListeners.size() == 0) 1025 return; 1026 1027 1029 NetBIOSNameEvent evt = new NetBIOSNameEvent(name, NetBIOSNameEvent.REGISTER_NAME); 1030 1031 1033 for (int i = 0; i < m_remoteListeners.size(); i++) 1034 { 1035 RemoteNameListener nameListener = m_remoteListeners.get(i); 1036 nameListener.netbiosAddRemoteName(evt, addr); 1037 } 1038 } 1039 1040 1046 protected final synchronized void fireNameReleaseEvent(NetBIOSName name, InetAddress addr) 1047 { 1048 1049 1051 if (m_remoteListeners == null || m_remoteListeners.size() == 0) 1052 return; 1053 1054 1056 NetBIOSNameEvent evt = new NetBIOSNameEvent(name, NetBIOSNameEvent.REGISTER_NAME); 1057 1058 1060 for (int i = 0; i < m_remoteListeners.size(); i++) 1061 { 1062 RemoteNameListener nameListener = m_remoteListeners.get(i); 1063 nameListener.netbiosReleaseRemoteName(evt, addr); 1064 } 1065 } 1066 1067 1072 private void openSocket() throws java.net.SocketException 1073 { 1074 1075 1077 if (hasBindAddress()) 1078 m_socket = new DatagramSocket (getPort(), m_bindAddress); 1079 else 1080 m_socket = new DatagramSocket (getPort()); 1081 } 1082 1083 1090 protected final void processNameQuery(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1091 { 1092 1093 1095 if (pkt.getQuestionCount() != 1) 1096 return; 1097 1098 1100 String searchName = pkt.getQuestionName(); 1101 char nameType = searchName.charAt(15); 1102 1103 int len = 0; 1104 while (len <= 14 && searchName.charAt(len) != ' ') 1105 len++; 1106 searchName = searchName.substring(0, len); 1107 1108 1110 if (logger.isDebugEnabled()) 1111 logger.debug("%% Query name=" + searchName + ", type=" + NetBIOSName.TypeAsString(nameType) + ", len=" 1112 + len); 1113 1114 1116 Enumeration <NetBIOSName> enm = m_localNames.elements(); 1117 NetBIOSName nbName = null; 1118 boolean foundName = false; 1119 1120 while (enm.hasMoreElements() && foundName == false) 1121 { 1122 1123 1125 nbName = enm.nextElement(); 1126 1127 1129 if (logger.isDebugEnabled()) 1130 logger.debug("NetBIOS Name - " + nbName.getName() + ", len=" + nbName.getName().length() + ",type=" 1131 + NetBIOSName.TypeAsString(nbName.getType())); 1132 1133 1135 if (nbName.getType() == nameType && nbName.getName().compareTo(searchName) == 0) 1136 foundName = true; 1137 } 1138 1139 1141 if (foundName == true) 1142 { 1143 1144 1146 if (logger.isDebugEnabled()) 1147 logger.debug("%% Found name " + searchName + " in local name table : " + nbName.toString()); 1148 1149 1151 int pktLen = pkt.buildNameQueryResponse(nbName); 1152 1153 1155 if (logger.isDebugEnabled()) 1156 { 1157 logger.debug("%% NetBIOS Reply to " + fromAddr.getHostAddress() + " :-"); 1158 pkt.DumpPacket(false); 1159 } 1160 1161 1163 try 1164 { 1165 1166 1168 sendPacket(pkt, pktLen, fromAddr, fromPort); 1169 } 1170 catch (java.io.IOException ex) 1171 { 1172 logger.error("Name query response error", ex); 1173 } 1174 1175 1177 fireQueryNameEvent(nbName, fromAddr); 1178 } 1179 else 1180 { 1181 1182 1184 if (logger.isDebugEnabled()) 1185 logger.debug("%% Failed to find match for name " + searchName); 1186 } 1187 } 1188 1189 1196 protected final void processNameRegister(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1197 { 1198 1199 1201 if (pkt.getQuestionCount() != 1) 1202 return; 1203 1204 1206 String regName = pkt.getQuestionName(); 1207 char nameType = regName.charAt(15); 1208 1209 int len = 0; 1210 while (len <= 14 && regName.charAt(len) != ' ') 1211 len++; 1212 regName = regName.substring(0, len); 1213 1214 1216 if (logger.isDebugEnabled()) 1217 logger.debug("%% Register name=" + regName + ", type=" + NetBIOSName.TypeAsString(nameType) + ", len=" 1218 + len); 1219 1220 1222 byte[] hostIP = fromAddr.getAddress(); 1223 NetBIOSName nbName = new NetBIOSName(regName, nameType, false, hostIP); 1224 1225 1227 m_remoteNames.put(nbName, hostIP); 1228 1229 1231 fireNameRegisterEvent(nbName, fromAddr); 1232 1233 1235 if (logger.isDebugEnabled()) 1236 logger.debug("%% Added remote name " + nbName.toString() + " to remote names table"); 1237 } 1238 1239 1246 protected final void processNameRelease(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1247 { 1248 1249 1251 if (pkt.getQuestionCount() != 1) 1252 return; 1253 1254 1256 String regName = pkt.getQuestionName(); 1257 char nameType = regName.charAt(15); 1258 1259 int len = 0; 1260 while (len <= 14 && regName.charAt(len) != ' ') 1261 len++; 1262 regName = regName.substring(0, len); 1263 1264 1266 if (logger.isDebugEnabled()) 1267 logger 1268 .debug("%% Release name=" + regName + ", type=" + NetBIOSName.TypeAsString(nameType) + ", len=" 1269 + len); 1270 1271 1273 byte[] hostIP = fromAddr.getAddress(); 1274 NetBIOSName nbName = new NetBIOSName(regName, nameType, false, hostIP); 1275 1276 1278 m_remoteNames.remove(nbName); 1279 1280 1282 fireNameReleaseEvent(nbName, fromAddr); 1283 1284 1286 if (logger.isDebugEnabled()) 1287 logger.debug("%% Released remote name " + nbName.toString() + " from remote names table"); 1288 } 1289 1290 1297 protected final void processQueryResponse(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1298 { 1299 } 1300 1301 1308 protected final void processRegisterResponse(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1309 { 1310 1311 1313 if (pkt.getAnswerCount() == 0) 1314 return; 1315 1316 1318 int tranId = pkt.getTransactionId(); 1319 1320 1322 NetBIOSRequest req = findRequest(tranId); 1323 if (req == null) 1324 return; 1325 1326 1328 int errCode = pkt.getResultCode(); 1329 1330 if (errCode != 0) 1331 { 1332 1333 1335 req.setErrorStatus(true); 1336 1337 1339 String regName = pkt.getAnswerName(); 1340 char nameType = regName.charAt(15); 1341 1342 int len = 0; 1343 while (len <= 14 && regName.charAt(len) != ' ') 1344 len++; 1345 regName = regName.substring(0, len); 1346 1347 1349 byte[] hostIP = fromAddr.getAddress(); 1350 NetBIOSName nbName = new NetBIOSName(regName, nameType, false, hostIP); 1351 1352 1354 if (logger.isDebugEnabled()) 1355 logger.debug("%% Negative Name Registration name=" + nbName); 1356 1357 1359 fireAddNameEvent(req.getNetBIOSName(), NetBIOSNameEvent.ADD_FAILED); 1360 } 1361 else 1362 { 1363 1364 1366 if (logger.isDebugEnabled()) 1367 logger.debug("%% Name Registration Successful name=" + req.getNetBIOSName().getName()); 1368 1369 1371 fireAddNameEvent(req.getNetBIOSName(), NetBIOSNameEvent.ADD_SUCCESS); 1372 } 1373 } 1374 1375 1382 protected final void processReleaseResponse(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1383 { 1384 } 1385 1386 1393 protected final void processWack(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) 1394 { 1395 } 1396 1397 1402 public final synchronized void removeAddNameListener(AddNameListener l) 1403 { 1404 1405 1407 if (m_addListeners == null) 1408 return; 1409 m_addListeners.removeElement(l); 1410 } 1411 1412 1417 public final synchronized void removeQueryNameListener(QueryNameListener l) 1418 { 1419 1420 1422 if (m_queryListeners == null) 1423 return; 1424 m_queryListeners.removeElement(l); 1425 } 1426 1427 1432 public final synchronized void removeRemoteListener(RemoteNameListener l) 1433 { 1434 1435 1437 if (m_remoteListeners == null) 1438 return; 1439 m_remoteListeners.removeElement(l); 1440 } 1441 1442 1445 public void run() 1446 { 1447 1448 1450 NetBIOSPacket nbPkt = null; 1451 DatagramPacket pkt = null; 1452 byte[] buf = null; 1453 1454 try 1455 { 1456 1457 1459 Vector <byte[]> ipList = new Vector <byte[]>(); 1460 1461 if (hasBindAddress()) 1462 { 1463 1464 1466 ipList.add(getBindAddress().getAddress()); 1467 } 1468 else 1469 { 1470 1471 1473 InetAddress [] addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()); 1474 1475 for (int i = 0; i < addrs.length; i++) 1476 { 1477 1478 1480 if (addrs[i].getHostAddress().equals("127.0.0.1") == false 1481 && addrs[i].getHostAddress().equals("0.0.0.0") == false) 1482 ipList.add(addrs[i].getAddress()); 1483 } 1484 1485 1487 if ( ipList.size() == 0) 1488 { 1489 1491 logger.error("Failed to get IP address(es) for NetBIOS name"); 1492 for ( int i = 0; i < addrs.length; i++) 1493 logger.error( " Address: " + addrs[i]); 1494 logger.error("Check hosts file and/or DNS setup"); 1495 logger.error("NetBIOS name server is shutting down"); 1496 1497 return; 1498 } 1499 } 1500 1501 1503 if (m_socket == null) 1504 openSocket(); 1505 1506 1508 m_reqList = new Vector <NetBIOSRequest>(); 1509 1510 1512 AddName(new NetBIOSName(getConfiguration().getServerName(), NetBIOSName.FileServer, false, ipList, 1513 DefaultTTL)); 1514 AddName(new NetBIOSName(getConfiguration().getServerName(), NetBIOSName.WorkStation, false, ipList, 1515 DefaultTTL)); 1516 1517 if (getConfiguration().getDomainName() != null) 1518 AddName(new NetBIOSName(getConfiguration().getDomainName(), NetBIOSName.Domain, true, ipList, 1519 DefaultTTL)); 1520 1521 1523 m_reqHandler = new NetBIOSRequestHandler(); 1524 m_reqHandler.start(); 1525 1526 1528 m_refreshThread = new NetBIOSNameRefresh(); 1529 m_refreshThread.start(); 1530 1531 1533 buf = new byte[1024]; 1534 nbPkt = new NetBIOSPacket(buf); 1535 pkt = new DatagramPacket (buf, buf.length); 1536 } 1537 catch (Exception ex) 1538 { 1539 1540 1542 logger.error("NetBIOSNameServer setup error:", ex); 1543 1544 1546 setException(ex); 1547 fireServerEvent(ServerListener.ServerError); 1548 } 1549 1550 1552 if (m_reqList != null && m_reqList.size() > 0) 1553 { 1554 synchronized (m_reqList) 1555 { 1556 m_reqList.notify(); 1557 } 1558 } 1559 1560 1562 setActive(true); 1563 fireServerEvent(ServerListener.ServerActive); 1564 1565 1567 if (hasException() == false) 1568 { 1569 1570 1572 m_shutdown = false; 1573 1574 while (m_shutdown == false) 1575 { 1576 1577 try 1578 { 1579 1580 1582 m_socket.receive(pkt); 1583 1584 1586 if (pkt.getLength() == 0) 1587 continue; 1588 1589 1591 InetAddress fromAddr = pkt.getAddress(); 1592 int fromPort = pkt.getPort(); 1593 1594 switch (nbPkt.getOpcode()) 1595 { 1596 1597 1599 case NetBIOSPacket.NAME_QUERY: 1600 processNameQuery(nbPkt, fromAddr, fromPort); 1601 break; 1602 1603 1605 case NetBIOSPacket.NAME_REGISTER: 1606 processNameRegister(nbPkt, fromAddr, fromPort); 1607 break; 1608 1609 1611 case NetBIOSPacket.NAME_RELEASE: 1612 processNameRelease(nbPkt, fromAddr, fromPort); 1613 break; 1614 1615 1617 case NetBIOSPacket.RESP_REGISTER: 1618 processRegisterResponse(nbPkt, fromAddr, fromPort); 1619 break; 1620 1621 1623 case NetBIOSPacket.RESP_QUERY: 1624 processQueryResponse(nbPkt, fromAddr, fromPort); 1625 break; 1626 1627 1629 case NetBIOSPacket.RESP_RELEASE: 1630 processReleaseResponse(nbPkt, fromAddr, fromPort); 1631 break; 1632 1633 1635 case NetBIOSPacket.WACK: 1636 processWack(nbPkt, fromAddr, fromPort); 1637 break; 1638 1639 1641 case NetBIOSPacket.REFRESH: 1642 processNameRegister(nbPkt, fromAddr, fromPort); 1643 break; 1644 1645 1647 case NetBIOSPacket.NAME_REGISTER_MULTI: 1648 processNameRegister(nbPkt, fromAddr, fromPort); 1649 break; 1650 1651 1653 default: 1654 logger.error("Unknown OpCode 0x" + Integer.toHexString(nbPkt.getOpcode())); 1655 break; 1656 } 1657 } 1658 catch (Exception ex) 1659 { 1660 1661 1663 if ( m_shutdown == false) 1664 logger.error("NetBIOSNameServer error", ex); 1665 1666 1672 if (m_shutdown == false) 1673 { 1674 setException(ex); 1675 fireServerEvent(ServerListener.ServerError); 1676 } 1677 } 1678 } 1679 } 1680 1681 1683 setActive(false); 1684 fireServerEvent(ServerListener.ServerShutdown); 1685 } 1686 1687 1694 protected final void sendPacket(NetBIOSPacket nbpkt, int len) throws java.io.IOException 1695 { 1696 1697 1699 DatagramPacket pkt = new DatagramPacket (nbpkt.getBuffer(), len, NetworkSettings.getBroadcastAddress(), 1700 getPort()); 1701 1702 1704 m_socket.send(pkt); 1705 } 1706 1707 1716 protected final void sendPacket(NetBIOSPacket nbpkt, int len, InetAddress replyAddr, int replyPort) 1717 throws java.io.IOException 1718 { 1719 1720 1722 DatagramPacket pkt = new DatagramPacket (nbpkt.getBuffer(), len, replyAddr, replyPort); 1723 1724 1726 m_socket.send(pkt); 1727 } 1728 1729 1734 public final void setBindAddress(InetAddress addr) 1735 { 1736 m_bindAddress = addr; 1737 } 1738 1739 1744 public final void setServerPort(int port) 1745 { 1746 m_port = port; 1747 } 1748 1749 1754 public final void setPrimaryWINSServer(InetAddress addr) 1755 { 1756 m_winsPrimary = addr; 1757 } 1758 1759 1764 public final void setSecondaryWINSServer(InetAddress addr) 1765 { 1766 m_winsSecondary = addr; 1767 } 1768 1769 1775 private final NetBIOSRequest findRequest(int id) 1776 { 1777 1778 1780 if (m_reqList == null) 1781 return null; 1782 1783 1785 NetBIOSRequest req = null; 1786 1787 synchronized (m_reqList) 1788 { 1789 1790 1792 int idx = 0; 1793 1794 while (req == null && idx < m_reqList.size()) 1795 { 1796 1797 1799 NetBIOSRequest curReq = (NetBIOSRequest) m_reqList.elementAt(idx++); 1800 if (curReq.getTransactionId() == id) 1801 req = curReq; 1802 } 1803 } 1804 1805 1807 return req; 1808 } 1809 1810 1815 public void shutdownServer(boolean immediate) 1816 { 1817 1818 1820 try 1821 { 1822 1823 if (m_refreshThread != null) 1824 { 1825 m_refreshThread.shutdownRequest(); 1826 } 1827 } 1828 catch (Exception ex) 1829 { 1830 1831 1833 logger.error("Shutdown NetBIOS server error", ex); 1834 } 1835 1836 1838 if (isActive() && immediate == false) 1839 { 1840 1841 1843 for (int i = 0; i < m_localNames.size(); i++) 1844 { 1845 1846 1848 NetBIOSName nbName = (NetBIOSName) m_localNames.elementAt(i); 1849 1850 1852 try 1853 { 1854 DeleteName(nbName); 1855 } 1856 catch (IOException ex) 1857 { 1858 logger.error("Shutdown NetBIOS server error", ex); 1859 } 1860 } 1861 1862 1864 while (m_reqList.size() > 0) 1865 { 1866 try 1867 { 1868 Thread.sleep(100); 1869 } 1870 catch (InterruptedException ex) 1871 { 1872 } 1873 } 1874 } 1875 1876 1878 try 1879 { 1880 1881 1883 if (m_reqHandler != null) 1884 { 1885 m_reqHandler.shutdownRequest(); 1886 m_reqHandler.join(1000); 1887 m_reqHandler = null; 1888 } 1889 } 1890 catch (Exception ex) 1891 { 1892 1893 1895 logger.error("Shutdown NetBIOS request handler error", ex); 1896 } 1897 1898 1900 m_shutdown = true; 1901 1902 try 1903 { 1904 1905 1907 if (m_socket != null) 1908 { 1909 1910 try 1911 { 1912 m_socket.close(); 1913 } 1914 catch (Exception ex) 1915 { 1916 } 1917 m_socket = null; 1918 } 1919 } 1920 catch (Exception ex) 1921 { 1922 logger.error("Shutdown NetBIOS server error", ex); 1923 } 1924 1925 1927 fireServerEvent(ServerListener.ServerShutdown); 1928 } 1929 1930 1933 public void startServer() 1934 { 1935 1936 1938 m_srvThread = new Thread (this); 1939 m_srvThread.setName("NetBIOS Name Server"); 1940 m_srvThread.setDaemon(true); 1941 1942 m_srvThread.start(); 1943 1944 1946 fireServerEvent(ServerListener.ServerStartup); 1947 } 1948} | Popular Tags |