diff --git a/Router/ARPLayer.java b/Router/ARPLayer.java index 4a80c46..a2d4795 100644 --- a/Router/ARPLayer.java +++ b/Router/ARPLayer.java @@ -14,19 +14,23 @@ public class ARPLayer implements BaseLayer{ public BaseLayer p_UnderLayer = null; public ArrayList p_aUpperLayer = new ArrayList(); public Hashtable timerList = new Hashtable<>(); + public RouterDlg GUI_Layer; + public ARPTable arpTable; + public int interfaceNum; - byte[] BROADCAST = broadcast(); - - // GUI Layer 변수 - public ApplicationLayer GUI_LAYER; - // ARP Cache Table - public static ArrayList<_ARP_Cache> ArpCacheTable = new ArrayList<>(); + public void setARPTable(ARPTable arpTable) { + this.arpTable = arpTable; + } + + public void setInterfaceNum(int num){ + this.interfaceNum = num; + } + + byte[] BROADCAST = broadcast(); //Proxy Entry Table public static ArrayList<_Proxy_Entry> ProxyEntryTable = new ArrayList<>(); - - class _ARP_MSG { byte[] hardType = new byte[2]; // 2bytes. Type of Hardware Address byte[] protType = new byte[2]; // 2bytes. Type of Protocol Address @@ -102,10 +106,7 @@ public void setDstIPAddr(byte[] dstIPAddr) { } public void setDstBroadcast() { - byte[] buf = new byte[6]; - for(int i = 0 ; i < 6 ; i++) { - buf[i] = (byte)0xFF; - } + byte[] buf = {-1, -1, -1, -1, -1, -1}; this.dstMacAddr = buf; } @@ -131,42 +132,7 @@ public ARPLayer(String pName) { ResetMSG(); // Layer 생성할 때 Reset 한다 } - // ARP Cache - public static class _ARP_Cache { - public byte[] getIpAddr() { - return ipAddr; - } - - public void setIpAddr(byte[] ipAddr) { - this.ipAddr = ipAddr; - } - - public byte[] getMacAddr() { - return macAddr; - } - - public void setMacAddr(byte[] macAddr) { - this.macAddr = macAddr; - } - - public boolean isStatus() { - return status; - } - - public void setStatus(boolean status) { - this.status = status; - } - - byte[] ipAddr; - byte[] macAddr; - boolean status; // complete == true, incomplete == false - - public _ARP_Cache(byte[] ipAddr, byte[] macAddr, boolean status) { - this.ipAddr = ipAddr; - this.macAddr = macAddr; - this.status = status; - } - } + public static class _Proxy_Entry { String hostName; @@ -181,19 +147,20 @@ public _Proxy_Entry (String hostName, byte[] ipAddr, byte[] macAddr) { } - public boolean Send(byte[] input, int length) { + /*public boolean Send(byte[] input, int length) { byte[] dstIPAddress = arp_header.getDstIPAddr(); byte[] srcIPAddress = arp_header.getSrcIPAddr(); int index = -1; + ((EthernetLayer)this.GetUnderLayer()).set_type((byte)0x06); // Sender == Target : GARP MSG if(IsIPEquals(dstIPAddress, srcIPAddress)) { ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(BROADCAST); }else { - index = IsInArpCacheTable(dstIPAddress); + index = arpTable.IsInArpCacheTable(dstIPAddress); if(index >= 0) { System.out.println("ARP Cache Table에 있는 IP주소로 전송 시작"); - byte[] TargetMac = ArpCacheTable.get(index).getMacAddr(); + byte[] TargetMac = arpTable.ArpCacheTable.get(index).getMacAddr(); ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(TargetMac); this.arp_header.setDstMacAddr(TargetMac); @@ -201,11 +168,10 @@ public boolean Send(byte[] input, int length) { System.out.println("ARP Cache Table에 없는 IP주소로 전송 시작"); ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(BROADCAST); //Broadcast로 목적지 설정 byte[] TargetMac = new byte[6]; - _ARP_Cache cache = new _ARP_Cache(dstIPAddress, TargetMac, false); - ArpCacheTable.add(cache); + arpTable.AddARPCache(dstIPAddress, TargetMac, false, this.interfaceNum); // 모르는 주소이므로 3분으로 타이머 설정 - Timer timer = this.setTimeOut(dstIPAddress, 3 * 60 * 1000); - timerList.put(IpToString(dstIPAddress), timer); + //Timer timer = this.setTimeOut(dstIPAddress, 3 * 60 * 1000); + //timerList.put(IpToString(dstIPAddress), timer); } } @@ -214,14 +180,95 @@ public boolean Send(byte[] input, int length) { return true; - + }*/ + + public void setSrcIP(byte[] srcIP){ + this.arp_header.setSrcIPAddr(srcIP); } + public void setDstIP(byte[] dstIP){ + this.arp_header.setDstIPAddr(dstIP); + } + + public void setSrcMac(byte[] srcMac){ + this.arp_header.setSrcMacAddr(srcMac); + } + + public void setDstMac(byte[] dstMac){ + this.arp_header.setDstMacAddr(dstMac); + } + + public boolean Send(byte[] input, int length, byte[] dstIP){ + this.arp_header.setDstIPAddr(dstIP); + int index = arpTable.IsInArpCacheTable(dstIP); + if(index < 0) { + return arpSend(input, length, dstIP); + } + boolean state = false; + while(!state){ + try { + Thread.sleep(100); //기다린다 + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + state = arpTable.getARPCache(index).status; + } + return dataSend(input, input.length, arpTable.getARPCache(index).getMacAddr()); + + + } + + // arp 전송 함수 + public boolean arpSend(byte[] input, int length, byte[] targetIP){ + byte[] msg = new byte[1]; + ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(BROADCAST); + ((EthernetLayer)this.GetUnderLayer()).set_type((byte)0x06); + byte[] TargetMac = new byte[6]; + int interfaceNum = (int)targetIP[2]; + arpTable.UpdateARPCache(targetIP, TargetMac, false, interfaceNum); + GUI_Layer.ARPTableUpdate(targetIP, TargetMac, false, interfaceNum); + byte[] packet = ObjToByte(arp_header, msg, msg.length); + return ((EthernetLayer)this.GetUnderLayer()).Send(packet, packet.length); + } + + // data 전송함수 + public boolean dataSend(byte[] input, int length, byte[] TargetMac){ + ((EthernetLayer)this.GetUnderLayer()).set_type((byte)0x00); + ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(TargetMac); + this.arp_header.setDstMacAddr(TargetMac); + // 그냥 그대로 전달 -> 아는 주소니까 + return ((EthernetLayer)this.GetUnderLayer()).Send(input, input.length); + + } + + + + // GARP + public boolean GARPSend(byte[] input){ + this.arp_header.setDstIPAddr(this.arp_header.srcIPAddr); + ((EthernetLayer)this.GetUnderLayer()).set_type((byte)0x06); + byte[] garp = new byte[28]; + + garp[0] = arp_header.hardType[0]; + garp[1] = arp_header.hardType[1]; + garp[2] = arp_header.protType[0]; + garp[3] = arp_header.protType[1]; + garp[4] = arp_header.hardSize; + garp[5] = arp_header.protSize; + garp[6] = arp_header.opCode[0]; + garp[7] = arp_header.opCode[1]; + + System.arraycopy(arp_header.getSrcMacAddr(), 0, garp, 8, 6); + System.arraycopy(arp_header.getSrcIPAddr(), 0, garp, 14, 4); + System.arraycopy(arp_header.getDstMacAddr(), 0, garp, 18, 6); + System.arraycopy(arp_header.getDstIPAddr(), 0, garp, 24, 4); + ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(broadcast()); + return ((EthernetLayer)this.GetUnderLayer()).Send(garp, garp.length); + } // Reply Send할 때 쓸 함수 public boolean ReplySend(byte[] request) { - - System.out.println("==== 응답 전송 ===="); // 받은 ARP RequstMsg에서의 주소 byte[] rplMsg = new byte[request.length]; System.arraycopy(request, 0, rplMsg, 0, request.length); @@ -233,55 +280,45 @@ public boolean ReplySend(byte[] request) { byte[] targetMac = new byte[6]; System.arraycopy(rplMsg, 18, targetMac, 0, 6); - + ((EthernetLayer)this.GetUnderLayer()).set_type((byte)0x06); ((EthernetLayer)this.GetUnderLayer()).set_dstaddr(targetMac); ((EthernetLayer)this.GetUnderLayer()).Send(rplMsg, rplMsg.length); return true; } - public static void PrintMsg(byte[] input) { - System.out.print("Msg내용 : "); - for(int i = 0 ; i < input.length ; i++) { - System.out.print(input[i]); - } - System.out.println(); - } // Receive 함수 - public boolean Receive(byte[] input) { - System.out.print("메세지 받는중 : "); + public synchronized boolean Receive(byte[] input) { byte[] opCode = Arrays.copyOfRange(input, 6, 8); byte[] SenderMac = Arrays.copyOfRange(input, 8, 14); byte[] SenderIP = Arrays.copyOfRange(input, 14,18); byte[] TargetIP = Arrays.copyOfRange(input, 24,28); + /* // 이미 존재하는 IP 주소라면( timer Reset함 ) if(timerList.containsKey(IpToString(SenderIP))){ System.out.println("Timer를 취소합니다 - IP 주소 : " + IpToString(SenderIP)); timerList.get(IpToString(SenderIP)).cancel(); - } + }q + */ - System.out.println("== 새 Timer 설정(MAC 주소를 알고 있으므로 20분으로 설정합니다) =="); - Timer timer = this.setTimeOut(SenderIP, 20 * 60 * 1000); - timerList.put(IpToString(SenderIP), timer); + //System.out.println("== 새 Timer 설정(MAC 주소를 알고 있으므로 20분으로 설정합니다) =="); + //Timer timer = this.setTimeOut(SenderIP, 20 * 60 * 1000); + //timerList.put(IpToString(SenderIP), timer); if(opCode[1] == (byte) 0x01){ - // GARP 받은 경우 - if(IsIPEquals(SenderIP, TargetIP)) { - System.out.println("GARP MSG 받음"); - - } // 나한테 온 것 -> Reply보내야함 - else if(IsMyIP(TargetIP) || IsInProxyTable(TargetIP)) { - System.out.println("응답 메세지 보냅니다."); + if(IsMyIP(TargetIP) || IsInProxyTable(TargetIP)) { ReplySend(input); } } - UpdateARPCache(SenderIP, SenderMac, true); - GUI_LAYER.GetArpTable(); // ARP Table 업데이트 + int interfaceNum = SenderIP[2]; + arpTable.UpdateARPCache(SenderIP, SenderMac, true, interfaceNum); + GUI_Layer.ARPTableUpdate(SenderIP, SenderMac, true, interfaceNum); // ARP Table 업데이트 return true; } + // _ARP_MSG Object를 byte[]로 바꿔주는 함수 public byte[] ObjToByte(_ARP_MSG arpMsg, byte[] input, int length) { @@ -327,18 +364,7 @@ public byte[] StringToIP(String ipAddr){ } - // ARP Msg의 Target IP와 나의 IP 주소와 비교 - public boolean IsMyIP (byte[] targetIP) { - byte[] myIP = arp_header.getSrcIPAddr(); - for(int i = 0; i < 4 ; i++) { - // 일치하지 않는 경우 - if (myIP[i] != targetIP[i]) { - System.out.println(i +"번째 주소 일치하지 않음"); - return false; - } - } - return true; - } + // Proxy Table에 있는지 확인하는 함수 public boolean IsInProxyTable(byte[] targetIP) { @@ -349,71 +375,28 @@ public boolean IsInProxyTable(byte[] targetIP) { _Proxy_Entry entry = iter.next(); byte[] addr = entry.ipAddr; if (IsIPEquals(targetIP, addr)){ - System.out.println("Proxy 테이블에 존재"); return true; } } return false; //Proxy Table에 존재하지 않는 경우 } - // Arp Cache Table에 있는지 확인하는 함수 - public int IsInArpCacheTable(byte[] targetIP) { - // iterator로 ArrayList를 순회 - int index = 0; - Iterator <_ARP_Cache> iter = ArpCacheTable.iterator(); - while(iter.hasNext()) { - // targetIP와 Entry의 IP주소가 같은지 확인 - _ARP_Cache target = iter.next(); - if(IsIPEquals(targetIP, target.ipAddr)) return index; - else index++; - } - return -1; //ARP Table에 존재하지 않는 경우 - } - - public boolean IsIPEquals(byte[] ip1, byte[] ip2) { - for(int i = 0; i < 4; i++) { - if(ip1[i] != ip2[i]){ + // ARP Msg의 Target IP와 나의 IP 주소와 비교 + public boolean IsMyIP (byte[] targetIP) { + byte[] myIP = arp_header.getSrcIPAddr(); + for(int i = 0; i < 4 ; i++) { + // 일치하지 않는 경우 + if (myIP[i] != targetIP[i]) { return false; } } return true; } - - // ARP Cache Table 추가하는 함수 - public boolean AddARPCache(byte[] IPAddr, byte[] MACAddr, boolean status) { - _ARP_Cache newArpCache = new _ARP_Cache(IPAddr, MACAddr, status); - ArpCacheTable.add(newArpCache); - return true; + + public boolean IsIPEquals(byte[] ip1, byte[] ip2) { + return Arrays.equals(ip1, ip2); } - // ARP Cache Table 삭제하는 함수 - public boolean RemoveARPCache(byte[] IPAddr) { - for(int i = 0; i < ArpCacheTable.size() ; i++) { - // 순회하면서 지우려고 하는 IP주소가 있는지 확인. - if(Arrays.equals(ArpCacheTable.get(i).ipAddr, IPAddr)) { - ArpCacheTable.remove(i); // ArrayList에서 index이용해 제거한다. - return true; - }if(timerList.containsKey(IpToString(IPAddr))){ - System.out.println("Timer를 취소합니다 - IP 주소 : " + IpToString(IPAddr)); - timerList.get(IpToString(IPAddr)).cancel(); - } - } - return false; - } - // ARP Cache Table 업데이트 하는 함수 - public boolean UpdateARPCache(byte[] IPAddr, byte[] MACAddr, boolean status) { - // iterator로 ArrayList를 순회 - int idx = IsInArpCacheTable(IPAddr); - if(idx >= 0){ - ArpCacheTable.get(idx).setIpAddr(IPAddr); - ArpCacheTable.get(idx).setMacAddr(MACAddr); - ArpCacheTable.get(idx).setStatus(status); - } else { - ArpCacheTable.add(new _ARP_Cache(IPAddr, MACAddr, status)); - } - - return false; - } // Proxy Table에 Entry 추가하는 함수 public boolean AddPoxyEntry(String hostName, byte[] ipAddr, byte[] macAddr) { @@ -442,8 +425,8 @@ public byte[] broadcast() { } // GUI Layer 설정하는 함수 - public void SetGUI(ApplicationLayer GUI) { - this.GUI_LAYER = GUI; + public void SetGUI(RouterDlg GUI) { + this.GUI_Layer = GUI; } @@ -488,21 +471,22 @@ public void SetUpperUnderLayer(BaseLayer pUULayer) { } - /* Timer 관련 함수 생성 */ +/* Timer 부분은 일단 제거 + * Timer 관련 함수 생성 private Timer setTimeOut(byte[] srcIPAddr, long time) { Timer timer = new Timer(IpToString(srcIPAddr)); // Timer 생성 TimerTask task = new TimerTask() { @Override public void run() { // TODO Auto-generated method stub - RemoveARPCache(StringToIP(Thread.currentThread().getName())); // 삭제한다. + ARPTable.RemoveARPCache(StringToIP(Thread.currentThread().getName())); // 삭제한다. GUI_LAYER.GetArpTable(); // Update System.out.println("!!TimeOut!! - IP주소: " +Thread.currentThread().getName()+"가 "+ time / 1000 + "초가 지나서 삭제되었습니다."); } }; timer.schedule(task, time); // timer return timer; - } + }*/ diff --git a/Router/ARPTable.java b/Router/ARPTable.java new file mode 100644 index 0000000..a38bdb9 --- /dev/null +++ b/Router/ARPTable.java @@ -0,0 +1,113 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + + +public class ARPTable { + + // ARP Cache Table + public static ArrayList<_ARP_Cache> ArpCacheTable = new ArrayList<>(); + + + // ARP Cache + public static class _ARP_Cache { + public byte[] getIpAddr() { + return ipAddr; + } + + public void setIpAddr(byte[] ipAddr) { + this.ipAddr = ipAddr; + } + + public byte[] getMacAddr() { + return macAddr; + } + + public void setMacAddr(byte[] macAddr) { + this.macAddr = macAddr; + } + + public boolean isStatus() { + return status; + } + + public void setStatus(boolean status) { + this.status = status; + } + + public int getInterNum(){ + return this.interfaceNum; + } + + byte[] ipAddr; + byte[] macAddr; + boolean status; // complete == true, incomplete == false + int interfaceNum; + + public _ARP_Cache(byte[] ipAddr, byte[] macAddr, boolean status, int interfaceNum) { + this.ipAddr = ipAddr; + this.macAddr = macAddr; + this.status = status; + this.interfaceNum = interfaceNum; + } + } + + + + // Arp Cache Table에 있는지 확인하는 함수 + public static int IsInArpCacheTable(byte[] targetIP) { + // iterator로 ArrayList를 순회 + int index = 0; + for(int i = 0; i < ArpCacheTable.size(); i++) { + // targetIP와 Entry의 IP주소가 같은지 확인 + _ARP_Cache target = ArpCacheTable.get(i); + if(IsIPEquals(targetIP, target.ipAddr)){ + index = i; + return index; + } + } + return -1; //ARP Table에 존재하지 않는 경우 + } + + // ARP Cache Table 추가하는 함수 + public boolean AddARPCache(byte[] IPAddr, byte[] MACAddr, boolean status, int interfaceNum) { + _ARP_Cache newArpCache = new _ARP_Cache(IPAddr, MACAddr, status, interfaceNum); + ArpCacheTable.add(newArpCache); + return true; + } + + // ARP Cache Table 삭제하는 함수 + public boolean RemoveARPCache(byte[] IPAddr) { + for(int i = 0; i < ArpCacheTable.size() ; i++) { + // 순회하면서 지우려고 하는 IP주소가 있는지 확인. + if(Arrays.equals(ArpCacheTable.get(i).ipAddr, IPAddr)) { + ArpCacheTable.remove(i); // ArrayList에서 index이용해 제거한다. + return true; + } + } + return false; + } + // ARP Cache Table 업데이트 하는 함수 + public static boolean UpdateARPCache(byte[] IPAddr, byte[] MACAddr, boolean status, int interfaceNum) { + // iterator로 ArrayList를 순회 + int index = IsInArpCacheTable(IPAddr); + if(index >= 0){ + ArpCacheTable.get(index).setIpAddr(IPAddr); + ArpCacheTable.get(index).setMacAddr(MACAddr); + ArpCacheTable.get(index).setStatus(status); + } else { + ArpCacheTable.add(new _ARP_Cache(IPAddr, MACAddr, status, interfaceNum)); + } + return true; + } + + public static _ARP_Cache getARPCache(int index){ + return ArpCacheTable.get(index); + } + + public static boolean IsIPEquals(byte[] ip1, byte[] ip2) { + return Arrays.equals(ip1, ip2); + } + + +} diff --git a/Router/ApplicationLayer.java b/Router/ApplicationLayer.java deleted file mode 100644 index 38f05be..0000000 --- a/Router/ApplicationLayer.java +++ /dev/null @@ -1,570 +0,0 @@ -import javax.swing.*; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.*; - -import org.jnetpcap.Pcap; -import org.jnetpcap.PcapIf; -import org.jnetpcap.packet.PcapPacket; -import org.jnetpcap.packet.PcapPacketHandler; - -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.Font; -import java.awt.List; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.Color; - -import javax.swing.border.EmptyBorder; -import javax.swing.border.TitledBorder; -import javax.swing.border.BevelBorder; - -public class ApplicationLayer extends JFrame implements BaseLayer{ - - public int nUpperLayerCount = 0; - public String pLayerName = null; - public BaseLayer p_UnderLayer = null; - public ArrayList p_aUpperLayer = new ArrayList(); - public ArrayList m_pAdapterList; - public byte[] MY_IP; - public byte[] MY_MAC; - - String path; - - private static LayerManager m_LayerMgr = new LayerManager(); - int selected_index; - - public static void main(String[] args) { - m_LayerMgr.AddLayer(new NILayer("NI")); - m_LayerMgr.AddLayer(new EthernetLayer("ETHERNET")); - m_LayerMgr.AddLayer(new ARPLayer("ARP")); - m_LayerMgr.AddLayer(new IPLayer("IP")); - m_LayerMgr.AddLayer(new TCPLayer("TCP")); - m_LayerMgr.AddLayer(new ApplicationLayer("GUI")); - - - m_LayerMgr.ConnectLayers(" NI ( *ETHERNET ( +IP ( *TCP ( *GUI ) ) ) ) "); - // ARP Layer - IP Layer 단방향 연결 - m_LayerMgr.GetLayer("IP").SetUnderLayer(m_LayerMgr.GetLayer("ARP")); - // ARP Layer - Ethernet Layer 양방향 연결 - m_LayerMgr.GetLayer("ETHERNET").SetUpperUnderLayer(m_LayerMgr.GetLayer("ARP")); - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).SetGUI(((ApplicationLayer)m_LayerMgr.GetLayer("GUI")));//Update를 위해 변수로 전달함. - - } - - private JPanel contentPanel; // 전체 화면 JPanel - - private JPanel BasicPanel; // Basic ARP용 JPanel - private List ARPCacheList; // ARP Cache Table Display - private JButton btnItemDelete; // Basic ARP Selected Item Delete Button - private JButton btnAllDelete; // Basic ARP All ITem Delete Button - private JTextField IPAddrInput; // Basic ARP IP Input Field - private JButton btnBasicSend; // Basic ARP IP Send Button - - private JPanel ProxyPane; // Proxy ARP용 Panel - private List ProxyEntryList; // Proxy Entry Display - private JButton btnProxyAdd; // Proxy Entry Add Button - private JButton btnProxyDelete; // Proxy Entry Delete Button - - private JPanel GratuitousPane; // Gratuitous ARP용 Panel - private JTextField GARPAddrInput; // Gratuitous ARP MAC Address Input Field - private JButton btnGratSend; // Gratuitous ARP Mac Address Send Button - private JLabel lblDevice; - private JLabel lblIpAddress; - private JLabel lblMacAddress; - private JTextField DeviceName; - private JTextField ProxyIPAddr; - private JTextField ProxyMACAddr; - private JTextField srcMacAddress; - private JTextField srcIPAddress; - - private JComboBox NICList; - - - - /* ARP Table Dlg*/ - public ApplicationLayer(String pName) { - setTitle("TestARP"); - pLayerName = pName; - - setBounds(250, 250, 1115, 525); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - contentPanel = new JPanel(); - contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); - getContentPane().add(contentPanel, BorderLayout.CENTER); - contentPanel.setLayout(null); - - BasicPanel = new JPanel(); - BasicPanel.setBorder(new TitledBorder(null, "ARP Cache", TitledBorder.LEADING, TitledBorder.TOP, null, null)); - BasicPanel.setBounds(14, 29, 351, 429); - contentPanel.add(BasicPanel); - BasicPanel.setLayout(null); - - ARPCacheList = new List(); - //ARPCacheList.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null)); - ARPCacheList.setBounds(13, 23, 324, 269); - BasicPanel.add(ARPCacheList); - GetArpTable(); - - btnItemDelete = new JButton("Item Delete"); - btnItemDelete.setBounds(32, 298, 127, 42); - BasicPanel.add(btnItemDelete); - // ARP Cache Entry 삭제 버튼(선택한 것만 지운다) - btnItemDelete.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - int index = ARPCacheList.getSelectedIndex(); - if(index >= 0) { - DeleteARP(index); - } - } - }); - - btnAllDelete = new JButton("All Detete"); - btnAllDelete.setBounds(196, 298, 127, 42); - btnAllDelete.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if(e.getSource() == btnAllDelete){ - ARPLayer.ArpCacheTable.clear(); - GetArpTable(); - } - } - }); - BasicPanel.add(btnAllDelete); - - JLabel IPAddrLabel = new JLabel("IP Address"); - IPAddrLabel.setBounds(13, 352, 134, 18); - BasicPanel.add(IPAddrLabel); - - - // ARP Send 버튼 - btnBasicSend = new JButton("Send"); - btnBasicSend.setBounds(262, 382, 75, 35); - btnBasicSend.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent e) { - if (e.getSource() == btnBasicSend) { //BasicPanel의 Send버튼 : BasicARPSend 동작하는 함수 - // Step1. IPAddrInput의 값을 읽어와서 byte[]로 변경 - // Step2. ARPLayer의 Send함수 호출 - // Step3. Application Layer의 ArpCacheList 업데이트 - - //Step1 - String[] dstIP = IPAddrInput.getText().split("\\."); - byte[] dstIPAddr = new byte[4]; - for (int i = 0; i < 4; i++) { - dstIPAddr[i] = (byte) Integer.parseInt(dstIP[i]); - } - IPAddrInput.setText(""); - - // Step2 - String msg = ""; // 상위 Layer에서 내려가는 data - byte[] input = msg.getBytes(); - - // ARP Layer의 dstIP 주소를 dstIPAddr로 설정한다. - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).arp_header.setDstIPAddr(dstIPAddr); - // IP Layer의 dstIP주소를 dstIPAddr로 설정한다. - ((IPLayer)m_LayerMgr.GetLayer("IP")).m_sHeader.setIp_dst(dstIPAddr); - - // TCP Layer로 내려보낸다. - ((TCPLayer)m_LayerMgr.GetLayer("TCP")).Send(input, 0); - //Step3 - GetArpTable(); - } - } - }); - BasicPanel.add(btnBasicSend); - - IPAddrInput = new JTextField(); - IPAddrInput.setBounds(13, 382, 235, 35); - BasicPanel.add(IPAddrInput); - IPAddrInput.setColumns(10); - - ProxyPane = new JPanel(); - ProxyPane.setBorder(new TitledBorder(null, "Proxy ARP Entry", TitledBorder.LEADING, TitledBorder.TOP, null, null)); - ProxyPane.setBounds(371, 29, 349, 429); - contentPanel.add(ProxyPane); - ProxyPane.setLayout(null); - - ProxyEntryList = new List(); - //ProxyEntryList.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null)); - ProxyEntryList.setBounds(14, 24, 321, 200); - ProxyPane.add(ProxyEntryList); - - btnProxyAdd = new JButton("Add"); - btnProxyAdd.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - AddProxyEntry(DeviceName.getText(), ProxyIPAddr.getText(), ProxyMACAddr.getText()); - GetProxyTable(); - DeviceName.setText(""); - ProxyIPAddr.setText(""); - ProxyMACAddr.setText(""); - } - }); - - btnProxyAdd.setBounds(51, 384, 105, 33); - - ProxyPane.add(btnProxyAdd); - - btnProxyDelete = new JButton("Delete"); - btnProxyDelete.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - int index = ProxyEntryList.getSelectedIndex(); - if(index >= 0) { - DeleteProxy(index); - } - GetProxyTable();//Proxy Table 갱신 - } - }); - btnProxyDelete.setBounds(195, 384, 105, 33); - ProxyPane.add(btnProxyDelete); - - lblDevice = new JLabel("Device"); - lblDevice.setHorizontalAlignment(SwingConstants.RIGHT); - lblDevice.setBounds(27, 253, 89, 18); - ProxyPane.add(lblDevice); - - lblIpAddress = new JLabel("IP Address"); - lblIpAddress.setHorizontalAlignment(SwingConstants.RIGHT); - lblIpAddress.setBounds(27, 295, 89, 18); - ProxyPane.add(lblIpAddress); - - lblMacAddress = new JLabel("MAC Address"); - lblMacAddress.setHorizontalAlignment(SwingConstants.RIGHT); - lblMacAddress.setBounds(27, 338, 89, 18); - ProxyPane.add(lblMacAddress); - - DeviceName = new JTextField(); - DeviceName.setBounds(130, 250, 182, 24); - ProxyPane.add(DeviceName); - DeviceName.setColumns(10); - - ProxyIPAddr = new JTextField(); - ProxyIPAddr.setColumns(10); - ProxyIPAddr.setBounds(130, 292, 182, 24); - ProxyPane.add(ProxyIPAddr); - - ProxyMACAddr = new JTextField(); - ProxyMACAddr.setColumns(10); - ProxyMACAddr.setBounds(130, 335, 182, 24); - ProxyPane.add(ProxyMACAddr); - - GratuitousPane = new JPanel(); - GratuitousPane.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Gratuitous ARP", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0))); - GratuitousPane.setBounds(734, 39, 349, 191); - contentPanel.add(GratuitousPane); - GratuitousPane.setLayout(null); - - JLabel lblHwA = new JLabel("H/W Address"); - lblHwA.setHorizontalAlignment(SwingConstants.LEFT); - lblHwA.setBounds(14, 42, 135, 34); - GratuitousPane.add(lblHwA); - - - GARPAddrInput = new JTextField(); - GARPAddrInput.setBounds(14, 75, 321, 34); - GratuitousPane.add(GARPAddrInput); - GARPAddrInput.setColumns(10); - - // Gratuitous ARP의 Send 버튼 - btnGratSend = new JButton("Send"); - btnGratSend.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (e.getSource() == btnGratSend) { - System.out.println("==== GARP 전송입니다.===="); - String newMacAddr = GARPAddrInput.getText(); - byte[] newAddr = StringToMAC(newMacAddr); // 입력된 MAC 주소(변경된 내 MAC 주소) - -// // ARP Layer의 src Mac 주소는 newAddr로, dstIP주소는 MY_IP로 설정한다. - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).arp_header.setSrcMacAddr(newAddr); // Sender 주소 - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).arp_header.setDstIPAddr(MY_IP); -// ((ARPLayer)m_LayerMgr.GetLayer("ARP")).arp_header.setDstMacAddr(newAddr); // Target 주소 - - // IPLayer의 dst,src ip주소를 나의 ip 주소로 설정한다. - ((IPLayer)m_LayerMgr.GetLayer("IP")).m_sHeader.setIp_dst(MY_IP); - ((IPLayer)m_LayerMgr.GetLayer("IP")).m_sHeader.setIp_src(MY_IP); - byte[] bc = new byte[6]; - for(int i = 0 ; i < 6 ; i++) { - bc[i] = (byte)0xff; - } - - //((EthernetLayer)m_LayerMgr.GetLayer("ETHERNET")).set_srcaddr(newAddr); // Ethernet Layer의 src mac 주소를 addr로 설정한다. - ((EthernetLayer)m_LayerMgr.GetLayer("ETHERNET")).set_dstaddr(bc); // broadcast 설정 - - // TCP Layer로 내려보낸다. - String msg = ""; // 상위 Layer에서 내려가는 data - byte[] input = msg.getBytes(); - ((TCPLayer)m_LayerMgr.GetLayer("TCP")).Send(input, input.length); - } - } - }); - btnGratSend.setBounds(144, 132, 75, 39); - GratuitousPane.add(btnGratSend); - - - - JPanel panel = new JPanel(); - panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Address", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0))); - panel.setBounds(734, 252, 349, 206); - contentPanel.add(panel); - panel.setLayout(null); - - NICList = new JComboBox(); - NICList.setBounds(120, 43, 188, 24); - panel.add(NICList); - - JLabel lblNewLabel = new JLabel("NIC List"); - lblNewLabel.setBounds(14, 46, 92, 18); - panel.add(lblNewLabel); - - JLabel lblMacAddress = new JLabel("MAC Address"); - lblMacAddress.setBounds(14, 82, 92, 18); - panel.add(lblMacAddress); - - JLabel lblIpAddress = new JLabel("IP Address"); - lblIpAddress.setBounds(14, 118, 92, 18); - panel.add(lblIpAddress); - - srcMacAddress = new JTextField(); - srcMacAddress.setBounds(120, 79, 188, 24); - panel.add(srcMacAddress); - srcMacAddress.setColumns(10); - - srcIPAddress = new JTextField(); - srcIPAddress.setColumns(10); - srcIPAddress.setBounds(120, 115, 188, 24); - panel.add(srcIPAddress); - - // Network Interface Card 설정하는 부분 - JButton btnSetting = new JButton("Setting"); - btnSetting.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - - String selected = NICList.getSelectedItem().toString(); - selected_index = NICList.getSelectedIndex(); - // Network Layer에서 Adapter Number 저장 - ((NILayer) m_LayerMgr.GetLayer("NI")).SetAdapterNumber(selected_index); - - srcMacAddress.setText(""); - String MacAddr = ""; - byte[] MacAddress = new byte[6]; - - // 해당 Network Interface에서 Ethernet 주소를 가져오는 함수 - try { - MacAddress = ((NILayer) m_LayerMgr.GetLayer("NI")).GetAdapterObject(selected_index) - .getHardwareAddress(); - MacAddr = macToString(MacAddress).toUpperCase(); - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - srcMacAddress.setText(MacAddr); - MY_MAC = MacAddress; // 나의 MAC 주소를 Application Layer에 저장함 - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).arp_header.setSrcMacAddr(MY_MAC); - ((EthernetLayer)m_LayerMgr.GetLayer("ETHERNET")).set_srcaddr(MY_MAC); - - // IP주소 저장하는 과정. - srcIPAddress.setText(""); - String IPAddress = ""; - - // 현재 내 IP 주소 가져오기 : String Type - try { - IPAddress = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } - srcIPAddress.setText(IPAddress); - MY_IP = StringToIP(IPAddress); - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).arp_header.setSrcIPAddr(MY_IP); - ((IPLayer)m_LayerMgr.GetLayer("IP")).m_sHeader.setIp_src(MY_IP); //IP Layer에 나의 IP 저장 - - // 여기까지 기본 설정(NI Adapter 설정, 나의 MAC 주소 설정, 나의 IP 주소 저장) - - } - }); - btnSetting.setBounds(230, 151, 105, 38); - panel.add(btnSetting); - - setVisible(true); - SetCombobox(); - - - } - - // Network Interface 목록을 가져옴 - private void SetCombobox() { - java.util.List m_pAdapterList = new ArrayList(); - StringBuilder errbuf = new StringBuilder(); - - int r = Pcap.findAllDevs(m_pAdapterList, errbuf); - if (r == Pcap.NOT_OK || m_pAdapterList.isEmpty()) { - System.err.printf("Can't read list of devices, error is %s", errbuf.toString()); - return; - } - for (int i = 0; i < m_pAdapterList.size(); i++) - this.NICList.addItem(m_pAdapterList.get(i).getDescription()); - } - - - // GetArpTable : ARPLayer의 ARPCacheTable을 읽어오는 함수 - public boolean GetArpTable() { - // AppLayer의 ARPCacheList 초기화 - ARPCacheList.removeAll(); - Iterator iter = ARPLayer.ArpCacheTable.iterator(); - while(iter.hasNext()) { - ARPLayer._ARP_Cache arpCache = iter.next(); - byte[] ipAddr = arpCache.ipAddr; - byte[] macAddr = arpCache.macAddr; - String status = arpCache.status == true ? "Complete" : "Incomplete"; //status에 따라 다르게 나타나도록 - String strMacAddr = ""; - String strIPAddr = ipToString(ipAddr); - - // MAC 주소 알면 MAC 주소로, 모르면 ????????로 나타냄 - strMacAddr = arpCache.status == true ? macToString(macAddr) : "?????????????"; - ARPCacheList.add(String.format("%15s", strIPAddr) + " " + strMacAddr + " " + status); - System.out.println("Table 갯수 : " + ARPLayer.ArpCacheTable.size()); - } - return true; - } - // DeleteARP - public boolean DeleteARP(int index){ - // ARP Layer에서 해당 index의 ARP Cache를 제거 - ARPLayer.ArpCacheTable.remove(index); - // GUI Update - GetArpTable(); - return true; - } - - // Add Proxy Entry - public boolean AddProxyEntry(String DeviceName, String IpAddr, String MacAddr) { - byte[] ipAddr = StringToIP(IpAddr); - byte[] macAddr = StringToMAC(MacAddr); - ARPLayer._Proxy_Entry newProxy = new ARPLayer._Proxy_Entry(DeviceName, ipAddr, macAddr); - ARPLayer.ProxyEntryTable.add(newProxy); - return true; - } - - // Proxy Table Get - public boolean GetProxyTable() { - // AppLayer의 Proxy Table 초기화 - ProxyEntryList.removeAll(); - // iterator 순회하면서 table의 값들을 읽어온다. - Iterator iter = ARPLayer.ProxyEntryTable.iterator(); - while(iter.hasNext()) { - ARPLayer._Proxy_Entry proxyEntry = iter.next(); - // AppLayer의 List에 나타내기 위해 String으로 모두 변경 - String DeviceName = proxyEntry.hostName; - String ipAddr = ipToString(proxyEntry.ipAddr); - String macAddr = macToString(proxyEntry.macAddr); - ProxyEntryList.add(DeviceName + " " + ipAddr + " " + macAddr); - } - return true; - } - - // Delete Proxy Entry - public boolean DeleteProxy(int index) { - ((ARPLayer)m_LayerMgr.GetLayer("ARP")).ProxyEntryTable.remove(index); - System.out.println("ProxyTableSize : " + ((ARPLayer)m_LayerMgr.GetLayer("ARP")).ProxyEntryTable.size()); - return true; - } - - // byte[]의 IP주소를 String으로 반환(000.000.000.000)의 형태 - public String ipToString(byte[] ipAddr) { - String ipStr = new String(); - for (int i = 0 ; i < 4; i++) { - // 중간에는 .으로 구분함 - if(i != 3) { - ipStr += ipAddr[i] & 0xFF; - ipStr += "."; - } - else { - ipStr += ipAddr[i] & 0xFF; - } - } - return ipStr; - } - // String의 IP주소를 byte[]로 변환 - public byte[] StringToIP(String ipAddr){ - byte[] buf = new byte[4]; - String[] temp = ipAddr.split("\\."); - for(int i = 0; i < 4; i++){ - buf[i] = (byte)Integer.parseInt(temp[i]); - } - - return buf; - } - - // byte[]의 MAC 주소를 String으로 변환(FF:FF:FF:FF:FF:FF)의 형태 - public String macToString(byte[] macAddr) { - String macStr = ""; - for(int i = 0 ; i < 6; i++){ - macStr += String.format("%02X", macAddr[i] & 0xFF).toUpperCase(); - //macStr += Integer.toHexString(macAddr[i] & 0xFF).toUpperCase(); - if(i != 5) { - macStr += ":"; - } - - } - return macStr; - } - // String MAC 주소를 byte[]로 변환 - public byte[] StringToMAC(String macAddr){ - byte[] buf = new byte[6]; - String[] temp = macAddr.split(":"); - for(int i = 0 ; i < 6 ; i++){ - int hex = Integer.parseUnsignedInt(temp[i], 16); - buf[i] = (byte)hex; - } - return buf; - } - - @Override - public void SetUnderLayer(BaseLayer pUnderLayer) { - // TODO Auto-generated method stub - if (pUnderLayer == null) - return; - this.p_UnderLayer = pUnderLayer; - } - - @Override - public void SetUpperLayer(BaseLayer pUpperLayer) { - // TODO Auto-generated method stub - if (pUpperLayer == null) - return; - this.p_aUpperLayer.add(nUpperLayerCount++, pUpperLayer); - // nUpperLayerCount++; - } - - @Override - public String GetLayerName() { - // TODO Auto-generated method stub - return pLayerName; - } - - @Override - public BaseLayer GetUnderLayer() { - // TODO Auto-generated method stub - if (p_UnderLayer == null) - return null; - return p_UnderLayer; - } - - @Override - public BaseLayer GetUpperLayer(int nindex) { - // TODO Auto-generated method stub - if (nindex < 0 || nindex > nUpperLayerCount || nUpperLayerCount < 0) - return null; - return p_aUpperLayer.get(nindex); - } - - @Override - public void SetUpperUnderLayer(BaseLayer pUULayer) { - this.SetUpperLayer(pUULayer); - pUULayer.SetUnderLayer(this); - - } -} - - diff --git a/Router/EthernetLayer.java b/Router/EthernetLayer.java index f832460..4d17bf5 100644 --- a/Router/EthernetLayer.java +++ b/Router/EthernetLayer.java @@ -5,6 +5,7 @@ import java.io.Serializable; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Arrays; public class EthernetLayer implements BaseLayer { public int nUpperLayerCount = 0; @@ -12,70 +13,76 @@ public class EthernetLayer implements BaseLayer { public BaseLayer p_UnderLayer = null; public ArrayList p_aUpperLayer = new ArrayList(); - private class _ETHERNET_ADDR { - private byte[] addr = new byte[6]; - - public _ETHERNET_ADDR() { - this.addr[0] = (byte) 0x00; - this.addr[1] = (byte) 0x00; - this.addr[2] = (byte) 0x00; - this.addr[3] = (byte) 0x00; - this.addr[4] = (byte) 0x00; - this.addr[5] = (byte) 0x00; - } - } - + // UpperLayer 0번 : IP Layer 1번 : ARPLayer private class _ETHERNET_HEADER { - _ETHERNET_ADDR enet_dstaddr; - _ETHERNET_ADDR enet_srcaddr; - byte[] enet_type; + byte[] enet_dstaddr; + byte[] enet_srcaddr; + byte[] enet_type = new byte[2]; byte[] enet_data; public _ETHERNET_HEADER() { - this.enet_dstaddr = new _ETHERNET_ADDR(); - this.enet_srcaddr = new _ETHERNET_ADDR(); - this.enet_type = new byte[2]; + this.enet_dstaddr = new byte[6]; + this.enet_srcaddr = new byte[6]; this.enet_type[0] = (byte) 0x08; // 0x08?? - this.enet_type[1] = (byte) 0x06; // 0x0806 + this.enet_type[1] = (byte) 0x00; //일단은 IP this.enet_data = null; } + public void set_type(byte type) { + this.enet_type = new byte[]{0x08, type}; + } + public void set_dst(byte[] dstMac) { + for(int i = 0 ; i < 6 ; i++){ + this.enet_dstaddr[i] = dstMac[i]; + } + } + + public void set_src(byte[] srcMac) { + for(int i = 0 ; i < 6 ; i++){ + this.enet_srcaddr[i] = srcMac[i]; + } + } + public byte[] get_dst(){ + return this.enet_dstaddr; + } + public byte[] get_src(){ + return this.enet_srcaddr; + } + } _ETHERNET_HEADER m_sHeader = new _ETHERNET_HEADER(); + + public void set_type(byte type){ // 타입저장 - m_sHeader.enet_data[1] = (byte)type; + this.m_sHeader.set_type(type); } public void set_dstaddr(byte[] dst){ // 목적지 저장 //m_sHeader.enet_dstaddr.addr = dst; - for(int i = 0 ; i < 6 ; i++){ - m_sHeader.enet_dstaddr.addr[i] = dst[i]; - } + this.m_sHeader.set_dst(dst); } public void set_srcaddr(byte[] src){ // 주소 저장 - for(int i = 0; i < 6 ; i++) { - m_sHeader.enet_srcaddr.addr[i] = src[i]; - } + this.m_sHeader.set_src(src); //m_sHeader.enet_srcaddr.addr = src; } public byte[] get_dst(){ //dst return - return m_sHeader.enet_dstaddr.addr; + return this.m_sHeader.get_dst(); } public byte[] get_src(){ //src return - return m_sHeader.enet_srcaddr.addr; + return this.m_sHeader.get_src(); } + public EthernetLayer(String pName) { // super(pName); // TODO Auto-generated constructor stub pLayerName = pName; - } public byte[] ObjToByte(_ETHERNET_HEADER Header, byte[] input, int length) { byte[] buf = new byte[length + 14]; for (int i = 0; i < 6; i++) { - buf[i] = Header.enet_dstaddr.addr[i]; - buf[i + 6] = Header.enet_srcaddr.addr[i]; + buf[i] = Header.enet_dstaddr[i]; + buf[i + 6] = Header.enet_srcaddr[i]; } buf[12] = Header.enet_type[0]; buf[13] = Header.enet_type[1]; @@ -86,28 +93,11 @@ public byte[] ObjToByte(_ETHERNET_HEADER Header, byte[] input, int length) { } public boolean Send(byte[] input, int length) { - byte[] sender = m_sHeader.enet_srcaddr.addr; - System.out.println("Sender 주소 : "); - for(int i = 0; i p_aUpperLayer = new ArrayList(); + public IPLayer otherIP; + public RoutingTable RT_Table; + + public void setRT_Table(RoutingTable RT_Table) { + this.RT_Table = RT_Table; + } - private class _IP_ADDR { - private byte[] addr = new byte[4]; - - public _IP_ADDR() { - this.addr[0] = (byte) 0x00; - this.addr[1] = (byte) 0x00; - this.addr[2] = (byte) 0x00; - this.addr[3] = (byte) 0x00; - } - - public _IP_ADDR(byte[] ipAddress) { - this.addr[0] = ipAddress[0]; - this.addr[1] = ipAddress[1]; - this.addr[2] = ipAddress[2]; - this.addr[3] = ipAddress[3]; - } + public void setOtherIP(IPLayer ip) { + this.otherIP = ip; } class _IP_HEADER { @@ -33,47 +26,63 @@ class _IP_HEADER { byte ip_ttl; // time to live in gateway hops (1byte) byte ip_proto; // IP protocol (1byte) byte[] ip_cksum; // header checksum (2byte) - _IP_ADDR ip_src; // IP address of source (4byte) - _IP_ADDR ip_dst; // IP address of destination (4byte) + byte[] ip_src; // IP address of source (4byte) + byte[] ip_dst; // IP address of destination (4byte) byte[] ip_data; // variable length data public _IP_HEADER() { - this.ip_src = new _IP_ADDR(); - this.ip_dst = new _IP_ADDR(); - this.ip_verlen = (byte) 4; - this.ip_tos = (byte)0x00; + this.ip_src = new byte[4]; + this.ip_dst = new byte[4]; + this.ip_verlen = (byte)4; + this.ip_tos = (byte)0; this.ip_len = new byte[2]; this.ip_id = new byte[2]; this.ip_fragoff = new byte[2]; - this.ip_ttl = (byte)0x00; - this.ip_proto = (byte)0x00; + this.ip_ttl = (byte)64; + this.ip_proto = (byte)0; this.ip_cksum = new byte[2]; } - - public _IP_ADDR getIp_src() { + public byte[] getIp_src() { return ip_src; } - public void setIp_src(byte[] ip_src) { - this.ip_src = new _IP_ADDR(ip_src); + this.ip_src = ip_src; } - - public _IP_ADDR getIp_dst() { + public byte[] getIp_dst() { return ip_dst; } - public void setIp_dst(byte[] ip_dst) { - this.ip_dst = new _IP_ADDR(ip_dst); + this.ip_dst = ip_dst; } } _IP_HEADER m_sHeader = new _IP_HEADER(); + + public void set_srcIP(byte[] src){ + this.m_sHeader.setIp_src(src); + } + + public void set_dstIP(byte[] dst){ + this.m_sHeader.setIp_dst(dst); + } + + public byte[] get_srcIP(){ + return this.m_sHeader.getIp_src(); + } + public byte[] get_dstIP(){ + return this.m_sHeader.getIp_dst(); + } + + public void setLength(int length){ + m_sHeader.ip_len[0] = (byte) (length >> 8); + m_sHeader.ip_len[1] = (byte) (length); + } public IPLayer(String pName) { // super(pName); @@ -82,28 +91,81 @@ public IPLayer(String pName) { } - // IP Layer는 ARP와는 단방향 연결이고 ETHERNET과는 양방향 연결입니다. + + + // 이번 과제에서는 무조건 IP -> ARP로 갑니다. public boolean Send(byte[] input, int length) { - // Header 부분에서 설정할 것이 있지만 일단은 생략하는 것으로 하겠습니다. byte[] output = ObjToByte(m_sHeader, input, length); + return ((ARPLayer)this.GetUnderLayer()).Send(output, output.length); + } + + public boolean Send(byte[] input, int length, byte[] dstIPAddr){ + ((ARPLayer)this.GetUnderLayer()).setDstIP(dstIPAddr); + return((ARPLayer)this.GetUnderLayer()).Send(input, input.length, dstIPAddr); - // 연결 여부 확인을 위한 UnderLayer의 이름 출력 - System.out.println(this.GetUnderLayer().GetLayerName()); - ((ARPLayer)this.GetUnderLayer()).Send(input, length); - - - return false; } - + public boolean Receive(byte[] input) { + byte[] msgSrcIP = Arrays.copyOfRange(input, 12, 16); + byte[] msgDstIP = Arrays.copyOfRange(input, 16, 20); + //라우터가 목적지인 경우 + if(Arrays.equals(msgDstIP, m_sHeader.getIp_src())) { + m_sHeader.setIp_dst(msgSrcIP); + byte[] reply = RemoveIPHeader(input, input.length); + if(reply[0] == (byte)0x08){ + reply[0] = (byte)0x00; //reply는 0 request는 8 + reply = ObjToByte(m_sHeader, reply, reply.length); + return ((ARPLayer)this.GetUnderLayer()).Send(reply, reply.length, msgSrcIP); + } + } + + RoutingTable._ROUTING_ENTRY_ entry = RT_Table.routing(msgDstIP); + if (entry == null) + return false; + + // 라우터 엔트리의 정보 + int interNum = Integer.parseInt(entry.getRT_INTERFACE().split(" ")[1]); + String flag = entry.getRT_FLAG(); + byte[] gateway = entry.getRT_GATEWAY(); + + + // 현재 인터페이스 정보 + int thisInter = (int)this.m_sHeader.getIp_src()[2]; + // 현재 네트워크 인터페이스 내의 전송 + if(thisInter == interNum){ + if(flag.equals("U")) { + // 연결되어있으니까 거기로 보낸다 + ((ARPLayer)this.GetUnderLayer()).Send(input, input.length, msgDstIP); + }else if(flag.equals("UG")){ + //Gateway주소로의 전송 + ((ARPLayer)this.GetUnderLayer()).GetUnderLayer().Send(input, input.length); + } + } + // 다른 네트워크로의 전송 + else { + if(flag.equals("U")) { + otherIP.Send(input, input.length, msgDstIP); + }else if(flag.equals("UG")){ + //Gateway주소로의 전송 + otherIP.Send(input, input.length, gateway); + } + } return true; + + } + public byte[] RemoveIPHeader(byte[] input, int length) { + byte[] data = new byte[length - 20]; + System.arraycopy(input, 20, data, 0, data.length); + return data; } public byte[] ObjToByte(_IP_HEADER header, byte[] input, int length) { byte[] buf = new byte[length + 20]; + // length setting + setLength(input.length + 20); buf[0] = header.ip_verlen; buf[1] = header.ip_tos; buf[2] = header.ip_len[0]; @@ -116,8 +178,8 @@ public byte[] ObjToByte(_IP_HEADER header, byte[] input, int length) { buf[9] = header.ip_proto; buf[10] = header.ip_cksum[0]; buf[11] = header.ip_cksum[1]; - System.arraycopy(header.ip_src.addr, 0, buf, 12, 4); - System.arraycopy(header.ip_dst.addr, 0, buf, 16, 4); + System.arraycopy(header.ip_src, 0, buf, 12, 4); + System.arraycopy(header.ip_dst, 0, buf, 16, 4); for(int i = 0; i < length ; i++) { buf[i + 19] = input[i]; } diff --git a/Router/RouterDlg.java b/Router/RouterDlg.java index 48fbf75..b158289 100644 --- a/Router/RouterDlg.java +++ b/Router/RouterDlg.java @@ -35,26 +35,117 @@ public class RouterDlg extends JFrame implements BaseLayer{ public BaseLayer p_UnderLayer = null; public ArrayList p_aUpperLayer = new ArrayList(); public ArrayList m_pAdapterList; + public DefaultTableModel StaticRouterModel, ARPCacheModel, ProxyARPModel; private static LayerManager m_LayerMgr = new LayerManager(); public static RoutingTable routingTable; + public static ARPTable arpTable; + + public static NILayer[] niLayers = new NILayer[2]; + public static EthernetLayer[] ethLayers = new EthernetLayer[2]; + public static ARPLayer[] arpLayers = new ARPLayer[2]; + public static IPLayer[] ipLayers = new IPLayer[2]; public static void main(String[] args) { - /* - * TODO: - * - Layer 생성 - * - Layer 연결 - */ - RouterDlg layer = new RouterDlg("GUI"); + + // Table 설정 routingTable = new RoutingTable(); + arpTable = new ARPTable(); + // Layer 생성 + m_LayerMgr.AddLayer(new NILayer("NI1")); + m_LayerMgr.AddLayer(new EthernetLayer("ETHERNET1")); + m_LayerMgr.AddLayer(new IPLayer("IP1")); + m_LayerMgr.AddLayer(new ARPLayer("ARP1")); + + m_LayerMgr.AddLayer(new NILayer("NI2")); + m_LayerMgr.AddLayer(new EthernetLayer("ETHERNET2")); + m_LayerMgr.AddLayer(new IPLayer("IP2")); + m_LayerMgr.AddLayer(new ARPLayer("ARP2")); + + //GUI Layer 생성 + m_LayerMgr.AddLayer(new RouterDlg("GUI")); + + // Layer 연결 시작 IP랑 Ethernet 단방향, IP랑 ARP 단방향 + m_LayerMgr.ConnectLayers(" NI1 ( *ETHERNET1 ( +IP1 ( *GUI ) ) )"); + m_LayerMgr.GetLayer("IP1").SetUnderLayer((ARPLayer)m_LayerMgr.GetLayer("ARP1")); + m_LayerMgr.GetLayer("ETHERNET1").SetUpperUnderLayer((ARPLayer)m_LayerMgr.GetLayer("ARP1")); + + m_LayerMgr.GetLayer("NI2").SetUpperUnderLayer((EthernetLayer)m_LayerMgr.GetLayer("ETHERNET2")); + m_LayerMgr.GetLayer("ETHERNET2").SetUpperLayer((IPLayer)m_LayerMgr.GetLayer("IP2")); + m_LayerMgr.GetLayer("IP2").SetUpperUnderLayer((RouterDlg)m_LayerMgr.GetLayer("GUI")); + m_LayerMgr.GetLayer("IP2").SetUnderLayer((ARPLayer)m_LayerMgr.GetLayer("ARP2")); + m_LayerMgr.GetLayer("ETHERNET2").SetUpperUnderLayer((ARPLayer)m_LayerMgr.GetLayer("ARP2")); + // Layer 연결 끝 + + //IPLayer 설정 + ((IPLayer)m_LayerMgr.GetLayer("IP1")).setOtherIP(((IPLayer)m_LayerMgr.GetLayer("IP2"))); + ((IPLayer)m_LayerMgr.GetLayer("IP2")).setOtherIP(((IPLayer)m_LayerMgr.GetLayer("IP1"))); + ((IPLayer)m_LayerMgr.GetLayer("IP1")).setRT_Table(routingTable); + ((IPLayer)m_LayerMgr.GetLayer("IP2")).setRT_Table(routingTable); + + // ARPLayer 설정 + ((ARPLayer)m_LayerMgr.GetLayer("ARP1")).SetGUI((RouterDlg)m_LayerMgr.GetLayer("GUI")); + ((ARPLayer)m_LayerMgr.GetLayer("ARP2")).SetGUI((RouterDlg)m_LayerMgr.GetLayer("GUI")); + ((ARPLayer)m_LayerMgr.GetLayer("ARP1")).setARPTable(arpTable); + ((ARPLayer)m_LayerMgr.GetLayer("ARP2")).setARPTable(arpTable); + ((ARPLayer)m_LayerMgr.GetLayer("ARP1")).setInterfaceNum(1); + ((ARPLayer)m_LayerMgr.GetLayer("ARP2")).setInterfaceNum(2); + // NILayer Setting + ((NILayer)m_LayerMgr.GetLayer("NI1")).SetAdapterNumber(0); + ((NILayer)m_LayerMgr.GetLayer("NI2")).SetAdapterNumber(1); + + // 각 Layer들 Address Setting(src) + //1.Ethernet 정보 + + try { + ((EthernetLayer)m_LayerMgr.GetLayer("ETHERNET1")).set_srcaddr((((NILayer)m_LayerMgr.GetLayer("NI1")).m_pAdapterList.get(0).getHardwareAddress())); + System.out.println("Network interface0 Info:\n" + (((NILayer)m_LayerMgr.GetLayer("NI1")).m_pAdapterList.get(0).toString())); + ((EthernetLayer)m_LayerMgr.GetLayer("ETHERNET2")).set_srcaddr((((NILayer)m_LayerMgr.GetLayer("NI2")).m_pAdapterList.get(1).getHardwareAddress())); + System.out.println("Network interface1 Info:\n" + (((NILayer)m_LayerMgr.GetLayer("NI2")).m_pAdapterList.get(1).toString())); + System.out.println("MAC1 ADDRESS : " + macToString((((NILayer)m_LayerMgr.GetLayer("NI1")).m_pAdapterList.get(0).getHardwareAddress()))); + System.out.println("MAC2 ADDRESS : " + macToString((((NILayer)m_LayerMgr.GetLayer("NI2")).m_pAdapterList.get(1).getHardwareAddress()))); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // 2. IPLayer 정보 + ((IPLayer)m_LayerMgr.GetLayer("IP1")).set_srcIP((((NILayer)m_LayerMgr.GetLayer("NI1")).m_pAdapterList.get(0).getAddresses().get(0).getAddr().getData())); + ((IPLayer)m_LayerMgr.GetLayer("IP2")).set_srcIP((((NILayer)m_LayerMgr.GetLayer("NI2")).m_pAdapterList.get(1).getAddresses().get(0).getAddr().getData())); + // 3. ARPLayer 정보 + try { + ((ARPLayer)m_LayerMgr.GetLayer("ARP1")).setSrcIP(((NILayer)m_LayerMgr.GetLayer("NI1")).m_pAdapterList.get(0).getAddresses().get(0).getAddr().getData()); + ((ARPLayer)m_LayerMgr.GetLayer("ARP1")).setSrcMac(((NILayer)m_LayerMgr.GetLayer("NI1")).m_pAdapterList.get(0).getHardwareAddress()); + ((ARPLayer)m_LayerMgr.GetLayer("ARP2")).setSrcIP(((NILayer)m_LayerMgr.GetLayer("NI2")).m_pAdapterList.get(1).getAddresses().get(0).getAddr().getData()); + ((ARPLayer)m_LayerMgr.GetLayer("ARP2")).setSrcMac(((NILayer)m_LayerMgr.GetLayer("NI2")).m_pAdapterList.get(1).getHardwareAddress()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // 입력하는 시간 필요 + Scanner sc = new Scanner(System.in); + System.out.print("Routing Rable 입력을 마쳤다면 end를 입력해주세요 : "); + while(true){ + // Routing Program 실행시 GARP사용하여 LAN의 Host들에게 자기 자신을 알려야함 + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(sc.next().equals("end")){ + break; + } + } + byte[] garp = new byte[1]; + ((ARPLayer)m_LayerMgr.GetLayer("ARP1")).GARPSend(garp); + ((ARPLayer)m_LayerMgr.GetLayer("ARP2")).GARPSend(garp); } private JPanel contentPanel; // 전체 화면 JPanel - private JButton btnAllDelete; // Basic ARP All ITem Delete Button - private JTable StaticRouterTable; - private JTable ARPCacheTable; - private JTable ProxyARPTable; + public JTable StaticRouterTable; + public JTable ARPCacheTable; + public JTable ProxyARPTable; private JPanel StaticRouterPane; private JPanel ARPCachePane; private JPanel ProxyPane; @@ -71,7 +162,8 @@ public static void main(String[] args) { private JButton btnProxyDelete; private JDialog addRouterDlg; private JDialog proxyAddDlg; - public DefaultTableModel StaticRouterModel, ARPCacheModel, ProxyARPModel; + + @@ -88,6 +180,10 @@ public RouterDlg(String pName) { getContentPane().add(contentPanel, BorderLayout.CENTER); contentPanel.setLayout(null); + /* + * Static Routing Table 시작 + */ + StaticRouterPane = new JPanel(); StaticRouterPane.setBounds(14, 12, 615, 480); contentPanel.add(StaticRouterPane); @@ -104,15 +200,20 @@ public RouterDlg(String pName) { StaticRouterPane.add(RouterScrollPane); StaticRouterTable = new JTable(); + StaticRouterTable.setFont(new Font("Gulim", Font.PLAIN, 15)); + StaticRouterTable.setShowVerticalLines(false); + StaticRouterTable.setShowGrid(false); StaticRouterModel = new DefaultTableModel( new Object[][] { - {"123.123.123,123","123.123.123,123","123.123.123.123","UP","1","Host1"} }, new String[] { "Destination", "Netmask", "Gateway", "Flag", "Interface", "Metric" } ); StaticRouterTable.setModel(StaticRouterModel); + StaticRouterTable.getColumnModel().getColumn(0).setPreferredWidth(139); + StaticRouterTable.getColumnModel().getColumn(1).setPreferredWidth(133); + StaticRouterTable.getColumnModel().getColumn(2).setPreferredWidth(126); RouterScrollPane.setViewportView(StaticRouterTable); btnRouterAdd = new JButton("Add"); @@ -135,12 +236,17 @@ public void actionPerformed(ActionEvent e) { //remove selected row from the model StaticRouterModel.removeRow(selectedIndex); // TODO: Routing Table Class에서 해당 index 삭제하는 과정 + routingTable.deleteRoutingEntry(selectedIndex); } } }); btnRouterDelete.setBounds(345, 441, 105, 27); StaticRouterPane.add(btnRouterDelete); + /* + * Static Routing Table 끝 + */ + ARPCachePane = new JPanel(); ARPCachePane.setBounds(643, 12, 466, 252); contentPanel.add(ARPCachePane); @@ -168,6 +274,14 @@ public void actionPerformed(ActionEvent e) { ARPScrollPane.setViewportView(ARPCacheTable); btnARPDelete = new JButton("Delete"); + btnARPDelete.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int index = ARPCacheTable.getSelectedRow(); + if(index >= 0) { + DeleteARP(index); + } + } + }); btnARPDelete.setBounds(181, 221, 105, 27); ARPCachePane.add(btnARPDelete); @@ -210,10 +324,6 @@ public void actionPerformed(ActionEvent e) { btnProxyDelete = new JButton("Delete"); btnProxyDelete.setBounds(286, 182, 105, 27); ProxyPane.add(btnProxyDelete); - - - btnAllDelete = new JButton("All Detete"); - btnAllDelete.setBounds(196, 298, 127, 42); setVisible(true); @@ -294,61 +404,63 @@ public AddRouterDlg(JFrame frame, String title) { JButton btnAdd = new JButton("Add"); btnAdd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - byte[] dstIP = StringToByte(DestIP.getText()); - byte[] netmask = StringToByte(NetMaskIP.getText()); - byte[] gateway = StringToByte(GatewayIP.getText()); - String flag = getFlag(); - String inter = getInterface(); + byte[] dstIP = StringToIP(DestIP.getText()); + + byte[] netmask = StringToIP(NetMaskIP.getText()); + byte[] gateway = new byte[4]; + if(!GatewayIP.getText().isEmpty()){ + gateway = StringToIP(GatewayIP.getText()); + } + String gate = ""; + if(GatewayIP.getText().isEmpty()) gate = "*"; + else gate = GatewayIP.getText(); + String flag = getFlag(chckbxUp.isSelected(),chckbxGateway.isSelected(), chckbxHost.isSelected()); + int index = NICList.getSelectedIndex(); + String inter = "Interface " + (index+1); int metric = getMetric(); //routingTable 클래스에 Entry 추가 routingTable.addRoutingEntry(dstIP, netmask, gateway, flag, inter, metric); //TODO: GUI의 라우팅 테이블에 업데이트 + StaticRouterModel.addRow(new Object[]{DestIP.getText(),NetMaskIP.getText(), gate, flag, inter, Integer.toString(metric)}); + } }); btnAdd.setBounds(83, 271, 84, 27); AddRouterPane.add(btnAdd); JButton btnCancel = new JButton("Cancel"); + btnCancel.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); btnCancel.setBounds(208, 271, 84, 27); AddRouterPane.add(btnCancel); } - private String getInterface(){ - String output = "interface0"; - //TODO : Interface 설정 하는 과정 필요(NILayer) - - //TODO : Interface Name 반환 - return output; - } private int getMetric(){ int output = 1; - //TODO : Metric....반환.... + //TODO : Metric....반환....<미완료> return output; } - private String getFlag(){ + private String getFlag(boolean up, boolean gateway, boolean host){ String output = ""; - // TODO : Flag 확인해서 String으로 변환해서 return - - return output; - } - - private byte[] StringToByte(String input){ - byte[] output = new byte[4]; //IP 주소는 4byte - String[] tmp = input.split("\\."); - for(int i = 0 ; i < tmp.length; i++){ - output[i] = Int2Byte(Integer.parseInt(tmp[i])); + // TODO : Flag 확인해서 String으로 변환해서 return<완료> + if(up) { + output += "U"; + } + if(gateway){ + output += "G"; } + if(host){ + output += "H"; + } + return output; } - private byte Int2Byte(int src){ - byte result = 0; - // TODO : IP주소 숫자를 byte 배열에 넣기 위해서 바꾸는 과정이 필요함 - return result; - } - private void SetCombobox(JComboBox NICList) { java.util.List m_pAdapterList = new ArrayList(); StringBuilder errbuf = new StringBuilder(); @@ -359,7 +471,7 @@ private void SetCombobox(JComboBox NICList) { return; } for (int i = 0; i < m_pAdapterList.size(); i++) - NICList.addItem(m_pAdapterList.get(i).getDescription()); + NICList.addItem("Interface "+(i+1)); } @@ -422,14 +534,97 @@ public ProxyAddDlg() { } { JComboBox ProxyInterface = new JComboBox(); - ProxyInterface.setBounds(173, 144, 130, 24); + ProxyInterface.setBounds(173, 144, 194, 24); ProxyAddPanel.add(ProxyInterface); } } } + + public void ARPTableUpdate(byte[] IPAddr, byte[] MACAddr, boolean status, int interfaceNum){ + String strIP = ipToString(IPAddr); + String strMac = status ? macToString(MACAddr) : "???????????"; + String strStatus = status ? "Complete" : "Incomplete"; + String inter = "Interface " + interfaceNum; + // loop 돌면서 존재하는 지 확인 + boolean flag = false; + for(int i = 0; i < ARPCacheTable.getRowCount(); i++){ + // 존재한다면 + if(strIP.equals(ARPCacheModel.getValueAt(i, 0))){ + // 내용 업데이트 + ARPCacheModel.setValueAt(strMac, i, 1); + ARPCacheModel.setValueAt(inter, i, 2); + ARPCacheModel.setValueAt(strStatus, i, 3); + flag = true; + } + + } + // 존재하지 않는다면 + if(!flag) + ARPCacheModel.addRow(new Object[]{strIP,strMac,inter, strStatus}); + + } + + // DeleteARP + public boolean DeleteARP(int index){ + // ARP Layer에서 해당 index의 ARP Cache를 제거 + arpTable.ArpCacheTable.remove(index); + // GUI Update + ARPCacheModel.removeRow(index); + return true; + } + // byte[]의 IP주소를 String으로 반환(000.000.000.000)의 형태 + public static String ipToString(byte[] ipAddr) { + String ipStr = new String(); + for (int i = 0 ; i < 4; i++) { + // 중간에는 .으로 구분함 + if(i != 3) { + ipStr += (int)(ipAddr[i] & 0xFF); + ipStr += "."; + } + else { + ipStr += ipAddr[i] & 0xFF; + } + } + return ipStr; + } + // String의 IP주소를 byte[]로 변환 + public byte[] StringToIP(String ipAddr){ + byte[] buf = new byte[4]; + String[] temp = ipAddr.split("\\."); + for(int i = 0; i < 4; i++){ + buf[i] = (byte)Integer.parseInt(temp[i]); + } + + return buf; + } + + // byte[]의 MAC 주소를 String으로 변환(FF:FF:FF:FF:FF:FF)의 형태 + public static String macToString(byte[] macAddr) { + String macStr = ""; + for(int i = 0 ; i < 6; i++){ + macStr += String.format("%02X", macAddr[i] & 0xFF).toUpperCase(); + //macStr += Integer.toHexString(macAddr[i] & 0xFF).toUpperCase(); + if(i != 5) { + macStr += ":"; + } + } + return macStr; + } + // String MAC 주소를 byte[]로 변환 + public byte[] StringToMAC(String macAddr){ + byte[] buf = new byte[6]; + String[] temp = macAddr.split(":"); + for(int i = 0 ; i < 6 ; i++){ + int hex = Integer.parseUnsignedInt(temp[i], 16); + buf[i] = (byte)hex; + } + return buf; + } + + // Layer 관련 함수 @Override public void SetUnderLayer(BaseLayer pUnderLayer) { // TODO Auto-generated method stub diff --git a/Router/RoutingTable.java b/Router/RoutingTable.java index 3e339a6..8f87fb6 100644 --- a/Router/RoutingTable.java +++ b/Router/RoutingTable.java @@ -1,10 +1,14 @@ import java.util.ArrayList; +import java.util.Arrays; public class RoutingTable { public ArrayList<_ROUTING_ENTRY_> routingTable = new ArrayList<>(); + public IPLayer[] ipArr = new IPLayer[2]; + public RouterDlg GUI; + class _ROUTING_ENTRY_{ private byte[] RT_DEST_IP; // Routing Table destination IP Address @@ -26,12 +30,12 @@ public _ROUTING_ENTRY_(){ public void setRoutingEntry(byte[] dstIP, byte[] netmask, byte[] gateway, String flag, String inter, int metric) { - System.arraycopy(dstIP, 0, RT_DEST_IP, 0, 4); - System.arraycopy(netmask, 0, RT_NETMASK, 0, 4); - System.arraycopy(gateway, 0, RT_GATEWAY, 0, 4); - RT_FLAG = flag; - RT_INTERFACE = inter; - RT_METRIC = metric; + this.RT_DEST_IP = dstIP; + this.RT_NETMASK = netmask; + this.RT_GATEWAY = gateway; + this.RT_FLAG = flag; + this.RT_INTERFACE = inter; + this.RT_METRIC = metric; } @@ -60,6 +64,15 @@ public int getRT_METRIC() { } } + public void setGUI(RouterDlg DlgLayer){ + this.GUI = DlgLayer; + } + + public void setIPLayer(IPLayer layer1, IPLayer layer2) { + this.ipArr[0] = layer1; + this.ipArr[1] = layer2; + } + // Routing Table에 Entry를 추가하는 함수 public void addRoutingEntry(byte[] dstIP, byte[] netmask, byte[] gateway, String flag, String inter, int metric){ _ROUTING_ENTRY_ entry = new _ROUTING_ENTRY_(); //Entry 생성 @@ -70,19 +83,53 @@ public void addRoutingEntry(byte[] dstIP, byte[] netmask, byte[] gateway, String // index를 이용하여 Table에서 Entry찾아서 삭제 public boolean deleteRoutingEntry(int index){ // Table 범위 안에 들어가는 경우 - if(index >= 0 && index < routingTable.size()-1){ + if(index >= 0 && index < routingTable.size()){ routingTable.remove(index); return true; } return false; } - // TODO: Routing Table에서 Masking하는 함수 - // TODO: Routing Table에 있는지 확인하는 함수 - + public _ROUTING_ENTRY_ findMatchingEntry(byte[] dstIP) { + for (int i = 0; i < routingTable.size(); i++) { + // current entry object + _ROUTING_ENTRY_ currentEntry = routingTable.get(i); + + byte[] subnetMask = currentEntry.getRT_NETMASK(); + byte[] maskingResult = maskingDstIP(dstIP, subnetMask); + + // matching success + if (Arrays.equals(currentEntry.getRT_DEST_IP(), maskingResult)){ + return currentEntry; + } + } + return null; + } + // masking dstIP for subnetMask + public byte[] maskingDstIP(byte[] dstIP, byte[] subnetMask) { + byte[] maskingResult = new byte[4]; + for (int i = 0; i < dstIP.length; i++) { + maskingResult[i] = (byte) (dstIP[i] & subnetMask[i]); + } + + return maskingResult; + } + // Routing 과정 : input -> 올라온 메세지 + public _ROUTING_ENTRY_ routing(byte[] dstIP){ + // 원래의 목적지 IP 주소 + byte[] originDstIP = dstIP; + // 지금 보내야 하는 IP 주소 + byte[] nowDstIP = Arrays.copyOf(originDstIP, 4); // ARP Cache Table에서 찾아야 하는 주소 + // Matching 되는 IP 주소 보냄 + return findMatchingEntry(originDstIP); + + // IPLayer에서 받아서 ip가지고 RouterLayer로 내려보낸다. + + } + } diff --git a/Router/TCPLayer.java b/Router/TCPLayer.java deleted file mode 100644 index 1b8c996..0000000 --- a/Router/TCPLayer.java +++ /dev/null @@ -1,153 +0,0 @@ -import java.util.ArrayList; - -public class TCPLayer implements BaseLayer { - public int nUpperLayerCount = 0; - public String pLayerName = null; - public BaseLayer p_UnderLayer = null; - public ArrayList p_aUpperLayer = new ArrayList(); -/* -typedef struct _TCPLayer_HEADER { -unsigned short tcp_sport; // source port (2byte) -unsigned short tcp_dport;// destination port (2byte) -unsigned int tcp_seq; // sequence number (4byte) -unsigned int tcp_ack; // acknowledged sequence (4byte) -unsigned char tcp_offset; // no use (1byte) -unsigned char tcp_flag; // control flag (1byte) -unsigned short tcp_window; // no use (2byte) -unsigned short tcp_cksum; // check sum (2byte) -unsigned short tcp_urgptr; // no use (2byte) -unsigned char Padding[4]; //(4byte) -unsigned char tcp_data[ TCP_DATA_SIZE ]; // data part -}TCPLayer_HEADER, *LPTCPLayer_HEADER ; -*/ - private class _TCP_ADDR { - private byte[] addr = new byte[2]; - - public _TCP_ADDR () { - this.addr[0] = (byte) 0x00; - this.addr[1] = (byte) 0x00; - } - } - - private class _TCP_HEADER { - _TCP_ADDR tcp_sport; // source port (2byte) - _TCP_ADDR tcp_dport;// destination port (2byte) - byte[] tcp_seq; // sequence number (4byte) - byte[] tcp_ack; // acknowledged sequence (4byte) - byte tcp_offset; // no use (1byte) - byte tcp_flag; // control flag (1byte) - byte[] tcp_window; // no use (2byte) - byte[] tcp_cksum; // check sum (2byte) - byte[] tcp_urgptr; // no use (2byte) - byte[] Padding; //(4byte) - byte[] tcp_data; // data part - - public _TCP_HEADER() { - this.tcp_dport = new _TCP_ADDR(); - this.tcp_sport = new _TCP_ADDR(); - this.tcp_seq = new byte[4]; - this.tcp_ack = new byte[4]; - this.tcp_offset = (byte) 0x00; - this.tcp_flag = (byte) 0x00; - this.tcp_window = new byte[2]; - this.tcp_cksum = new byte[2]; - this.tcp_urgptr = new byte[2]; - this.Padding = new byte[4]; - - } - } - - _TCP_HEADER m_sHeader = new _TCP_HEADER(); - - public TCPLayer(String pName) { - // super(pName); - // TODO Auto-generated constructor stub - pLayerName = pName; - - } - - // Header를 Byte화 해서 하위 Layer로 전달한다(IP Layer) - public boolean Send(byte[] input, int length) { - // TCP Layer의 경우 지나가기만 하지 정해진 규칙(port 번호 등)이 없으므로 그냥 default 0으 값이 채워진 HEADER전달합니다. - // 현재는 ARP만 구현되어 있으므로 tcp_flag도 따로 설정하지 않겠습니다. - byte[] output = ObjToByte(m_sHeader, input, length); - // 하위 Layer인 IP Layer로 전달함. - ((IPLayer)this.GetUnderLayer()).Send(output, output.length); - - - return false; - } - - - - public boolean Receive(byte[] input) { - // ARP만 구현해서 이 부분은 구현하지 않았습니다. - return true; - } - - public byte[] ObjToByte(_TCP_HEADER header, byte[] input, int length) { - byte[] buf = new byte[24 + length]; - //TO-DO : 객체 -> byte 바꾸는 배열 필요 - buf[0] = header.tcp_sport.addr[0]; - buf[1] = header.tcp_sport.addr[1]; - buf[2] = header.tcp_dport.addr[0]; - buf[3] = header.tcp_dport.addr[1]; - System.arraycopy(header.tcp_seq, 0, buf, 4, 4); - System.arraycopy(header.tcp_ack, 0, buf, 8, 4); - buf[12] = header.tcp_offset; - buf[13] = header.tcp_flag; - buf[14] = header.tcp_window[0]; - buf[15] = header.tcp_window[1]; - buf[16] = header.tcp_cksum[0]; - buf[17] = header.tcp_cksum[1]; - buf[18] = header.tcp_urgptr[0]; - buf[19] = header.tcp_urgptr[1]; - System.arraycopy(header.Padding, 0, buf, 20, 4); - for(int i = 0; i < length ; i++) { - buf[23 + i] = input[i]; - } - - return buf; - } - - @Override - public void SetUnderLayer(BaseLayer pUnderLayer) { - if (pUnderLayer == null) - return; - this.p_UnderLayer = pUnderLayer; - } - - @Override - public void SetUpperLayer(BaseLayer pUpperLayer) { - if (pUpperLayer == null) - return; - this.p_aUpperLayer.add(nUpperLayerCount++, pUpperLayer); - } - - @Override - public String GetLayerName() { - // TODO Auto-generated method stub - return pLayerName; - } - - @Override - public BaseLayer GetUnderLayer() { - if (p_UnderLayer == null) - return null; - return p_UnderLayer; - } - - @Override - public BaseLayer GetUpperLayer(int nindex) { - if (nindex < 0 || nindex > nUpperLayerCount || nUpperLayerCount < 0) - return null; - return p_aUpperLayer.get(nindex); - } - - @Override - public void SetUpperUnderLayer(BaseLayer pUULayer) { - this.SetUpperLayer(pUULayer); - pUULayer.SetUnderLayer(this); - } - -}