|
|
| 48 |
void |
48 |
void |
| 49 |
EpcTftClassifier::Add (Ptr<EpcTft> tft, uint32_t id) |
49 |
EpcTftClassifier::Add (Ptr<EpcTft> tft, uint32_t id) |
| 50 |
{ |
50 |
{ |
| 51 |
NS_LOG_FUNCTION (this << tft); |
51 |
NS_LOG_FUNCTION (this << tft << id); |
| 52 |
|
52 |
m_tftMap[id] = tft; |
| 53 |
m_tftMap[id] = tft; |
53 |
|
| 54 |
|
|
|
| 55 |
// simple sanity check: there shouldn't be more than 16 bearers (hence TFTs) per UE |
54 |
// simple sanity check: there shouldn't be more than 16 bearers (hence TFTs) per UE |
| 56 |
NS_ASSERT (m_tftMap.size () <= 16); |
55 |
NS_ASSERT (m_tftMap.size () <= 16); |
| 57 |
} |
56 |
} |
|
|
| 67 |
uint32_t |
66 |
uint32_t |
| 68 |
EpcTftClassifier::Classify (Ptr<Packet> p, EpcTft::Direction direction) |
67 |
EpcTftClassifier::Classify (Ptr<Packet> p, EpcTft::Direction direction) |
| 69 |
{ |
68 |
{ |
| 70 |
NS_LOG_FUNCTION (this << p << direction); |
69 |
NS_LOG_FUNCTION (this << p << p->GetSize () << direction); |
| 71 |
|
70 |
|
| 72 |
Ptr<Packet> pCopy = p->Copy (); |
71 |
Ptr<Packet> pCopy = p->Copy (); |
| 73 |
|
72 |
|
|
|
| 105 |
} |
104 |
} |
| 106 |
NS_LOG_INFO ("local address: " << localAddressIpv4 << " remote address: " << remoteAddressIpv4); |
105 |
NS_LOG_INFO ("local address: " << localAddressIpv4 << " remote address: " << remoteAddressIpv4); |
| 107 |
|
106 |
|
|
|
107 |
uint16_t payloadSize = ipv4Header.GetPayloadSize (); |
| 108 |
uint16_t fragmentOffset = ipv4Header.GetFragmentOffset (); |
| 109 |
bool isLastFragment = ipv4Header.IsLastFragment (); |
| 110 |
|
| 111 |
// NS_LOG_DEBUG ("PayloadSize = " << payloadSize); |
| 112 |
// NS_LOG_DEBUG ("fragmentOffset " << fragmentOffset << " isLastFragment " << isLastFragment); |
| 113 |
|
| 108 |
protocol = ipv4Header.GetProtocol (); |
114 |
protocol = ipv4Header.GetProtocol (); |
| 109 |
tos = ipv4Header.GetTos (); |
115 |
tos = ipv4Header.GetTos (); |
|
|
116 |
|
| 117 |
// Port info only can be get if it is the first fragment and |
| 118 |
// there is enough data in the payload |
| 119 |
// We keep the port info for fragmented packets, |
| 120 |
// i.e. it is the first one but it is not the last one |
| 121 |
if (fragmentOffset == 0) |
| 122 |
{ |
| 123 |
if (protocol == UdpL4Protocol::PROT_NUMBER && payloadSize >= 8) |
| 124 |
{ |
| 125 |
UdpHeader udpHeader; |
| 126 |
pCopy->RemoveHeader (udpHeader); |
| 127 |
if (direction == EpcTft::UPLINK) |
| 128 |
{ |
| 129 |
localPort = udpHeader.GetSourcePort (); |
| 130 |
remotePort = udpHeader.GetDestinationPort (); |
| 131 |
} |
| 132 |
else |
| 133 |
{ |
| 134 |
remotePort = udpHeader.GetSourcePort (); |
| 135 |
localPort = udpHeader.GetDestinationPort (); |
| 136 |
} |
| 137 |
if (!isLastFragment) |
| 138 |
{ |
| 139 |
std::tuple<uint32_t, uint32_t, uint8_t, uint16_t> fragmentKey = |
| 140 |
std::make_tuple (ipv4Header.GetSource ().Get (), |
| 141 |
ipv4Header.GetDestination ().Get (), |
| 142 |
protocol, |
| 143 |
ipv4Header.GetIdentification ()); |
| 144 |
|
| 145 |
m_classifiedIpv4Fragments[fragmentKey] = std::make_pair (localPort, remotePort); |
| 146 |
} |
| 147 |
} |
| 148 |
else if (protocol == TcpL4Protocol::PROT_NUMBER && payloadSize >= 20) |
| 149 |
{ |
| 150 |
TcpHeader tcpHeader; |
| 151 |
pCopy->RemoveHeader (tcpHeader); |
| 152 |
if (direction == EpcTft::UPLINK) |
| 153 |
{ |
| 154 |
localPort = tcpHeader.GetSourcePort (); |
| 155 |
remotePort = tcpHeader.GetDestinationPort (); |
| 156 |
} |
| 157 |
else |
| 158 |
{ |
| 159 |
remotePort = tcpHeader.GetSourcePort (); |
| 160 |
localPort = tcpHeader.GetDestinationPort (); |
| 161 |
} |
| 162 |
|
| 163 |
if (!isLastFragment) |
| 164 |
{ |
| 165 |
std::tuple<uint32_t, uint32_t, uint8_t, uint16_t> fragmentKey = |
| 166 |
std::make_tuple (ipv4Header.GetSource ().Get (), |
| 167 |
ipv4Header.GetDestination ().Get (), |
| 168 |
protocol, |
| 169 |
ipv4Header.GetIdentification ()); |
| 170 |
|
| 171 |
m_classifiedIpv4Fragments[fragmentKey] = std::make_pair (localPort, remotePort); |
| 172 |
} |
| 173 |
} |
| 174 |
|
| 175 |
// else |
| 176 |
// First fragment but not enough data for port info or not UDP/TCP protocol. |
| 177 |
// Nothing can be done, i.e. we cannot get port info from packet. |
| 178 |
} |
| 179 |
else |
| 180 |
{ |
| 181 |
// Not first fragment, so port info is not available but |
| 182 |
// port info should already be known (if there is not fragment reordering) |
| 183 |
std::tuple<uint32_t, uint32_t, uint8_t, uint16_t> fragmentKey = |
| 184 |
std::make_tuple (ipv4Header.GetSource ().Get (), |
| 185 |
ipv4Header.GetDestination ().Get (), |
| 186 |
protocol, |
| 187 |
ipv4Header.GetIdentification ()); |
| 188 |
|
| 189 |
std::map< std::tuple<uint32_t, uint32_t, uint8_t, uint16_t>, |
| 190 |
std::pair<uint32_t, uint32_t> >::iterator it = |
| 191 |
m_classifiedIpv4Fragments.find (fragmentKey); |
| 192 |
|
| 193 |
if (it != m_classifiedIpv4Fragments.end ()) |
| 194 |
{ |
| 195 |
localPort = it->second.first; |
| 196 |
remotePort = it->second.second; |
| 197 |
|
| 198 |
if (isLastFragment) |
| 199 |
{ |
| 200 |
m_classifiedIpv4Fragments.erase (fragmentKey); |
| 201 |
} |
| 202 |
} |
| 203 |
} |
| 110 |
} |
204 |
} |
| 111 |
else if (ipType == 0x06) |
205 |
else if (ipType == 0x06) |
| 112 |
{ |
206 |
{ |
|
|
| 128 |
|
222 |
|
| 129 |
protocol = ipv6Header.GetNextHeader (); |
223 |
protocol = ipv6Header.GetNextHeader (); |
| 130 |
tos = ipv6Header.GetTrafficClass (); |
224 |
tos = ipv6Header.GetTrafficClass (); |
|
|
225 |
|
| 226 |
if (protocol == UdpL4Protocol::PROT_NUMBER) |
| 227 |
{ |
| 228 |
UdpHeader udpHeader; |
| 229 |
pCopy->RemoveHeader (udpHeader); |
| 230 |
|
| 231 |
if (direction == EpcTft::UPLINK) |
| 232 |
{ |
| 233 |
localPort = udpHeader.GetSourcePort (); |
| 234 |
remotePort = udpHeader.GetDestinationPort (); |
| 235 |
} |
| 236 |
else |
| 237 |
{ |
| 238 |
remotePort = udpHeader.GetSourcePort (); |
| 239 |
localPort = udpHeader.GetDestinationPort (); |
| 240 |
} |
| 241 |
} |
| 242 |
else if (protocol == TcpL4Protocol::PROT_NUMBER) |
| 243 |
{ |
| 244 |
TcpHeader tcpHeader; |
| 245 |
pCopy->RemoveHeader (tcpHeader); |
| 246 |
if (direction == EpcTft::UPLINK) |
| 247 |
{ |
| 248 |
localPort = tcpHeader.GetSourcePort (); |
| 249 |
remotePort = tcpHeader.GetDestinationPort (); |
| 250 |
} |
| 251 |
else |
| 252 |
{ |
| 253 |
remotePort = tcpHeader.GetSourcePort (); |
| 254 |
localPort = tcpHeader.GetDestinationPort (); |
| 255 |
} |
| 256 |
} |
| 131 |
} |
257 |
} |
| 132 |
else |
258 |
else |
| 133 |
{ |
259 |
{ |
| 134 |
NS_ABORT_MSG ("EpcTftClassifier::Classify - Unknown IP type..."); |
260 |
NS_ABORT_MSG ("EpcTftClassifier::Classify - Unknown IP type..."); |
| 135 |
} |
261 |
} |
| 136 |
|
262 |
|
| 137 |
if (protocol == UdpL4Protocol::PROT_NUMBER) |
|
|
| 138 |
{ |
| 139 |
UdpHeader udpHeader; |
| 140 |
pCopy->RemoveHeader (udpHeader); |
| 141 |
|
| 142 |
if (direction == EpcTft::UPLINK) |
| 143 |
{ |
| 144 |
localPort = udpHeader.GetSourcePort (); |
| 145 |
remotePort = udpHeader.GetDestinationPort (); |
| 146 |
} |
| 147 |
else |
| 148 |
{ |
| 149 |
remotePort = udpHeader.GetSourcePort (); |
| 150 |
localPort = udpHeader.GetDestinationPort (); |
| 151 |
} |
| 152 |
} |
| 153 |
else if (protocol == TcpL4Protocol::PROT_NUMBER) |
| 154 |
{ |
| 155 |
TcpHeader tcpHeader; |
| 156 |
pCopy->RemoveHeader (tcpHeader); |
| 157 |
if (direction == EpcTft::UPLINK) |
| 158 |
{ |
| 159 |
localPort = tcpHeader.GetSourcePort (); |
| 160 |
remotePort = tcpHeader.GetDestinationPort (); |
| 161 |
} |
| 162 |
else |
| 163 |
{ |
| 164 |
remotePort = tcpHeader.GetSourcePort (); |
| 165 |
localPort = tcpHeader.GetDestinationPort (); |
| 166 |
} |
| 167 |
} |
| 168 |
else if (protocol == Icmpv6L4Protocol::PROT_NUMBER || protocol == Icmpv4L4Protocol::PROT_NUMBER) |
| 169 |
{ |
| 170 |
remotePort = 0; |
| 171 |
localPort = 0; |
| 172 |
} |
| 173 |
else |
| 174 |
{ |
| 175 |
NS_LOG_INFO ("Unknown protocol: " << protocol); |
| 176 |
return 0; // no match |
| 177 |
} |
| 178 |
|
263 |
|
| 179 |
if (ipType == 0x04) |
264 |
if (ipType == 0x04) |
| 180 |
{ |
265 |
{ |