• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.net.module.util.netlink.xfrm;
18 
19 import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRMA_REPLAY_ESN_VAL;
20 
21 import android.util.Log;
22 
23 import androidx.annotation.NonNull;
24 import androidx.annotation.Nullable;
25 
26 import com.android.net.module.util.Struct;
27 import com.android.net.module.util.netlink.StructNlAttr;
28 import com.android.net.module.util.netlink.StructNlMsgHdr;
29 
30 import java.nio.ByteBuffer;
31 import java.nio.ByteOrder;
32 
33 /**
34  * A NetlinkMessage subclass for XFRM_MSG_NEWSA messages.
35  *
36  * <p>see also: &lt;linux_src&gt;/include/uapi/linux/xfrm.h
37  *
38  * <p>XFRM_MSG_NEWSA syntax
39  *
40  * <ul>
41  *   <li>TLV: xfrm_usersa_info
42  *   <li>Attributes: XFRMA_ALG_CRYPT, XFRMA_ALG_AUTH, XFRMA_OUTPUT_MARK, XFRMA_IF_ID,
43  *       XFRMA_REPLAY_ESN_VAL,XFRMA_REPLAY_VAL
44  * </ul>
45  *
46  * @hide
47  */
48 public class XfrmNetlinkNewSaMessage extends XfrmNetlinkMessage {
49     private static final String TAG = XfrmNetlinkNewSaMessage.class.getSimpleName();
50     @NonNull private final StructXfrmUsersaInfo mXfrmUsersaInfo;
51 
52     @NonNull private final StructXfrmReplayStateEsn mXfrmReplayStateEsn;
53 
XfrmNetlinkNewSaMessage( @onNull final StructNlMsgHdr header, @NonNull final StructXfrmUsersaInfo xfrmUsersaInfo, @NonNull final StructXfrmReplayStateEsn xfrmReplayStateEsn)54     private XfrmNetlinkNewSaMessage(
55             @NonNull final StructNlMsgHdr header,
56             @NonNull final StructXfrmUsersaInfo xfrmUsersaInfo,
57             @NonNull final StructXfrmReplayStateEsn xfrmReplayStateEsn) {
58         super(header);
59         mXfrmUsersaInfo = xfrmUsersaInfo;
60         mXfrmReplayStateEsn = xfrmReplayStateEsn;
61     }
62 
63     @Override
packPayload(@onNull final ByteBuffer byteBuffer)64     protected void packPayload(@NonNull final ByteBuffer byteBuffer) {
65         mXfrmUsersaInfo.writeToByteBuffer(byteBuffer);
66         if (mXfrmReplayStateEsn != null) {
67             mXfrmReplayStateEsn.writeToByteBuffer(byteBuffer);
68         }
69     }
70 
71     /**
72      * Parse XFRM_MSG_NEWSA message from ByteBuffer.
73      *
74      * <p>This method should be called from NetlinkMessage#parse(ByteBuffer, int) for generic
75      * message validation and processing
76      *
77      * @param nlmsghdr netlink message header.
78      * @param byteBuffer the ByteBuffer instance that wraps the raw netlink message bytes. MUST be
79      *                   host order
80      */
81     @Nullable
parseInternal( @onNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer)82     static XfrmNetlinkNewSaMessage parseInternal(
83             @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) {
84         final StructXfrmUsersaInfo xfrmUsersaInfo =
85                 Struct.parse(StructXfrmUsersaInfo.class, byteBuffer);
86         if (xfrmUsersaInfo == null) {
87             Log.d(TAG, "parse: fail to parse xfrmUsersaInfo");
88             return null;
89         }
90 
91         StructXfrmReplayStateEsn xfrmReplayStateEsn = null;
92 
93         final int payloadLen = nlmsghdr.nlmsg_len - StructNlMsgHdr.STRUCT_SIZE;
94         int parsedLength = StructXfrmUsersaInfo.STRUCT_SIZE;
95         while (parsedLength < payloadLen) {
96             final StructNlAttr attr = StructNlAttr.parse(byteBuffer);
97 
98             if (attr == null) {
99                 Log.d(TAG, "parse: fail to parse netlink attributes");
100                 return null;
101             }
102 
103             final ByteBuffer attrValueBuff = ByteBuffer.wrap(attr.nla_value);
104             attrValueBuff.order(ByteOrder.nativeOrder());
105 
106             if (attr.nla_type == XFRMA_REPLAY_ESN_VAL) {
107                 xfrmReplayStateEsn = StructXfrmReplayStateEsn.parse(attrValueBuff);
108             }
109 
110             parsedLength += attr.nla_len;
111         }
112 
113         // TODO: Add the support of XFRMA_REPLAY_VAL
114 
115         if (xfrmReplayStateEsn == null) {
116             Log.d(TAG, "parse: xfrmReplayStateEsn not found");
117             return null;
118         }
119 
120         final XfrmNetlinkNewSaMessage msg =
121                 new XfrmNetlinkNewSaMessage(nlmsghdr, xfrmUsersaInfo, xfrmReplayStateEsn);
122 
123         return msg;
124     }
125 
126     /** Return the TX sequence number in unisgned long */
getTxSequenceNumber()127     public long getTxSequenceNumber() {
128         return mXfrmReplayStateEsn.getTxSequenceNumber();
129     }
130 
131     /** Return the RX sequence number in unisgned long */
getRxSequenceNumber()132     public long getRxSequenceNumber() {
133         return mXfrmReplayStateEsn.getRxSequenceNumber();
134     }
135 
136     /** Return the bitmap */
getBitmap()137     public byte[] getBitmap() {
138         return mXfrmReplayStateEsn.getBitmap();
139     }
140 
141     /** Return the packet count in unsigned long */
getPacketCount()142     public long getPacketCount() {
143         // It is safe because "packets" is a 64-bit value
144         return mXfrmUsersaInfo.getCurrentLifetime().packets.longValue();
145     }
146 
147     /** Return the byte count in unsigned long */
getByteCount()148     public long getByteCount() {
149         // It is safe because "bytes" is a 64-bit value
150         return mXfrmUsersaInfo.getCurrentLifetime().bytes.longValue();
151     }
152 
153     /** Return the xfrm_usersa_info */
getXfrmUsersaInfo()154     public StructXfrmUsersaInfo getXfrmUsersaInfo() {
155         return mXfrmUsersaInfo;
156     }
157 }
158