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 #include "Ctrl.h"
18
19 #include "families/Mac80211hwsim.h"
20 #include "families/Nl80211.h"
21
22 #include <libnl++/Message.h>
23
24 namespace android::nl::protocols::generic {
25
26 using DataType = AttributeDefinition::DataType;
27 using Flags = AttributeDefinition::Flags;
28
29 // clang-format off
Ctrl(Generic::FamilyRegister & familyRegister)30 Ctrl::Ctrl(Generic::FamilyRegister& familyRegister)
31 : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL",
32 {
33 {CTRL_CMD_NEWFAMILY, "NEWFAMILY"},
34 {CTRL_CMD_DELFAMILY, "DELFAMILY"},
35 {CTRL_CMD_GETFAMILY, "GETFAMILY"},
36 {CTRL_CMD_NEWOPS, "NEWOPS"},
37 {CTRL_CMD_DELOPS, "DELOPS"},
38 {CTRL_CMD_GETOPS, "GETOPS"},
39 {CTRL_CMD_NEWMCAST_GRP, "NEWMCAST_GRP"},
40 {CTRL_CMD_DELMCAST_GRP, "DELMCAST_GRP"},
41 {CTRL_CMD_GETMCAST_GRP, "GETMCAST_GRP"},
42 }, {
43 {CTRL_ATTR_FAMILY_ID, {"FAMILY_ID", DataType::Uint}},
44 {CTRL_ATTR_FAMILY_NAME, {"FAMILY_NAME", DataType::StringNul}},
45 {CTRL_ATTR_VERSION, {"VERSION", DataType::Uint}},
46 {CTRL_ATTR_HDRSIZE, {"HDRSIZE", DataType::Uint}},
47 {CTRL_ATTR_MAXATTR, {"MAXATTR", DataType::Uint}},
48 {CTRL_ATTR_OPS, {"OPS", DataType::Nested, AttributeMap{
49 {std::nullopt, {"OP", DataType::Nested, AttributeMap{
50 {CTRL_ATTR_OP_ID, {"ID", DataType::Uint}},
51 {CTRL_ATTR_OP_FLAGS, {"FLAGS", DataType::Uint}},
52 }}},
53 }, Flags::Verbose}},
54 {CTRL_ATTR_MCAST_GROUPS, {"MCAST_GROUPS", DataType::Nested, AttributeMap{
55 {std::nullopt, {"GRP", DataType::Nested, AttributeMap{
56 {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::StringNul}},
57 {CTRL_ATTR_MCAST_GRP_ID, {"ID", DataType::Uint}},
58 }}},
59 }}},
60 }), mFamilyRegister(familyRegister) {}
61 // clang-format on
62
track(const Buffer<nlmsghdr> hdr)63 void Ctrl::track(const Buffer<nlmsghdr> hdr) {
64 const auto msgMaybe = Message<genlmsghdr>::parse(hdr, {GENL_ID_CTRL});
65 if (!msgMaybe.has_value()) return;
66 const auto msg = *msgMaybe;
67
68 if (msg->cmd != CTRL_CMD_NEWFAMILY) return;
69 const auto familyId = msg.attributes.get<uint16_t>(CTRL_ATTR_FAMILY_ID);
70 const auto familyName = msg.attributes.get<std::string>(CTRL_ATTR_FAMILY_NAME);
71
72 /* For now, we support just two families. But if you add more, please define proper
73 * abstraction and not hardcode every name and class here.
74 */
75 if (familyName == "nl80211") {
76 mFamilyRegister[familyId] = std::make_shared<families::Nl80211>(familyId);
77 }
78 if (familyName == "MAC80211_HWSIM") {
79 mFamilyRegister[familyId] = std::make_shared<families::Mac80211hwsim>(familyId);
80 }
81 }
82
83 } // namespace android::nl::protocols::generic
84