blob: dce8b619494e83131128f08cd80b5b97f41fc5dd [file] [log] [blame]
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +09001/*
2 * Copyright (C) 2018 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
17package android.net.dhcp;
18
Remi NGUYEN VANb0762eb2018-08-28 11:06:54 +090019import android.annotation.NonNull;
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090020import android.annotation.Nullable;
21import android.net.util.FdEventsReader;
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090022import android.os.Handler;
23import android.system.Os;
24
25import java.io.FileDescriptor;
26import java.net.Inet4Address;
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090027import java.net.InetSocketAddress;
28
29/**
30 * A {@link FdEventsReader} to receive and parse {@link DhcpPacket}.
31 * @hide
32 */
33abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> {
34 static final class Payload {
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090035 protected final byte[] mBytes = new byte[DhcpPacket.MAX_LENGTH];
36 protected Inet4Address mSrcAddr;
37 protected int mSrcPort;
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090038 }
39
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090040 DhcpPacketListener(@NonNull Handler handler) {
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090041 super(handler, new Payload());
42 }
43
44 @Override
Remi NGUYEN VANb0762eb2018-08-28 11:06:54 +090045 protected int recvBufSize(@NonNull Payload buffer) {
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090046 return buffer.mBytes.length;
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090047 }
48
49 @Override
Remi NGUYEN VANb0762eb2018-08-28 11:06:54 +090050 protected final void handlePacket(@NonNull Payload recvbuf, int length) {
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090051 if (recvbuf.mSrcAddr == null) {
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090052 return;
53 }
54
55 try {
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090056 final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.mBytes, length,
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090057 DhcpPacket.ENCAP_BOOTP);
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090058 onReceive(packet, recvbuf.mSrcAddr, recvbuf.mSrcPort);
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090059 } catch (DhcpPacket.ParseException e) {
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090060 logParseError(recvbuf.mBytes, length, e);
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090061 }
62 }
63
64 @Override
Remi NGUYEN VANb0762eb2018-08-28 11:06:54 +090065 protected int readPacket(@NonNull FileDescriptor fd, @NonNull Payload packetBuffer)
66 throws Exception {
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090067 final InetSocketAddress addr = new InetSocketAddress();
68 final int read = Os.recvfrom(
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090069 fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr);
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090070
71 // Buffers with null srcAddr will be dropped in handlePacket()
Remi NGUYEN VAN73105e112018-12-21 16:17:09 +090072 packetBuffer.mSrcAddr = inet4AddrOrNull(addr);
73 packetBuffer.mSrcPort = addr.getPort();
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090074 return read;
75 }
76
77 @Nullable
Remi NGUYEN VANb0762eb2018-08-28 11:06:54 +090078 private static Inet4Address inet4AddrOrNull(@NonNull InetSocketAddress addr) {
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090079 return addr.getAddress() instanceof Inet4Address
80 ? (Inet4Address) addr.getAddress()
81 : null;
82 }
83
Remi NGUYEN VANb0762eb2018-08-28 11:06:54 +090084 protected abstract void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
85 int srcPort);
86 protected abstract void logParseError(@NonNull byte[] packet, int length,
87 @NonNull DhcpPacket.ParseException e);
Remi NGUYEN VANc1413d02018-06-06 15:47:07 +090088}