blob: 7ec27df69489a668bed4e2f14d2f26193f663dc9 [file] [log] [blame]
Jason Jeremy Iman16f91722020-01-14 09:53:28 +09001// Copyright 2020 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#ifndef PATCHPANEL_BROADCAST_FORWARDER_H_
6#define PATCHPANEL_BROADCAST_FORWARDER_H_
Jason Jeremy Iman16f91722020-01-14 09:53:28 +09007
8#include <sys/socket.h>
9
10#include <shill/net/rtnl_listener.h>
Garrick Evans3388a032020-03-24 11:25:55 +090011#include "patchpanel/shill_client.h"
Jason Jeremy Iman16f91722020-01-14 09:53:28 +090012
13#include <map>
14#include <memory>
15#include <string>
16
17#include <base/files/file_descriptor_watcher_posix.h>
18#include <base/macros.h>
19
Garrick Evans3388a032020-03-24 11:25:55 +090020#include "patchpanel/net_util.h"
Jason Jeremy Iman16f91722020-01-14 09:53:28 +090021
Garrick Evans3388a032020-03-24 11:25:55 +090022namespace patchpanel {
Jason Jeremy Iman16f91722020-01-14 09:53:28 +090023
24constexpr uint32_t kBcastAddr = Ipv4Addr(255, 255, 255, 255);
25
26// Listens to broadcast messages sent by applications and forwards them between
27// network interfaces of host and guest.
28// BroadcastForwarder assumes that guest addresses, including broadcast and
29// netmask, are constant.
30class BroadcastForwarder {
31 public:
32 explicit BroadcastForwarder(const std::string& dev_ifname);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090033 BroadcastForwarder(const BroadcastForwarder&) = delete;
34 BroadcastForwarder& operator=(const BroadcastForwarder&) = delete;
35
Jason Jeremy Iman16f91722020-01-14 09:53:28 +090036 virtual ~BroadcastForwarder() = default;
37
38 bool AddGuest(const std::string& br_ifname);
39 void RemoveGuest(const std::string& br_ifname);
40
41 protected:
42 // Socket is used to keep track of an fd and its watcher.
43 // It also stores addresses corresponding to the interface it is bound to.
44 struct Socket {
45 Socket(base::ScopedFD fd,
46 const base::Callback<void(int)>& callback,
47 uint32_t addr,
48 uint32_t broadaddr,
49 uint32_t netmask = 0);
50 base::ScopedFD fd;
51 std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher;
52 uint32_t addr;
53 uint32_t broadaddr;
54 uint32_t netmask;
55 };
56
57 // Bind will create a broadcast socket and return its fd.
58 // This is used for sending broadcasts.
59 static base::ScopedFD Bind(const std::string& ifname, uint16_t port);
60
61 // BindRaw will create a broadcast socket that listens to all IP packets.
62 // It filters the packets to only broadcast packets that is sent by
63 // applications.
64 // This is used to listen on broadcasts.
65 static base::ScopedFD BindRaw(const std::string& ifname);
66
67 // SendToNetwork sends |data| using a socket bound to |src_port| and
68 // |dev_ifname_| using a temporary socket.
69 bool SendToNetwork(uint16_t src_port,
70 const void* data,
71 ssize_t len,
72 const struct sockaddr_in& dst);
73
74 // SendToGuests will forward the broadcast packet to all Chrome OS guests'
75 // (ARC++, Crostini, etc) internal fd.
76 bool SendToGuests(const void* ip_pkt,
77 ssize_t len,
78 const struct sockaddr_in& dst);
79
80 // Callback from RTNetlink listener, invoked when the lan interface IPv4
81 // address is changed.
82 void AddrMsgHandler(const shill::RTNLMessage& msg);
83
84 // Listens for RTMGRP_IPV4_IFADDR messages and invokes AddrMsgHandler.
85 std::unique_ptr<shill::RTNLListener> addr_listener_;
86
87 const std::string dev_ifname_;
88 std::unique_ptr<Socket> dev_socket_;
89
90 // Mapping from guest bridge interface name to its sockets.
91 std::map<std::string, std::unique_ptr<Socket>> br_sockets_;
92
93 private:
94 void OnFileCanReadWithoutBlocking(int fd);
95
96 base::WeakPtrFactory<BroadcastForwarder> weak_factory_{this};
Jason Jeremy Iman16f91722020-01-14 09:53:28 +090097};
98
Garrick Evans3388a032020-03-24 11:25:55 +090099} // namespace patchpanel
Jason Jeremy Iman16f91722020-01-14 09:53:28 +0900100
Garrick Evans3388a032020-03-24 11:25:55 +0900101#endif // PATCHPANEL_BROADCAST_FORWARDER_H_