123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- #include <hooks/hooks.h>
- #include <dhcp/pkt4.h>
- #include <dhcp/hwaddr.h>
- #include <dhcpsrv/subnet.h>
- #include <dhcpsrv/lease.h>
- #include <dhcpsrv/host.h>
- #include <util/strutil.h>
- #include <dhcp/option_string.h>
- #include <dhcp/option4_addrlst.h>
- #include <dhcp/docsis3_option_defs.h>
- #include <string>
- #include <dhcp/dhcp6.h>
- #include <dhcp/pkt6.h>
- #include <dhcp/option6_ia.h>
- #include <boost/foreach.hpp>
- #include "logger.h"
- #include "common.h"
- using namespace isc::dhcp;
- using namespace isc::hooks;
- extern "C" {
- #include <numeric> //inner_product
- #include <functional> //plus, equal_to, not2
- #include <algorithm>
- #include <string>
- #include <stdexcept>
- #include "mysql_connection.h"
- MySQLConnection conn;
- std::string getMacFromPacket(Pkt4Ptr);
- /**
- * Get the cablemodem mac from (option 82) or if vendor_class is *docsis* get the c_hwaddr
- */
- std::string getMacFromPacket(Pkt4Ptr pkt)
- {
- std::string rtr = "";
- if (pkt->getOption(DHO_DHCP_AGENT_OPTIONS)) {
- rtr = pkt->getOption(DHO_DHCP_AGENT_OPTIONS)->toHexString(false).substr(6,12);
- std::vector<uint8_t> binary;
- isc::util::str::decodeFormattedHexString(rtr, binary);
- } else if (pkt->getOption(DHO_VENDOR_CLASS_IDENTIFIER)) {
- std::string docsis_vendor_class = pkt->getOption(DHO_VENDOR_CLASS_IDENTIFIER)->toString().substr(2,6);
- if (docsis_vendor_class.compare("docsis") == 0) {
- rtr = pkt->getMAC(HWAddr::HWADDR_SOURCE_RAW)->toText(false);
- isc::util::str::uppercase(rtr);
- rtr.erase(std::remove(rtr.begin(), rtr.end(), ':'), rtr.end());
- }
- }
- return rtr;
- }
- enum HostType{ CABLEMODEM, EMTA, CPE };
- std::string HostClass[] = { "cm", "mta", "cpe" };
- HostType getHostType(Pkt4Ptr pkt)
- {
- HostType rtr = CPE;
- std::string cm_mac = getMacFromPacket(pkt);
- //Non Empty MAC
- if (cm_mac.size() != 0) {
- std::string chwdr = pkt->getHWAddr()->toText(false);
- isc::util::str::uppercase(chwdr);
- chwdr.erase(std::remove(chwdr.begin(), chwdr.end(), ':'), chwdr.end());
-
- std::string opt82mac = "";
- if (pkt->getOption(DHO_DHCP_AGENT_OPTIONS)) {
- opt82mac = pkt->getOption(DHO_DHCP_AGENT_OPTIONS)->toHexString(false).substr(6,12);
-
- std::vector<uint8_t> binary;
- isc::util::str::decodeFormattedHexString(opt82mac, binary);
- }
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("hwaddr: " + chwdr);
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("remoteid: "+opt82mac);
-
- if (chwdr == opt82mac) {
- rtr = CABLEMODEM;
-
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("option 82 mac == chwdr ==> CABLEMODEM");
- } else {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("dou't " + chwdr + " !== " + opt82mac);
-
- if (pkt->getOption(DHO_VENDOR_CLASS_IDENTIFIER)) {
- std::string docsis_vendor_class = pkt->getOption(DHO_VENDOR_CLASS_IDENTIFIER)->toString().substr(0,6);
- std::string pktc_vendor_class = pkt->getOption(DHO_VENDOR_CLASS_IDENTIFIER)->toString().substr(0,4);
-
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("Checking Vendor Class ID");
- if (docsis_vendor_class.compare("docsis") == 0) {
- rtr = CABLEMODEM;
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("docsis en vendor class ==> CABLEMODEM");
- } else {
- if (pktc_vendor_class.compare("pktc") == 0) {
- rtr = EMTA;
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("pktc en vendor class ==> EMTA");
- } else {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("vendor class unknown");
- }
- }
- } else {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("no vendor class");
- }
- }
- } else {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("Empty MAC fomr getMacFromPacket ==> CPE " + std::to_string(cm_mac.size()));
- if (pkt->isRelayed()) {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("Pakcet Relayed");
- }
- }
- return rtr;
- }
- /* IPv4 callouts */
- int pkt4_receive(CalloutHandle& handle)
- {
- Pkt4Ptr query;
- handle.getArgument("query4", query);
-
- // Busco la class para la mac que viene en el paquete
- // en fd3_dhcp.host, si no existe el host cargado no tiene class
- std::string mac = getMacFromPacket(query);
- std::string MAC = mac;
- std::transform(mac.begin(), mac.end(), mac.begin(), ::tolower);
-
- std::string sql_query = "SELECT state FROM `host` WHERE `mac` LIKE '" + mac + "';";
- std::string class_map = conn.executeQuery((sql_query).c_str());
- if (class_map != "") {
- cm_map[MAC] = class_map;
-
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("cablemodem " + mac + " class " + class_map);
- } else {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("cablemodem " + mac + " class not found ");
- }
-
- std::vector<std::string> list_class;
- HWAddrPtr remote_id;
- HostType ht = getHostType(query);
-
- list_class.push_back(HostClass[ht]);
- std::map<std::string,std::string>::iterator it = cm_map.find(MAC);
- if (it != cm_map.end()) {
- list_class.push_back(cm_map[MAC]);
- }
- std::string me, me2;
- BOOST_FOREACH(me, list_class) {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("class : " + me);
- BOOST_FOREACH(me2, list_class) {
- if (me.compare(me2) != 0) {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("class : " + me + "-" + me2);
- query->addClass(me + "-" + me2);
- }
- }
- query->addClass(me);
-
- Host::IdentifierType type;
- std::vector<uint8_t> id((me + "-" + mac).begin(), (me + "-" + mac).end());
- type = Host::IDENT_FLEX;
-
- handle.setArgument("id_value", id);
- handle.setArgument("id_type", type);
- }
- return 0;
- }
- int pkt4_send(CalloutHandle& handle)
- {
- Pkt4Ptr response;
- Pkt4Ptr query;
- handle.getArgument("response4", response);
- handle.getArgument("query4", query);
- uint8_t ufile_name[128] = "";
- std::string mac;
- HostType ht = getHostType(query);
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("ht : " + std::to_string(ht));
- if (ht == CABLEMODEM or ht == EMTA) {
- mac = getMacFromPacket(query);
- }
- if (ht == CABLEMODEM) {
- std::string file = mac + ".bin";
- isc::util::str::lowercase(file);
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("file : " + file);
- strcpy((char*)ufile_name, file.c_str());
- response->setFile(ufile_name, strlen((char *)ufile_name));
- std::map<std::string,std::string>::iterator it = option122_map.find(mac);
- if (it != option122_map.end()) {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("cablemodem " + mac + " found for MTA Activation on " + option122_map[mac]);
- OptionPtr option1(new Option(Option::V4, 122));
-
- Option4AddrLstPtr opt_server(new Option4AddrLst(1));
- opt_server->setAddress(isc::asiolink::IOAddress("255.255.255.255"));//option122_map[mac]));
-
- OptionStringPtr opt_basic1(new OptionString(Option::V4, 6, "BASIC.1"));
-
- option1->addOption(opt_server);
- option1->addOption(opt_basic1);
-
- response->addOption(option1);
- } else {
- LOG_INFO(runscript_logger, FLOWDAT_DEBUG_STRING).arg("cablemodem " + mac + " not found for MTA Activation");
- }
- }
- if (ht == EMTA) {
- std::string file = mac + ".mta.bin";
- isc::util::str::lowercase(file);
- std::map<std::string,std::string>::iterator it = option122_map.find(mac);
- }
- return 0;
- }
- // @TODO: Implementar para DHCPv6
- /* IPv6 callouts */
- int pkt6_receive(CalloutHandle& handle) {
- std::vector<std::string> env;
- Pkt6Ptr query;
- handle.getArgument("query6", query);
-
- // std::string mac = getMacFromPacket(query);
- // std::string class_map = conn->executeQuery("SELECT state FROM fd3_dhcp.host WHERE mac=" + string(mac));
- // cm_map[mac] = class_map;
-
- return 0;
- }
- } // end extern "C"
|