View Javadoc
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 }