|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2004 Andras Varga 00003 // Copyright (C) 2005 Christian Dankbar, Irene Ruengeler, Michael Tuexen 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 // This file is based on the PPP.cc of INET written by Andras Varga. 00020 00021 #define WANT_WINSOCK2 00022 00023 #include <platdep/sockets.h> 00024 #include <stdio.h> 00025 #include <string.h> 00026 #include <omnetpp.h> 00027 #include "InterfaceTable.h" 00028 #include "InterfaceTableAccess.h" 00029 #include "ExtInterface.h" 00030 #include "IPSerializer.h" 00031 00032 00033 Define_Module(ExtInterface); 00034 00035 void ExtInterface::initialize(int stage) 00036 { 00037 // subscribe at scheduler for external messages 00038 if(stage == 0) 00039 { 00040 if(dynamic_cast<cSocketRTScheduler *>(simulation.getScheduler()) != NULL) 00041 { 00042 rtScheduler = check_and_cast<cSocketRTScheduler *>(simulation.getScheduler()); 00043 //device = ev.config()->getAsString("Capture", "device", "lo0"); 00044 device = par("device"); 00045 //const char *filter = ev.config()->getAsString("Capture", "filter-string", "ip"); 00046 const char *filter = par("filterString"); 00047 rtScheduler->setInterfaceModule(this, device, filter); 00048 connected = true; 00049 } 00050 else 00051 { 00052 // this simulation run works without external interface.. 00053 connected = false; 00054 } 00055 } 00056 00057 if (stage == 3) 00058 { 00059 // update display string when addresses have been autoconfigured etc. 00060 updateDisplayString(); 00061 return; 00062 } 00063 00064 // all initialization is done in the first stage 00065 if (stage != 0) 00066 return; 00067 00068 numSent = numRcvd = numDropped = 0; 00069 WATCH(numSent); 00070 WATCH(numRcvd); 00071 WATCH(numDropped); 00072 00073 // register our interface entry in RoutingTable 00074 interfaceEntry = registerInterface(); 00075 00076 // if not connected, make it gray 00077 if (ev.isGUI() && !connected) 00078 { 00079 getDisplayString().setTagArg("i",1,"#707070"); 00080 getDisplayString().setTagArg("i",2,"100"); 00081 } 00082 } 00083 00084 InterfaceEntry *ExtInterface::registerInterface() 00085 { 00086 InterfaceEntry *e = new InterfaceEntry(); 00087 00088 // interface name: our module name without special characters ([]) 00089 char *interfaceName = new char[strlen(getFullName())+1]; 00090 char *d=interfaceName; 00091 for (const char *s=getFullName(); *s; s++) 00092 if (isalnum(*s)) 00093 *d++ = *s; 00094 *d = '\0'; 00095 e->setName(interfaceName); 00096 delete [] interfaceName; 00097 00098 e->setMtu(par("mtu")); 00099 e->setMulticast(true); 00100 e->setPointToPoint(true); 00101 IInterfaceTable *ift = InterfaceTableAccess().get(); 00102 ift->addInterface(e, this); 00103 return e; 00104 } 00105 00106 void ExtInterface::handleMessage(cMessage *msg) 00107 { 00108 00109 if(dynamic_cast<ExtFrame *>(msg) != NULL) 00110 { 00111 // incoming real packet from wire (captured by pcap) 00112 uint32 packetLength; 00113 ExtFrame *rawPacket = check_and_cast<ExtFrame *>(msg); 00114 00115 packetLength = rawPacket->getDataArraySize(); 00116 for(uint32 i=0; i < packetLength; i++) 00117 buffer[i] = rawPacket->getData(i); 00118 00119 IPDatagram *ipPacket = new IPDatagram("ip-from-wire"); 00120 IPSerializer().parse(buffer, packetLength, (IPDatagram *)ipPacket); 00121 EV << "Delivering an IP packet from " 00122 << ipPacket->getSrcAddress() 00123 << " to " 00124 << ipPacket->getDestAddress() 00125 << " and length of" 00126 << ipPacket->getByteLength() 00127 << " bytes to IP layer.\n"; 00128 send(ipPacket, "netwOut"); 00129 numRcvd++; 00130 } 00131 else 00132 { 00133 memset(buffer, 0, 1<<16); 00134 IPDatagram *ipPacket = check_and_cast<IPDatagram *>(msg); 00135 00136 if ((ipPacket->getTransportProtocol() != IP_PROT_ICMP) && 00137 (ipPacket->getTransportProtocol() != IPPROTO_SCTP) && 00138 (ipPacket->getTransportProtocol() != IPPROTO_TCP) && 00139 (ipPacket->getTransportProtocol() != IPPROTO_UDP)) 00140 { 00141 EV << "Can not send packet. Protocol " << ipPacket->getTransportProtocol() << " is not supported.\n"; 00142 numDropped++; 00143 delete(msg); 00144 return; 00145 } 00146 00147 if(connected) 00148 { 00149 struct sockaddr_in addr; 00150 addr.sin_family = AF_INET; 00151 #if !defined(linux) && !defined(_WIN32) 00152 addr.sin_len = sizeof(struct sockaddr_in); 00153 #endif 00154 addr.sin_port = 0; 00155 addr.sin_addr.s_addr = htonl(ipPacket->getDestAddress().getInt()); 00156 int32 packetLength = IPSerializer().serialize(ipPacket,buffer, sizeof(buffer)); 00157 EV << "Delivering an IP packet from " 00158 << ipPacket->getSrcAddress() 00159 << " to " 00160 << ipPacket->getDestAddress() 00161 << " and length of " 00162 << ipPacket->getByteLength() 00163 << " bytes to link layer.\n"; 00164 rtScheduler->sendBytes(buffer, packetLength, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); 00165 numSent++; 00166 } 00167 else 00168 { 00169 EV << "Interface is not connected, dropping packet " << msg << endl; 00170 numDropped++; 00171 } 00172 } 00173 delete(msg); 00174 if (ev.isGUI()) 00175 updateDisplayString(); 00176 } 00177 00178 void ExtInterface::displayBusy() 00179 { 00180 getDisplayString().setTagArg("i",1, "yellow"); 00181 gate("physOut")->getDisplayString().setTagArg("ls",0,"yellow"); 00182 gate("physOut")->getDisplayString().setTagArg("ls",1,"3"); 00183 } 00184 00185 void ExtInterface::displayIdle() 00186 { 00187 getDisplayString().setTagArg("i",1,""); 00188 gate("physOut")->getDisplayString().setTagArg("ls",0,"black"); 00189 gate("physOut")->getDisplayString().setTagArg("ls",1,"1"); 00190 } 00191 00192 void ExtInterface::updateDisplayString() 00193 { 00194 char buf[80]; 00195 if (ev.disable_tracing) 00196 getDisplayString().setTagArg("t",0,""); 00197 if(connected) 00198 sprintf(buf, "pcap device: %s\nrcv:%d snt:%d", device, numRcvd, numSent); 00199 else 00200 sprintf(buf, "not connected"); 00201 getDisplayString().setTagArg("t", 0, buf); 00202 } 00203 00204 void ExtInterface::finish() 00205 { 00206 std::cout << getFullPath() << ": " << numSent << " packets sent, " << 00207 numRcvd << " packets received, " << numDropped <<" packets dropped.\n"; 00208 } 00209