import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Random; public class Main { public static void main(String[] args) throws IOException { String userSearch = null; String userDNS = null; int userType = 0; String search = "google.pl"; //String DNS = "8.8.8.8"; // google [ograniczone dane, czesto puste wyniki] String DNS = "192.112.36.4"; // globalny DNS //String DNS = "62.233.233.233"; // DNS netii int type = 1; for(String arg : args) { if(arg.startsWith("-d=")) userSearch = arg.substring(3); else if(arg.startsWith("-ns=")) userDNS = arg.substring(4); else if(arg.startsWith("-t=")) userType = Integer.parseInt(arg.substring(3)); } if(userSearch == null) { System.out.println("Nie ustawiono poszukiwanej domeny. Zostanie uzyta domyslna wartosc: " + search); } else { search = userSearch; System.out.println("Ustawiono poszukiwana domene: " + search); } if(userDNS == null) { System.out.println("Nie ustawiono serwera DNS. Zostanie uzyta domyslna wartosc: " + DNS); } else { DNS = userDNS; System.out.println("Ustawiono serwer DNS: " + search); } if(userType == 0) { System.out.println("Nie ustawiono typu zapytania. Zostanie uzyta domyslna wartosc: " + type); } else { type = userType; System.out.println("Ustawiono typ zapytania: " + type); } if(type < 1 || type >= DNS_Record.TYPES.length) { System.out.println("Nie znany typ zapytania. Dozwolone: 1 (A), 2 (NS), 5 (CNAME), 6 (SOA), 15 (MX), 16 (TXT)"); System.exit(1); } DatagramSocket socket = new DatagramSocket(12345); socket.setSoTimeout(5000); DNS_Packet.socket = socket; Random random = new Random(); while(true) { System.out.println("-------------------------------------------------------"); DNS_Packet answer = get(search, DNS, type); System.out.println("OPCode: " + answer.OPCODE + ", Answers: " + answer.ANCount + ", Authority Records: " + answer.NSCount); boolean gotAnswer = false; if(answer.OPCODE != 0) // moze ta sama domena co wczesniej i petla musi sie przerwac, bo domena nie istnieje { System.out.println("Wystapil blad:"); switch(answer.OPCODE) { case (byte) 1: System.out.println("Format Error"); break; case (byte) 2: System.out.println("Server Failure"); break; case (byte) 3: System.out.println("Name Error"); break; case (byte) 4: System.out.println("Not Implemented"); break; case (byte) 5: System.out.println("Refused"); break; default: System.out.println("Nie obslugiwany. ID: " + answer.OPCODE); break; } break; } if(answer.ANCount > 0) { System.out.println("Odpowiedzi:"); for(int i = 0; i < answer.ANCount; i++) { DNS_Record record = answer.ANList[i]; answer.ptr = record.RData; if(record.QType == type) { gotAnswer = true; } switch(record.QType) { case (byte) 1: // A InetAddress address = InetAddress.getByAddress(new byte[] { answer.response[answer.ptr++], answer.response[answer.ptr++], answer.response[answer.ptr++], answer.response[answer.ptr++] }); System.out.println("Typ: A, Domena: " + record.domain + ", IP: " + address.getHostAddress()); break; case (byte) 2: // NS System.out.println("Typ: NS, Domena: " + record.domain + ", Domena NS: " + answer.getStringFromPoint()); break; case (byte) 5: // CNAME System.out.println("Typ: CNAME, Domena: " + record.domain + ", Rzeczywista domena: " + answer.getStringFromPoint()); break; case (byte) 6: // SOA System.out.println("Typ: SOA, Domena: " + record.domain + ", Domena NS: " + answer.getStringFromPoint() + ", Email kontaktowy: " + answer.getStringFromPoint()); break; case (byte) 15: // MX answer.ptr += 2; System.out.println("Typ: MX, Domena: " + record.domain + ", Adres: " + answer.getStringFromPoint()); break; case (byte) 16: // TXT System.out.print("Typ: TXT, Domena: " + record.domain + ", Text: "); for(int tt = 0; tt < answer.response[answer.ptr]; tt++) { System.out.print((char) answer.response[answer.ptr + tt + 1]); } System.out.println(); break; default: System.out.println("Otrzymano odpowiedz. Nie mozna pokazac danych. Nie obslugiwany typ pakietu Type ID: " + record.QType); break; } } if(gotAnswer) { break; } } if(!gotAnswer && answer.NSCount > 0) { System.out.println("Serwery NS:"); ArrayList dnsy = new ArrayList(); for(int i = 0; i < answer.NSCount; i++) { DNS_Record record = answer.NSList[i]; if(record.QType == (byte) 2) { answer.ptr = record.RData; String otherDNS = answer.getStringFromPoint(); if(!otherDNS.equals(DNS)) { dnsy.add(otherDNS); } System.out.println("Domena: " + record.domain + ", NS: " + otherDNS); } else if(record.QType == (byte) 6) { answer.ptr = record.RData; String otherDNS = answer.getStringFromPoint(); if((type == 2 || type == 6) && search.endsWith(record.domain)) { System.out.println("Typ: SOA, Domena: " + record.domain + ", Domena NS: " + otherDNS + ", Email kontaktowy: " + answer.getStringFromPoint()); System.exit(1); } if(!otherDNS.equals(DNS)) { dnsy.add(otherDNS); } System.out.println("Domena: " + record.domain + ", SOA: " + otherDNS); } else { System.err.println("W 'Authority Record' otrzymano informacje o domenie: " + record.domain + ", typu: " + record.QType + ", obslugiwane jest tylko NS (2)."); } } if(dnsy.size() == 0) { System.out.println("Nie uzyskano odpowiedzi podanego typu, ani adresow innych serwerow DNS."); break; } DNS = dnsy.get(random.nextInt(dnsy.size())); System.out.println("Wybrano nowy DNS: " + DNS); } else { System.out.println("Nie uzyskano odpowiedzi podanego typu, ani adresow innych serwerow DNS."); break; } } socket.close(); } public static DNS_Packet get(String domain, String fromDNS, int type) throws UnknownHostException, IOException { DNS_Packet packet = new DNS_Packet(domain, type); boolean reponseReceived = false; for(int i = 0; i < 3; i++) { System.out.println("Wysylanie zapytania o " + domain + " do " + fromDNS + ", typ " + DNS_Record.TYPES[type] + "."); if(packet.query(InetAddress.getByName(fromDNS))) { reponseReceived = true; break; } else { System.out.println("Brak odpowiedzi przez 5 sekund."); } } if(reponseReceived) { packet.parseResponse(); } else { System.out.println("Nie udalo sie uzyskac odpowiedzi od serwera DNS " + fromDNS); System.exit(1); } return packet; } }