1 /*
2  * Copyright (C) 2022 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.server.connectivity.mdns.internal;
18 
19 import android.annotation.NonNull;
20 import android.net.LinkAddress;
21 import android.os.Handler;
22 import android.system.OsConstants;
23 
24 import com.android.net.module.util.SharedLog;
25 import com.android.net.module.util.ip.NetlinkMonitor;
26 import com.android.net.module.util.netlink.NetlinkConstants;
27 import com.android.net.module.util.netlink.NetlinkMessage;
28 import com.android.net.module.util.netlink.RtNetlinkAddressMessage;
29 import com.android.net.module.util.netlink.StructIfaddrMsg;
30 import com.android.server.connectivity.mdns.AbstractSocketNetlinkMonitor;
31 import com.android.server.connectivity.mdns.MdnsSocketProvider;
32 
33 /**
34  * The netlink monitor for MdnsSocketProvider.
35  */
36 public class SocketNetlinkMonitor extends NetlinkMonitor implements AbstractSocketNetlinkMonitor {
37 
38     public static final String TAG = SocketNetlinkMonitor.class.getSimpleName();
39     @NonNull
40     private final SharedLog mSharedLog;
41 
42     @NonNull
43     private final MdnsSocketProvider.NetLinkMonitorCallBack mCb;
SocketNetlinkMonitor(@onNull final Handler handler, @NonNull SharedLog log, @NonNull final MdnsSocketProvider.NetLinkMonitorCallBack cb)44     public SocketNetlinkMonitor(@NonNull final Handler handler,
45             @NonNull SharedLog log,
46             @NonNull final MdnsSocketProvider.NetLinkMonitorCallBack cb) {
47         super(handler, log, TAG, OsConstants.NETLINK_ROUTE,
48                 NetlinkConstants.RTMGRP_IPV4_IFADDR | NetlinkConstants.RTMGRP_IPV6_IFADDR);
49         mCb = cb;
50         mSharedLog = log;
51     }
52     @Override
processNetlinkMessage(NetlinkMessage nlMsg, long whenMs)53     public void processNetlinkMessage(NetlinkMessage nlMsg, long whenMs) {
54         if (nlMsg instanceof RtNetlinkAddressMessage) {
55             processRtNetlinkAddressMessage((RtNetlinkAddressMessage) nlMsg);
56         }
57     }
58 
59     /**
60      * Process the RTM_NEWADDR and RTM_DELADDR netlink message.
61      */
processRtNetlinkAddressMessage(RtNetlinkAddressMessage msg)62     private void processRtNetlinkAddressMessage(RtNetlinkAddressMessage msg) {
63         final StructIfaddrMsg ifaddrMsg = msg.getIfaddrHeader();
64         final LinkAddress la = new LinkAddress(msg.getIpAddress(), ifaddrMsg.prefixLen,
65                 msg.getFlags(), ifaddrMsg.scope);
66         switch (msg.getHeader().nlmsg_type) {
67             case NetlinkConstants.RTM_NEWADDR:
68                 if (la.isPreferred()) {
69                     mCb.addOrUpdateInterfaceAddress(ifaddrMsg.index, la);
70                 }
71                 break;
72             case NetlinkConstants.RTM_DELADDR:
73                 mCb.deleteInterfaceAddress(ifaddrMsg.index, la);
74                 break;
75             default:
76                 mSharedLog.e("Unknown rtnetlink address msg type " + msg.getHeader().nlmsg_type);
77         }
78     }
79 
80     @Override
isSupported()81     public boolean isSupported() {
82         return true;
83     }
84 
85     @Override
startMonitoring()86     public void startMonitoring() {
87         this.start();
88     }
89 
90     @Override
stopMonitoring()91     public void stopMonitoring() {
92         this.stop();
93     }
94 }
95