1 /*
2 * Copyright 2020 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package io.netty.handler.pcap;
17
18 import io.netty.buffer.ByteBuf;
19
20 final class IPPacket {
21
22 private static final byte MAX_TTL = (byte) 255;
23 private static final short V4_HEADER_SIZE = 20;
24 private static final byte TCP = 6 & 0xff;
25 private static final byte UDP = 17 & 0xff;
26
27 /**
28 * Version + Traffic class + Flow label
29 */
30 private static final int IPV6_VERSION_TRAFFIC_FLOW = 60000000;
31
32 private IPPacket() {
33 // Prevent outside initialization
34 }
35
36 /**
37 * Write IPv4 Packet for UDP Packet
38 *
39 * @param byteBuf ByteBuf where IP Packet data will be set
40 * @param payload Payload of UDP
41 * @param srcAddress Source IPv4 Address
42 * @param dstAddress Destination IPv4 Address
43 */
44 static void writeUDPv4(ByteBuf byteBuf, ByteBuf payload, int srcAddress, int dstAddress) {
45 writePacketv4(byteBuf, payload, UDP, srcAddress, dstAddress);
46 }
47
48 /**
49 * Write IPv6 Packet for UDP Packet
50 *
51 * @param byteBuf ByteBuf where IP Packet data will be set
52 * @param payload Payload of UDP
53 * @param srcAddress Source IPv6 Address
54 * @param dstAddress Destination IPv6 Address
55 */
56 static void writeUDPv6(ByteBuf byteBuf, ByteBuf payload, byte[] srcAddress, byte[] dstAddress) {
57 writePacketv6(byteBuf, payload, UDP, srcAddress, dstAddress);
58 }
59
60 /**
61 * Write IPv4 Packet for TCP Packet
62 *
63 * @param byteBuf ByteBuf where IP Packet data will be set
64 * @param payload Payload of TCP
65 * @param srcAddress Source IPv4 Address
66 * @param dstAddress Destination IPv4 Address
67 */
68 static void writeTCPv4(ByteBuf byteBuf, ByteBuf payload, int srcAddress, int dstAddress) {
69 writePacketv4(byteBuf, payload, TCP, srcAddress, dstAddress);
70 }
71
72 /**
73 * Write IPv6 Packet for TCP Packet
74 *
75 * @param byteBuf ByteBuf where IP Packet data will be set
76 * @param payload Payload of TCP
77 * @param srcAddress Source IPv6 Address
78 * @param dstAddress Destination IPv6 Address
79 */
80 static void writeTCPv6(ByteBuf byteBuf, ByteBuf payload, byte[] srcAddress, byte[] dstAddress) {
81 writePacketv6(byteBuf, payload, TCP, srcAddress, dstAddress);
82 }
83
84 private static void writePacketv4(ByteBuf byteBuf, ByteBuf payload, int protocol, int srcAddress,
85 int dstAddress) {
86
87 byteBuf.writeByte(0x45); // Version + IHL
88 byteBuf.writeByte(0x00); // DSCP
89 byteBuf.writeShort(V4_HEADER_SIZE + payload.readableBytes()); // Length
90 byteBuf.writeShort(0x0000); // Identification
91 byteBuf.writeShort(0x0000); // Fragment
92 byteBuf.writeByte(MAX_TTL); // TTL
93 byteBuf.writeByte(protocol); // Protocol
94 byteBuf.writeShort(0); // Checksum
95 byteBuf.writeInt(srcAddress); // Source IPv4 Address
96 byteBuf.writeInt(dstAddress); // Destination IPv4 Address
97 byteBuf.writeBytes(payload); // Payload of L4
98 }
99
100 private static void writePacketv6(ByteBuf byteBuf, ByteBuf payload, int protocol, byte[] srcAddress,
101 byte[] dstAddress) {
102
103 byteBuf.writeInt(IPV6_VERSION_TRAFFIC_FLOW); // Version + Traffic class + Flow label
104 byteBuf.writeShort(payload.readableBytes()); // Payload length
105 byteBuf.writeByte(protocol & 0xff); // Next header
106 byteBuf.writeByte(MAX_TTL); // Hop limit
107 byteBuf.writeBytes(srcAddress); // Source IPv6 Address
108 byteBuf.writeBytes(dstAddress); // Destination IPv6 Address
109 byteBuf.writeBytes(payload); // Payload of L4
110 }
111 }