1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.networkstack.tethering;
18 
19 import android.net.MacAddress;
20 
21 import androidx.annotation.NonNull;
22 
23 import com.android.net.module.util.Struct;
24 import com.android.net.module.util.Struct.Field;
25 import com.android.net.module.util.Struct.Type;
26 
27 import java.net.InetAddress;
28 import java.net.UnknownHostException;
29 import java.util.Objects;
30 
31 /** Value type for downstream & upstream IPv4 forwarding maps. */
32 public class Tether4Value extends Struct {
33     @Field(order = 0, type = Type.U32)
34     public final long oif;
35 
36     // The ethhdr struct which is defined in uapi/linux/if_ether.h
37     @Field(order = 1, type = Type.EUI48)
38     public final MacAddress ethDstMac;
39     @Field(order = 2, type = Type.EUI48)
40     public final MacAddress ethSrcMac;
41     @Field(order = 3, type = Type.UBE16)
42     public final int ethProto;  // Packet type ID field.
43 
44     @Field(order = 4, type = Type.U16)
45     public final int pmtu;
46 
47     @Field(order = 5, type = Type.ByteArray, arraysize = 16)
48     public final byte[] src46;
49 
50     @Field(order = 6, type = Type.ByteArray, arraysize = 16)
51     public final byte[] dst46;
52 
53     @Field(order = 7, type = Type.UBE16)
54     public final int srcPort;
55 
56     @Field(order = 8, type = Type.UBE16)
57     public final int dstPort;
58 
59     // TODO: consider using U64.
60     @Field(order = 9, type = Type.U63)
61     public final long lastUsed;
62 
Tether4Value(final long oif, @NonNull final MacAddress ethDstMac, @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu, final byte[] src46, final byte[] dst46, final int srcPort, final int dstPort, final long lastUsed)63     public Tether4Value(final long oif, @NonNull final MacAddress ethDstMac,
64             @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu,
65             final byte[] src46, final byte[] dst46, final int srcPort,
66             final int dstPort, final long lastUsed) {
67         Objects.requireNonNull(ethDstMac);
68         Objects.requireNonNull(ethSrcMac);
69 
70         this.oif = oif;
71         this.ethDstMac = ethDstMac;
72         this.ethSrcMac = ethSrcMac;
73         this.ethProto = ethProto;
74         this.pmtu = pmtu;
75         this.src46 = src46;
76         this.dst46 = dst46;
77         this.srcPort = srcPort;
78         this.dstPort = dstPort;
79         this.lastUsed = lastUsed;
80     }
81 
82     @Override
toString()83     public String toString() {
84         try {
85             return String.format(
86                     "oif: %d, ethDstMac: %s, ethSrcMac: %s, ethProto: %d, pmtu: %d, "
87                             + "src46: %s, dst46: %s, srcPort: %d, dstPort: %d, "
88                             + "lastUsed: %d",
89                     oif, ethDstMac, ethSrcMac, ethProto, pmtu,
90                     InetAddress.getByAddress(src46), InetAddress.getByAddress(dst46),
91                     Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort),
92                     lastUsed);
93         } catch (UnknownHostException | IllegalArgumentException e) {
94             return String.format("Invalid IP address", e);
95         }
96     }
97 }
98