/* ** This file is part of Filius, a network construction and simulation software. ** ** Originally created at the University of Siegen, Institute "Didactics of ** Informatics and E-Learning" by a students' project group: ** members (2006-2007): ** André Asschoff, Johannes Bade, Carsten Dittich, Thomas Gerding, ** Nadja Haßler, Ernst Johannes Klebert, Michell Weyer ** supervisors: ** Stefan Freischlad (maintainer until 2009), Peer Stechert ** Project is maintained since 2010 by Christian Eibl <filius@c.fameibl.de> ** and Stefan Freischlad ** Filius is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 2 of the License, or ** (at your option) version 3. ** ** Filius is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Filius. If not, see <http://www.gnu.org/licenses/>. */ package filius.software.netzzugangsschicht; import java.util.ListIterator; import filius.Main; import filius.hardware.Port; import filius.hardware.knoten.Switch; import filius.software.ProtokollThread; import filius.software.system.SwitchFirmware; /** * Der Switch-Portbeobachter dient dazu, eingehende Frames an einem * Switch-Anschluss abzuholen und an den richtigen Anschluss weiterzuleiten. */ public class SwitchPortBeobachter extends ProtokollThread { /** Die Switch-Firmware */ private SwitchFirmware switchFirmware; /** Der Switch-Anschluss, der ueberwacht wird */ private Port anschluss; // private boolean threadRunning = false; /** * Der Konstruktor initialisiert den Eingangspuffer durch Aufruf des * Konstruktors der Oberklasse und initialisert die Switch-Firmware und den * zu ueberwachenden Anschluss. */ public SwitchPortBeobachter(SwitchFirmware switchFirmware, Port anschluss) { super(anschluss.holeEingangsPuffer()); Main.debug.println("INVOKED-2 ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (SwitchPortBeobachter), constr: SwitchPortBeobachter("+switchFirmware+","+anschluss+")"); this.switchFirmware = switchFirmware; this.anschluss = anschluss; } /** * Methode zur Weiterleitung der Frames zu dem richtigen Anschluss des * Switch. * <ol> * <li> Dazu wird zunaechst geprueft, ob der Frame bereits weitergeleitet * wurde. Wenn es eine Wiederholung ist, die durch einen Zyklus im Netzwerk * entstanden sein kann, wird der Frame verworfen. </li> * <li> Dann wird der Frame zu der von der Firmware verwalteten Liste der * weitergeleiteten Frames hinzugefuegt. </li> * <li> Die SAT-Tabelle wird ergaenzt. </li> * <li> Der Frame wird an einen Anschluss weitergeleitet, wenn fuer die * Ziel-MAC-Adresse ein Eintrag in der SAT existiert. </li> * <li> Wenn kein SAT-Eintrag existiert wird der Frame als Broadcast an alle * Anschluesse des Switch weitergeleitet. </li> * </ol> */ public void verarbeiteDatenEinheit(Object datenEinheit) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (SwitchPortBeobachter), verarbeiteDatenEinheit("+datenEinheit.toString()+")"); EthernetFrame etp; ListIterator iter; Port zielAnschluss; Port aktiverAnschluss; etp = (EthernetFrame) datenEinheit; if (!switchFirmware.holeDurchgelaufeneFrames().contains(etp)) { switchFirmware.holeDurchgelaufeneFrames().add(etp); switchFirmware.hinzuSatEintrag(etp.getQuellMacAdresse(), anschluss); zielAnschluss = switchFirmware.holeAnschlussFuerMAC(etp .getZielMacAdresse()); if (zielAnschluss != null) { //Main.debug.println("SwitchPortBeobachter: Frame fuer " //+ etp.getZielMacAdresse() + " an Port " //+ zielAnschluss.toString()); synchronized (zielAnschluss.holeAusgangsPuffer()) { zielAnschluss.holeAusgangsPuffer().add(etp); zielAnschluss.holeAusgangsPuffer().notify(); } } else { // Broadcast // Main.debug.println("SwitchPortBeobachter: Broadcast wird weitergeleitet."); iter = ((Switch) switchFirmware.getKnoten()).getAnschluesse() .listIterator(); while (iter.hasNext()) { aktiverAnschluss = (Port) iter.next(); // Main.debug.println("\t an Anschluss " // + aktiverAnschluss.toString()); if (!aktiverAnschluss.isPortFrei() && (aktiverAnschluss != anschluss)) { synchronized (aktiverAnschluss.holeAusgangsPuffer()) { aktiverAnschluss.holeAusgangsPuffer().add(etp); aktiverAnschluss.holeAusgangsPuffer().notify(); } } } } } } }