![]() |
Multicast Routing Modelling In OMNeT++
|
00001 00009 #include <omnetpp.h> 00010 #include "AnsaIP.h" 00011 #include "PimSplitter.h" 00012 00013 Define_Module(AnsaIP); 00014 00015 00023 void AnsaIP::initialize(int stage) 00024 { 00025 INET_API IP::initialize(); 00026 00027 mrt = MulticastRoutingTableAccess().get(); 00028 nb = NotificationBoardAccess().get(); 00029 00030 } 00031 00044 void AnsaIP::handlePacketFromNetwork(IPDatagram *datagram) 00045 { 00046 // 00047 // "Prerouting" 00048 // 00049 00050 // check for header biterror 00051 if (datagram->hasBitError()) 00052 { 00053 // probability of bit error in header = size of header / size of total message 00054 // (ignore bit error if in payload) 00055 double relativeHeaderLength = datagram->getHeaderLength() / (double)datagram->getByteLength(); 00056 if (dblrand() <= relativeHeaderLength) 00057 { 00058 EV << "bit error found, sending ICMP_PARAMETER_PROBLEM\n"; 00059 icmpAccess.get()->sendErrorMessage(datagram, ICMP_PARAMETER_PROBLEM, 0); 00060 return; 00061 } 00062 } 00063 00064 // remove control info 00065 if (datagram->getTransportProtocol()!=IP_PROT_DSR && datagram->getTransportProtocol()!=IP_PROT_MANET && !datagram->getDestAddress().isMulticast() && datagram->getTransportProtocol()!=IP_PROT_PIM) 00066 { 00067 delete datagram->removeControlInfo(); 00068 } 00069 else if (datagram->getMoreFragments()) 00070 delete datagram->removeControlInfo(); // delete all control message except the last 00071 00072 //MYWORK Add all neccessery info to the IP Control Info for future use. 00073 if (datagram->getDestAddress().isMulticast() || datagram->getTransportProtocol() == IP_PROT_PIM) 00074 { 00075 IPControlInfo *ctrl = (IPControlInfo*)(datagram->removeControlInfo()); 00076 ctrl->setSrcAddr(datagram->getSrcAddress()); 00077 ctrl->setDestAddr(datagram->getDestAddress()); 00078 ctrl->setInterfaceId(getSourceInterfaceFrom(datagram)->getInterfaceId()); 00079 datagram->setControlInfo(ctrl); 00080 } 00081 00082 // hop counter decrement; FIXME but not if it will be locally delivered 00083 datagram->setTimeToLive(datagram->getTimeToLive()-1); 00084 00085 // send IGMP packet to IGMP module 00086 if (datagram->getTransportProtocol() == IP_PROT_IGMP) 00087 { 00088 cPacket *packet = decapsulateIP(datagram); 00089 send(packet, "transportOut", mapping.getOutputGateForProtocol(IP_PROT_IGMP)); 00090 return; 00091 } 00092 00093 //MYWORK send PIM packet to PIM module 00094 if (datagram->getTransportProtocol() == IP_PROT_PIM) 00095 { 00096 cPacket *packet = decapsulateIP(datagram); 00097 send(packet, "transportOut", mapping.getOutputGateForProtocol(IP_PROT_PIM)); 00098 return; 00099 } 00100 00101 //MYWORK route packet 00102 if (!datagram->getDestAddress().isMulticast()) 00103 routePacket(datagram, NULL, false,NULL); 00104 else 00105 routeMulticastPacket(datagram, NULL, getSourceInterfaceFrom(datagram)); 00106 } 00107 00124 void AnsaIP::routeMulticastPacket(IPDatagram *datagram, InterfaceEntry *destIE, InterfaceEntry *fromIE) 00125 { 00126 IPAddress destAddr = datagram->getDestAddress(); 00127 IPAddress srcAddr = datagram->getSrcAddress(); 00128 IPControlInfo *ctrl = (IPControlInfo *) datagram->getControlInfo(); 00129 EV << "Routing multicast datagram `" << datagram->getName() << "' with dest=" << destAddr << "\n"; 00130 MulticastIPRoute *route = mrt->getRouteFor(destAddr, srcAddr); 00131 00132 numMulticast++; 00133 00134 // Process datagram only if sent locally or arrived on the shortest 00135 // route (provided routing table already contains srcAddr) = RPF interface; 00136 // otherwise discard and continue. 00137 InterfaceEntry *rpfInt = rt->getInterfaceForDestAddr(datagram->getSrcAddress()); 00138 if (fromIE!=NULL && rpfInt!=NULL && fromIE!=rpfInt) 00139 { 00140 //MYWORK RPF interface has changed 00141 /*if (route != NULL && (route->getInIntId() != rpfInt->getInterfaceId())) 00142 { 00143 EV << "RPF interface has changed" << endl; 00144 nb->fireChangeNotification(NF_IPv4_RPF_CHANGE, route); 00145 }*/ 00146 //MYWORK Data come to non-RPF interface 00147 if (!rt->isLocalMulticastAddress(destAddr) && !destAddr.isLinkLocalMulticast()) 00148 { 00149 EV << "Data on non-RPF interface" << endl; 00150 nb->fireChangeNotification(NF_IPv4_DATA_ON_NONRPF, ctrl); 00151 return; 00152 } 00153 else 00154 { 00155 // FIXME count dropped 00156 EV << "Packet dropped." << endl; 00157 delete datagram; 00158 return; 00159 } 00160 } 00161 00162 //MYWORK for local traffic to given destination (PIM messages) 00163 if (fromIE == NULL && destIE != NULL) 00164 { 00165 IPDatagram *datagramCopy = (IPDatagram *) datagram->dup(); 00166 datagramCopy->setSrcAddress(destIE->ipv4Data()->getIPAddress()); 00167 fragmentAndSend(datagramCopy, destIE, destAddr); 00168 00169 delete datagram; 00170 return; 00171 } 00172 00173 // if received from the network... 00174 if (fromIE!=NULL) 00175 { 00176 EV << "Packet was received from the network..." << endl; 00177 // check for local delivery (multicast assigned to any interface) 00178 if (rt->isLocalMulticastAddress(destAddr)) 00179 { 00180 EV << "isLocalMulticastAddress." << endl; 00181 IPDatagram *datagramCopy = (IPDatagram *) datagram->dup(); 00182 00183 // FIXME code from the MPLS model: set packet dest address to routerId 00184 datagramCopy->setDestAddress(rt->getRouterId()); 00185 reassembleAndDeliver(datagramCopy); 00186 } 00187 00188 // don't forward if IP forwarding is off 00189 if (!rt->isIPForwardingEnabled()) 00190 { 00191 EV << "IP forwarding is off." << endl; 00192 delete datagram; 00193 return; 00194 } 00195 00196 // don't forward if dest address is link-scope 00197 // address is in the range 224.0.0.0 to 224.0.0.255 00198 if (destAddr.isLinkLocalMulticast()) 00199 { 00200 EV << "isLinkLocalMulticast." << endl; 00201 delete datagram; 00202 return; 00203 } 00204 } 00205 00206 //MYWORK(to the end) now: routing 00207 EV << "AnsaIP::routeMulticastPacket - Multicast routing." << endl; 00208 00209 // multicast group is not in multicast routing table and has to be added 00210 if (route == NULL) 00211 { 00212 EV << "AnsaIP::routeMulticastPacket - Multicast route does not exist, try to add." << endl; 00213 nb->fireChangeNotification(NF_IPv4_NEW_MULTICAST, ctrl); 00214 delete datagram->removeControlInfo(); 00215 ctrl = NULL; 00216 // read new record 00217 route = mrt->getRouteFor(destAddr, srcAddr); 00218 } 00219 00220 if (route == NULL) 00221 { 00222 EV << "Still do not exist." << endl; 00223 delete datagram; 00224 return; 00225 } 00226 00227 nb->fireChangeNotification(NF_IPv4_DATA_ON_RPF, route); 00228 00229 // data won't be sent because there is no outgoing interface and/or route is pruned 00230 InterfaceVector outInt = route->getOutInt(); 00231 if (outInt.size() == 0 || route->isFlagSet(P)) 00232 { 00233 EV << "Route does not have any outgoing interface or it is pruned." << endl; 00234 if(ctrl != NULL) 00235 { 00236 if (!route->isFlagSet(A)) 00237 nb->fireChangeNotification(NF_IPv4_DATA_ON_PRUNED_INT, ctrl); 00238 } 00239 delete datagram; 00240 return; 00241 } 00242 00243 // send packet to all outgoing interfaces of route (oilist) 00244 for (unsigned int i=0; i<outInt.size(); i++) 00245 { 00246 // do not send to pruned interface 00247 if (outInt[i].forwarding == Pruned) 00248 continue; 00249 00250 InterfaceEntry *destIE = outInt[i].intPtr; 00251 IPDatagram *datagramCopy = (IPDatagram *) datagram->dup(); 00252 00253 // set datagram source address if not yet set 00254 if (datagramCopy->getSrcAddress().isUnspecified()) 00255 datagramCopy->setSrcAddress(destIE->ipv4Data()->getIPAddress()); 00256 00257 // send 00258 fragmentAndSend(datagramCopy, destIE, destAddr); 00259 } 00260 00261 // only copies sent, delete original datagram 00262 delete datagram; 00263 } 00264