00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <omnetpp.h>
00026 #include <string.h>
00027 #include "UDPPacket.h"
00028 #include "UDP.h"
00029 #include "IPControlInfo.h"
00030 #include "IPv6ControlInfo.h"
00031 #include "ICMPAccess.h"
00032 #include "ICMPv6Access.h"
00033
00034
00035 #include "ICMPMessage_m.h"
00036 #include "ICMPv6Message_m.h"
00037 #include "IPDatagram_m.h"
00038 #include "IPv6Datagram_m.h"
00039
00040
00041 #define EPHEMERAL_PORTRANGE_START 1024
00042 #define EPHEMERAL_PORTRANGE_END 5000
00043
00044
00045 Define_Module( UDP );
00046
00047
00048 static std::ostream & operator<<(std::ostream & os, const UDP::SockDesc& sd)
00049 {
00050 os << "sockId=" << sd.sockId;
00051 os << " appGateIndex=" << sd.appGateIndex;
00052 os << " userId=" << sd.userId;
00053 os << " localPort=" << sd.localPort;
00054 if (sd.remotePort!=0)
00055 os << " remotePort=" << sd.remotePort;
00056 if (!sd.localAddr.isUnspecified())
00057 os << " localAddr=" << sd.localAddr;
00058 if (!sd.remoteAddr.isUnspecified())
00059 os << " remoteAddr=" << sd.remoteAddr;
00060 if (sd.interfaceId!=-1)
00061 os << " interfaceId=" << sd.interfaceId;
00062
00063 return os;
00064 }
00065
00066 static std::ostream & operator<<(std::ostream & os, const UDP::SockDescList& list)
00067 {
00068 for (UDP::SockDescList::const_iterator i=list.begin(); i!=list.end(); ++i)
00069 os << "sockId=" << (*i)->sockId << " ";
00070 return os;
00071 }
00072
00073
00074
00075 UDP::~UDP()
00076 {
00077 for (SocketsByIdMap::iterator i=socketsByIdMap.begin(); i!=socketsByIdMap.end(); ++i)
00078 delete i->second;
00079 }
00080
00081 void UDP::initialize()
00082 {
00083 WATCH_PTRMAP(socketsByIdMap);
00084 WATCH_MAP(socketsByPortMap);
00085
00086 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00087 icmp = NULL;
00088 icmpv6 = NULL;
00089
00090 numSent = 0;
00091 numPassedUp = 0;
00092 numDroppedWrongPort = 0;
00093 numDroppedBadChecksum = 0;
00094 WATCH(numSent);
00095 WATCH(numPassedUp);
00096 WATCH(numDroppedWrongPort);
00097 WATCH(numDroppedBadChecksum);
00098 }
00099
00100 void UDP::bind(int gateIndex, UDPControlInfo *ctrl)
00101 {
00102
00103
00104
00105 SockDesc *sd = new SockDesc();
00106 sd->sockId = ctrl->getSockId();
00107 sd->userId = ctrl->getUserId();
00108 sd->appGateIndex = gateIndex;
00109 sd->localAddr = ctrl->getSrcAddr();
00110 sd->remoteAddr = ctrl->getDestAddr();
00111 sd->localPort = ctrl->getSrcPort();
00112 sd->remotePort = ctrl->getDestPort();
00113 sd->interfaceId = ctrl->getInterfaceId();
00114
00115 if (sd->sockId==-1)
00116 error("sockId in BIND message not filled in");
00117 if (sd->localPort==0)
00118 sd->localPort = getEphemeralPort();
00119
00120 sd->onlyLocalPortIsSet = sd->localAddr.isUnspecified() &&
00121 sd->remoteAddr.isUnspecified() &&
00122 sd->remotePort==0 &&
00123 sd->interfaceId==-1;
00124
00125 EV << "Binding socket: " << *sd << "\n";
00126
00127
00128 ASSERT(socketsByIdMap.find(sd->sockId)==socketsByIdMap.end());
00129 socketsByIdMap[sd->sockId] = sd;
00130
00131
00132 SockDescList& list = socketsByPortMap[sd->localPort];
00133 list.push_back(sd);
00134 }
00135
00136 void UDP::connect(int sockId, IPvXAddress addr, int port)
00137 {
00138 SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00139 if (it==socketsByIdMap.end())
00140 error("socket id=%d doesn't exist (already closed?)", sockId);
00141 if (addr.isUnspecified())
00142 opp_error("connect: unspecified remote address");
00143 if (port<=0 || port>65535)
00144 opp_error("connect: invalid remote port number %d", port);
00145
00146 SockDesc *sd = it->second;
00147 sd->remoteAddr = addr;
00148 sd->remotePort = port;
00149
00150 sd->onlyLocalPortIsSet = false;
00151
00152 EV << "Connecting socket: " << *sd << "\n";
00153 }
00154
00155 void UDP::unbind(int sockId)
00156 {
00157
00158 SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00159 if (it==socketsByIdMap.end())
00160 error("socket id=%d doesn't exist (already closed?)", sockId);
00161 SockDesc *sd = it->second;
00162 socketsByIdMap.erase(it);
00163
00164 EV << "Unbinding socket: " << *sd << "\n";
00165
00166
00167 SockDescList& list = socketsByPortMap[sd->localPort];
00168 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00169 if (*it == sd)
00170 {list.erase(it); break;}
00171 if (list.empty())
00172 socketsByPortMap.erase(sd->localPort);
00173 delete sd;
00174 }
00175
00176 ushort UDP::getEphemeralPort()
00177 {
00178
00179 ushort searchUntil = lastEphemeralPort++;
00180 if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END)
00181 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00182
00183 while (socketsByPortMap.find(lastEphemeralPort)!=socketsByPortMap.end())
00184 {
00185 if (lastEphemeralPort == searchUntil)
00186 error("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
00187 lastEphemeralPort++;
00188 if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END)
00189 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00190 }
00191
00192
00193 return lastEphemeralPort;
00194 }
00195
00196 void UDP::handleMessage(cMessage *msg)
00197 {
00198
00199 if (msg->arrivedOn("ipIn") || msg->arrivedOn("ipv6In"))
00200 {
00201 if (dynamic_cast<ICMPMessage *>(msg) || dynamic_cast<ICMPv6Message *>(msg))
00202 processICMPError(PK(msg));
00203 else
00204 processUDPPacket(check_and_cast<UDPPacket *>(msg));
00205 }
00206 else
00207 {
00208 if (msg->getKind()==UDP_C_DATA)
00209 processMsgFromApp(PK(msg));
00210 else
00211 processCommandFromApp(msg);
00212 }
00213
00214 if (ev.isGUI())
00215 updateDisplayString();
00216 }
00217
00218 void UDP::updateDisplayString()
00219 {
00220 char buf[80];
00221 sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
00222 if (numDroppedWrongPort>0)
00223 {
00224 sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
00225 getDisplayString().setTagArg("i",1,"red");
00226 }
00227 getDisplayString().setTagArg("t",0,buf);
00228 }
00229
00230 bool UDP::matchesSocket(SockDesc *sd, UDPPacket *udp, IPControlInfo *ipCtrl)
00231 {
00232
00233 if (sd->remotePort!=0 && sd->remotePort!=udp->getSourcePort())
00234 return false;
00235 if (!sd->localAddr.isUnspecified() && sd->localAddr.get4()!=ipCtrl->getDestAddr())
00236 return false;
00237 if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get4()!=ipCtrl->getSrcAddr())
00238 return false;
00239 if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->getInterfaceId())
00240 return false;
00241 return true;
00242 }
00243
00244 bool UDP::matchesSocket(SockDesc *sd, UDPPacket *udp, IPv6ControlInfo *ipCtrl)
00245 {
00246
00247 if (sd->remotePort!=0 && sd->remotePort!=udp->getSourcePort())
00248 return false;
00249 if (!sd->localAddr.isUnspecified() && sd->localAddr.get6()!=ipCtrl->getDestAddr())
00250 return false;
00251 if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get6()!=ipCtrl->getSrcAddr())
00252 return false;
00253 if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->getInterfaceId())
00254 return false;
00255 return true;
00256 }
00257
00258 bool UDP::matchesSocket(SockDesc *sd, const IPvXAddress& localAddr, const IPvXAddress& remoteAddr, ushort remotePort)
00259 {
00260 return (sd->remotePort==0 || sd->remotePort!=remotePort) &&
00261 (sd->localAddr.isUnspecified() || sd->localAddr==localAddr) &&
00262 (sd->remoteAddr.isUnspecified() || sd->remoteAddr==remoteAddr);
00263 }
00264
00265 void UDP::sendUp(cPacket *payload, UDPPacket *udpHeader, IPControlInfo *ipCtrl, SockDesc *sd)
00266 {
00267
00268 UDPControlInfo *udpCtrl = new UDPControlInfo();
00269 udpCtrl->setSockId(sd->sockId);
00270 udpCtrl->setUserId(sd->userId);
00271 udpCtrl->setSrcAddr(ipCtrl->getSrcAddr());
00272 udpCtrl->setDestAddr(ipCtrl->getDestAddr());
00273 udpCtrl->setSrcPort(udpHeader->getSourcePort());
00274 udpCtrl->setDestPort(udpHeader->getDestinationPort());
00275 udpCtrl->setInterfaceId(ipCtrl->getInterfaceId());
00276 payload->setControlInfo(udpCtrl);
00277
00278 send(payload, "appOut", sd->appGateIndex);
00279 numPassedUp++;
00280 }
00281
00282 void UDP::sendUp(cPacket *payload, UDPPacket *udpHeader, IPv6ControlInfo *ipCtrl, SockDesc *sd)
00283 {
00284
00285 UDPControlInfo *udpCtrl = new UDPControlInfo();
00286 udpCtrl->setSockId(sd->sockId);
00287 udpCtrl->setUserId(sd->userId);
00288 udpCtrl->setSrcAddr(ipCtrl->getSrcAddr());
00289 udpCtrl->setDestAddr(ipCtrl->getDestAddr());
00290 udpCtrl->setSrcPort(udpHeader->getSourcePort());
00291 udpCtrl->setDestPort(udpHeader->getDestinationPort());
00292 udpCtrl->setInterfaceId(ipCtrl->getInterfaceId());
00293 payload->setControlInfo(udpCtrl);
00294
00295 send(payload, "appOut", sd->appGateIndex);
00296 numPassedUp++;
00297 }
00298
00299 void UDP::processUndeliverablePacket(UDPPacket *udpPacket, cPolymorphic *ctrl)
00300 {
00301 numDroppedWrongPort++;
00302
00303
00304 if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL)
00305 {
00306 if (!icmp)
00307 icmp = ICMPAccess().get();
00308 IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00309 if (!ctrl4->getDestAddr().isMulticast())
00310 icmp->sendErrorMessage(udpPacket, ctrl4, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PORT_UNREACHABLE);
00311 }
00312 else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->getControlInfo())!=NULL)
00313 {
00314 if (!icmpv6)
00315 icmpv6 = ICMPv6Access().get();
00316 IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00317 if (!ctrl6->getDestAddr().isMulticast())
00318 icmpv6->sendErrorMessage(udpPacket, ctrl6, ICMPv6_DESTINATION_UNREACHABLE, PORT_UNREACHABLE);
00319 }
00320 else
00321 {
00322 error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
00323 }
00324 }
00325
00326 void UDP::processICMPError(cPacket *msg)
00327 {
00328
00329 int type, code;
00330 IPvXAddress localAddr, remoteAddr;
00331 ushort localPort, remotePort;
00332
00333 if (dynamic_cast<ICMPMessage *>(msg))
00334 {
00335 ICMPMessage *icmpMsg = (ICMPMessage *)msg;
00336 type = icmpMsg->getType();
00337 code = icmpMsg->getCode();
00338
00339 IPDatagram *datagram = check_and_cast<IPDatagram *>(icmpMsg->getEncapsulatedMsg());
00340 UDPPacket *packet = check_and_cast<UDPPacket *>(datagram->getEncapsulatedMsg());
00341 localAddr = datagram->getSrcAddress();
00342 remoteAddr = datagram->getDestAddress();
00343 localPort = packet->getSourcePort();
00344 remotePort = packet->getDestinationPort();
00345 delete icmpMsg;
00346 }
00347 else if (dynamic_cast<ICMPv6Message *>(msg))
00348 {
00349 ICMPv6Message *icmpMsg = (ICMPv6Message *)msg;
00350 type = icmpMsg->getType();
00351 code = -1;
00352
00353 IPv6Datagram *datagram = check_and_cast<IPv6Datagram *>(icmpMsg->getEncapsulatedMsg());
00354 UDPPacket *packet = check_and_cast<UDPPacket *>(datagram->getEncapsulatedMsg());
00355 localAddr = datagram->getSrcAddress();
00356 remoteAddr = datagram->getDestAddress();
00357 localPort = packet->getSourcePort();
00358 remotePort = packet->getDestinationPort();
00359 delete icmpMsg;
00360 }
00361 EV << "ICMP error received: type=" << type << " code=" << code
00362 << " about packet " << localAddr << ":" << localPort << " > "
00363 << remoteAddr << ":" << remotePort << "\n";
00364
00365
00366 SocketsByPortMap::iterator it = socketsByPortMap.find(localPort);
00367 if (it==socketsByPortMap.end())
00368 {
00369 EV << "No socket on that local port, ignoring ICMP error\n";
00370 return;
00371 }
00372 SockDescList& list = it->second;
00373 SockDesc *srcSocket = NULL;
00374 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00375 {
00376 SockDesc *sd = *it;
00377 if (sd->onlyLocalPortIsSet || matchesSocket(sd, localAddr, remoteAddr, remotePort))
00378 {
00379 srcSocket = sd;
00380 }
00381 }
00382 if (!srcSocket)
00383 {
00384 EV << "No matching socket, ignoring ICMP error\n";
00385 return;
00386 }
00387
00388
00389 EV << "Source socket is sockId=" << srcSocket->sockId << ", notifying.\n";
00390 sendUpErrorNotification(srcSocket, UDP_I_ERROR, localAddr, remoteAddr, remotePort);
00391 }
00392
00393 void UDP::sendUpErrorNotification(SockDesc *sd, int msgkind, const IPvXAddress& localAddr, const IPvXAddress& remoteAddr, ushort remotePort)
00394 {
00395 cPacket *notifyMsg = new cPacket("ERROR", msgkind);
00396 UDPControlInfo *udpCtrl = new UDPControlInfo();
00397 udpCtrl->setSockId(sd->sockId);
00398 udpCtrl->setUserId(sd->userId);
00399 udpCtrl->setSrcAddr(localAddr);
00400 udpCtrl->setDestAddr(remoteAddr);
00401 udpCtrl->setSrcPort(sd->localPort);
00402 udpCtrl->setDestPort(remotePort);
00403 notifyMsg->setControlInfo(udpCtrl);
00404
00405 send(notifyMsg, "appOut", sd->appGateIndex);
00406 }
00407
00408 void UDP::processUDPPacket(UDPPacket *udpPacket)
00409 {
00410
00411 EV << "Packet " << udpPacket->getName() << " received from network, dest port " << udpPacket->getDestinationPort() << "\n";
00412 if (udpPacket->hasBitError())
00413 {
00414 EV << "Packet has bit error, discarding\n";
00415 delete udpPacket;
00416 numDroppedBadChecksum++;
00417 return;
00418 }
00419
00420 int destPort = udpPacket->getDestinationPort();
00421 cPolymorphic *ctrl = udpPacket->removeControlInfo();
00422
00423
00424 SocketsByPortMap::iterator it = socketsByPortMap.find(destPort);
00425 if (it==socketsByPortMap.end())
00426 {
00427 EV << "No socket registered on port " << destPort << "\n";
00428 processUndeliverablePacket(udpPacket, ctrl);
00429 return;
00430 }
00431 SockDescList& list = it->second;
00432
00433 int matches = 0;
00434
00435
00436 cPacket *payload = udpPacket->getEncapsulatedMsg();
00437 if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL)
00438 {
00439 IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00440 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00441 {
00442 SockDesc *sd = *it;
00443 if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4))
00444 {
00445 EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n";
00446 sendUp((cPacket*)payload->dup(), udpPacket, ctrl4, sd);
00447 matches++;
00448 }
00449 }
00450 }
00451 else if (dynamic_cast<IPv6ControlInfo *>(ctrl)!=NULL)
00452 {
00453 IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00454 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00455 {
00456 SockDesc *sd = *it;
00457 if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6))
00458 {
00459 EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n";
00460 sendUp((cPacket*)payload->dup(), udpPacket, ctrl6, sd);
00461 matches++;
00462 }
00463 }
00464 }
00465 else
00466 {
00467 error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
00468 }
00469
00470
00471 if (matches==0)
00472 {
00473 EV << "None of the sockets on port " << destPort << " matches the packet\n";
00474 processUndeliverablePacket(udpPacket, ctrl);
00475 return;
00476 }
00477
00478 delete udpPacket;
00479 delete ctrl;
00480 }
00481
00482
00483 void UDP::processMsgFromApp(cPacket *appData)
00484 {
00485 UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo());
00486
00487 UDPPacket *udpPacket = createUDPPacket(appData->getName());
00488 udpPacket->setByteLength(UDP_HEADER_BYTES);
00489 udpPacket->encapsulate(appData);
00490
00491
00492 udpPacket->setSourcePort(udpCtrl->getSrcPort());
00493 udpPacket->setDestinationPort(udpCtrl->getDestPort());
00494
00495 if (!udpCtrl->getDestAddr().isIPv6())
00496 {
00497
00498 EV << "Sending app packet " << appData->getName() << " over IPv4.\n";
00499 IPControlInfo *ipControlInfo = new IPControlInfo();
00500 ipControlInfo->setProtocol(IP_PROT_UDP);
00501 ipControlInfo->setSrcAddr(udpCtrl->getSrcAddr().get4());
00502 ipControlInfo->setDestAddr(udpCtrl->getDestAddr().get4());
00503 ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId());
00504 udpPacket->setControlInfo(ipControlInfo);
00505 delete udpCtrl;
00506
00507 send(udpPacket,"ipOut");
00508 }
00509 else
00510 {
00511
00512 EV << "Sending app packet " << appData->getName() << " over IPv6.\n";
00513 IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
00514 ipControlInfo->setProtocol(IP_PROT_UDP);
00515 ipControlInfo->setSrcAddr(udpCtrl->getSrcAddr().get6());
00516 ipControlInfo->setDestAddr(udpCtrl->getDestAddr().get6());
00517
00518 udpPacket->setControlInfo(ipControlInfo);
00519 delete udpCtrl;
00520
00521 send(udpPacket,"ipv6Out");
00522 }
00523 numSent++;
00524 }
00525
00526 UDPPacket *UDP::createUDPPacket(const char *name)
00527 {
00528 return new UDPPacket(name);
00529 }
00530
00531 void UDP::processCommandFromApp(cMessage *msg)
00532 {
00533 UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
00534 switch (msg->getKind())
00535 {
00536 case UDP_C_BIND:
00537 bind(msg->getArrivalGate()->getIndex(), udpCtrl);
00538 break;
00539 case UDP_C_CONNECT:
00540 connect(udpCtrl->getSockId(), udpCtrl->getDestAddr(), udpCtrl->getDestPort());
00541 break;
00542 case UDP_C_UNBIND:
00543 unbind(udpCtrl->getSockId());
00544 break;
00545 default:
00546 error("unknown command code (message kind) %d received from app", msg->getKind());
00547 }
00548
00549 delete udpCtrl;
00550 delete msg;
00551 }
00552
00553