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