Advertisement
Guest User

Untitled

a guest
Jun 25th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.62 KB | None | 0 0
  1. /******************************************************
  2.  Laboratoire #3 : Programmation d'un serveur DNS
  3.  
  4.  Cours :             LOG610
  5.  Session :           Hiver 2007
  6.  Groupe :            01
  7.  Projet :            Laboratoire #3
  8.  �tudiant(e)(s) :    Maxime Bouchard
  9.  Code(s) perm. :     BOUM24028309
  10.  
  11.  Professeur :        Michel Lavoie
  12.  Nom du fichier :    UDPReceiver.java
  13.  Date cr�e :         2007-03-10
  14.  Date dern. modif.   X
  15.  *******************************************************/
  16. import java.net.DatagramPacket;
  17. import java.net.DatagramSocket;
  18. import java.net.InetAddress;
  19. import java.net.InetSocketAddress;
  20. import java.nio.ByteBuffer;
  21.  
  22.  
  23. /**
  24.  * Cette classe permet la r�ception d'un paquet UDP sur le port de r�ception
  25.  * UDP/DNS. Elle analyse le paquet et extrait le hostname
  26.  *
  27.  * Il s'agit d'un Thread qui �coute en permanance
  28.  * pour ne pas affecter le d�roulement du programme
  29.  * @author Max
  30.  *
  31.  */
  32.  
  33.  
  34. public class UDPReceiver extends Thread {
  35.     /**
  36.      * Les champs d'un Packet UDP
  37.      * --------------------------
  38.      * En-t�te (12 octects)
  39.      * Question : l'adresse demand�
  40.      * R�ponse : l'adresse IP
  41.      * Autorit� : info sur le serveur d'autorit�
  42.      * Additionnel : information suppl�mentaire
  43.      */
  44.    
  45.     /**
  46.      * D�finition de l'En-t�te d'un Packet UDP
  47.      * ---------------------------------------
  48.      * Identifiant Param�tres
  49.      * QDcount Ancount
  50.      * NScount ARcount
  51.      *
  52.      *� identifiant est un entier permettant d�identifier la requete.
  53.      *� parametres contient les champs suivant :
  54.      *  � QR (1 bit) : indique si le message est une question (0) ou une reponse (1).
  55.      *  � OPCODE (4 bits) : type de la requete (0000 pour une requete simple).
  56.      *  � AA (1 bit) : le serveur qui a fourni la reponse a-t�il autorite sur le domaine?
  57.      *  � TC (1 bit) : indique si le message est tronque.
  58.      *  � RD (1 bit) : demande d�une requete recursive.
  59.      *  � RA (1 bit) : indique que le serveur peut faire une demande recursive.
  60.      *  � UNUSED, AD, CD (1 bit chacun) : non utilises.
  61.      *  � RCODE (4 bits) : code de retour. 0 : OK, 1 : erreur sur le format de la requete, 2: probleme du serveur,
  62.      *    3 : nom de domaine non trouve (valide seulement si AA), 4 : requete non supportee, 5 : le serveur refuse
  63.      *    de repondre (raisons de s�ecurite ou autres).
  64.      * � QDCount : nombre de questions.
  65.      * � ANCount, NSCount, ARCount : nombre d�entrees dans les champs �Reponse�, �Autorite�, �Additionnel�.
  66.      */
  67.    
  68.     /**
  69.      * Les champs Reponse, Autorite, Additionnel sont tous representes de la meme maniere :
  70.      *
  71.      * � Nom (16 bits) : Pour eviter de recopier la totalite du nom, on utilise des offsets. Par exemple si ce champ
  72.      *   vaut C0 0C, cela signifie qu�on a un offset (C0) de 12 (0C) octets. C�est-a-dire que le nom en clair se trouve
  73.      *   au 12eme octet du message.
  74.      * � Type (16 bits) : idem que pour le champ Question.
  75.      * � Class (16 bits) : idem que pour le champ Question.
  76.      * � TTL (32 bits) : dur�ee de vie de l�entr�ee.
  77.      * � RDLength (16 bits): nombre d�octets de la zone RDData.
  78.      * � RDData (RDLength octets) : reponse
  79.      */
  80.    
  81.     private ByteBuffer bb = null;
  82.     protected final static int BUF_SIZE = 1024;
  83.     protected String SERVER_DNS = null;
  84.     protected int port = 53;  // port de r�ception
  85.     private String DomainName = "none";
  86.     private String DNSFile = null;
  87.     private String adrIP = null;
  88.     private boolean RedirectionSeulement = false;
  89.     private String adresseIP = "";
  90.    
  91.     private String adresseIPClient;
  92.     private int portClient;
  93.    
  94.     public void setport(int p) {
  95.         this.port = p;
  96.     }
  97.    
  98.     public void setRedirectionSeulement(boolean b){
  99.         this.RedirectionSeulement = b;
  100.     }
  101.    
  102.     public String gethostNameFromPacket(){
  103.         return DomainName;
  104.     }
  105.    
  106.     public String getAdrIP(){
  107.         return adrIP;
  108.     }
  109.    
  110.     private void setAdrIP(String ip){
  111.         adrIP = ip;
  112.     }
  113.    
  114.     public void sethostNameFromPacket(String hostname){
  115.         this.DomainName = hostname;
  116.     }
  117.    
  118.     public String getSERVER_DNS(){
  119.         return SERVER_DNS;
  120.     }
  121.    
  122.     public void setSERVER_DNS(String server_dns){
  123.         this.SERVER_DNS = server_dns;
  124.     }
  125.    
  126.     public void UDPReceiver(String SERVER_DNS,int Port) {
  127.         this.SERVER_DNS = SERVER_DNS;
  128.         this.port = Port;
  129.     }
  130.    
  131.     public void setDNSFile(String filename){
  132.         DNSFile = filename;
  133.     }
  134.    
  135.     private void findQueryDomainName() {
  136.         //*Lecture du Query Domain name, a partir du 13 byte
  137.         bb.position(12);
  138.         byte[] byteOff = new byte[1];
  139.         bb.get(byteOff);
  140.         int offset = byteOff[0];
  141.        
  142.         //*Sauvegarde du Query Domain name
  143.        
  144.         this.DomainName = "";
  145.         while(offset != 0) {
  146.             byte[] section = new byte[offset];
  147.            
  148.             bb.get(section);
  149.            
  150.             DomainName += "." + new String(section);
  151.            
  152.             bb.get(byteOff);
  153.             offset = byteOff[0];
  154.         }
  155.         DomainName = DomainName.replaceFirst(".", "");
  156.     }
  157.    
  158.     public void run(){
  159.  
  160.         try{
  161.            
  162.             //*Creation d'un socket UDP
  163.             DatagramSocket udpSocket = new DatagramSocket(port);
  164.            
  165.             //*Boucle infinie de recpetion
  166.             while(true){
  167.                 byte[ ] data = new byte[BUF_SIZE];
  168.                 DatagramPacket packet = new DatagramPacket(data, data.length);
  169.                
  170.                 //*Reception d'un paquet UDP via le socket
  171.                 udpSocket.receive(packet);
  172.                
  173.                 data = packet.getData();
  174.                
  175.                 //*Creation d'un ByteBuffer pour manipuler les bytes du paquet             
  176.                 bb = ByteBuffer.wrap(data);
  177.                
  178.                 //*Lecture et sauvegarde des deux premier bytes, qui specifie l'identifiant            
  179.                 int id = bb.getShort();
  180.                
  181.                 //*Lecture et sauvegarde du huitieme byte, qui specifie le nombre de reponse dans le message
  182.                 bb.position(7);
  183.                 byte[] byteRep = new byte[1];
  184.                 bb.get(byteRep);
  185.  
  186.                 int rep = byteRep[0];
  187.  
  188.                 //*Dans le cas d'une reponse
  189.                 if(rep == 1) {
  190.                    
  191.                     //*Trouve le nom de domaine
  192.                     findQueryDomainName();
  193.                    
  194.                     //*Passe par dessus Query Type et Query Class
  195.                     //*Passe par dessus les premiers champs du ressource record pour arriver au ressource data
  196.                     //*qui contient l'adresse IP associe au hostname (dans le fond saut de 16 bytes)
  197.                     bb.position(bb.position() + 16);
  198.                    
  199.                     //*Capture de l'adresse IP
  200.                     this.adresseIP = "";
  201.                    
  202.                     byte[] byteIP = new byte[1];
  203.                     for(int i=0; i < 4; i++) {
  204.                         bb.get(byteIP);
  205.                         int section = byteIP[0];
  206.                        
  207.                         if(section < 0)
  208.                             adresseIP += "." + (section + 256);
  209.                         else
  210.                             adresseIP += "." + section;
  211.                     }
  212.                     adresseIP = adresseIP.replaceFirst(".", "");
  213.                    
  214.                     //*Ajouter la correspondance dans le fichier seulement si une seule
  215.                     //*reponse dans le message DNS (cette apllication ne traite que ce cas)
  216.                     AnswerRecorder answerRecorder = new AnswerRecorder(DNSFile);
  217.                     answerRecorder.StartRecord(DomainName, adresseIP);
  218.                    
  219.                     //*Faire parvenir le paquet reponse au demandeur original, ayant emis une requete
  220.                     //*avec cet identifiant
  221.                     UDPAnswerPacketCreator udpResponse = new UDPAnswerPacketCreator();
  222.                     packet.setAddress(InetAddress.getByName(adresseIPClient));
  223.                     packet.setPort(portClient);
  224.                     packet.setData(udpResponse.CreateAnswerPacket(data, adresseIP));
  225.                     udpSocket.send(packet);
  226.                    
  227.                 //*Dans le cas d'une requete
  228.                 } else if (rep == 0) {
  229.                     //*Trouve le nom de domaine
  230.                     findQueryDomainName();
  231.                    
  232.                     //*Sauvegarde de l'adresse, du port et de l'identifiant de la requete
  233.                     this.adresseIPClient = packet.getAddress().getHostAddress();
  234.                     this.portClient = packet.getPort();
  235.  
  236.                     //*Si le mode est redirection seulement
  237.                     if(RedirectionSeulement) {
  238.                         //*Rediriger le paquet vers le serveur DNS
  239.                         packet.setSocketAddress(new InetSocketAddress(SERVER_DNS, port));
  240.                         udpSocket.send(packet);
  241.                     //*Sinon
  242.                     } else {   
  243.                         //*Rechercher l'adresse IP associe au Query Domain name dans le fichier de
  244.                         //*correspondance de ce serveur
  245.                         QueryFinder qFinder = new QueryFinder(DNSFile);
  246.                         String adressDomaine = qFinder.StartResearch(DomainName);
  247.                        
  248.                         //*Si la correspondance n'est pas trouvee
  249.                         if("none".equals(adressDomaine)){
  250.                             //*Rediriger le paquet vers le serveur DNS
  251.                             packet.setSocketAddress(new InetSocketAddress(SERVER_DNS, port));
  252.                             udpSocket.send(packet);
  253.                         //*Sinon
  254.                         } else {
  255.                             //*Creer le paquet de reponse a l'aide du UDPAnswerPaquetCreator
  256.                             UDPAnswerPacketCreator udpResponse = new UDPAnswerPacketCreator();
  257.                             packet.setData(udpResponse.CreateAnswerPacket(data, adressDomaine));
  258.                             //*Placer ce paquet dans le socket
  259.                             //*Envoyer le paquet
  260.                             udpSocket.send(packet);
  261.                         }
  262.                     }
  263.                 }
  264.             }
  265.         }catch(Exception e){
  266.             System.err.println("Probl�me � l'ex�cution :");
  267.             e.printStackTrace(System.err);
  268.         }  
  269.     }
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement