| 35 | #include "utils/udp.h" |
| 36 | |
| 37 | void IPSwap::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { |
| 38 | using bess::utils::Ethernet; |
| 39 | using bess::utils::Ipv4; |
| 40 | using bess::utils::Udp; |
| 41 | |
| 42 | int cnt = batch->cnt(); |
| 43 | |
| 44 | for (int i = 0; i < cnt; i++) { |
| 45 | bess::Packet *pkt = batch->pkts()[i]; |
| 46 | |
| 47 | Ethernet *eth = pkt->head_data<Ethernet *>(); |
| 48 | Ipv4 *ip = reinterpret_cast<Ipv4 *>(eth + 1); |
| 49 | size_t ip_bytes = (ip->header_length & 0xf) << 2; |
| 50 | Udp *udp = |
| 51 | reinterpret_cast<Udp *>(reinterpret_cast<uint8_t *>(ip) + ip_bytes); |
| 52 | |
| 53 | // std::swap cannot be used for packed fields |
| 54 | bess::utils::be32_t tmp_ip = ip->src; |
| 55 | ip->src = ip->dst; |
| 56 | ip->dst = tmp_ip; |
| 57 | |
| 58 | bess::utils::be16_t tmp_port; |
| 59 | switch (ip->protocol) { |
| 60 | case Ipv4::Proto::kTcp: |
| 61 | case Ipv4::Proto::kUdp: |
| 62 | // TCP and UDP share the same layout for ports |
| 63 | tmp_port = udp->src_port; |
| 64 | udp->src_port = udp->dst_port; |
| 65 | udp->dst_port = tmp_port; |
| 66 | break; |
| 67 | case Ipv4::Proto::kIcmp: |
| 68 | break; |
| 69 | default: |
| 70 | VLOG(1) << "Unknown protocol: " << ip->protocol; |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | RunNextModule(ctx, batch); |
| 75 | } |
| 76 | |
| 77 | ADD_MODULE(IPSwap, "ipswap", |
| 78 | "swaps source/destination IP addresses and L4 ports") |