diff --git a/src/ac/Makefile b/src/ac/Makefile index 56899662..6c735dd8 100644 --- a/src/ac/Makefile +++ b/src/ac/Makefile @@ -16,6 +16,7 @@ CFLAGS += -Werror -g -O0 -D_REENTRANT -DIPV6 -I/usr/local/include -I../ -DSYS_AR LIBS+=-lcapwap LIBS+=-lcisco +LIBS+=-lfortinet LIBS+=-lcipwap LIBS+=-lcapwap80211 LIBS+=-lcw diff --git a/src/ac/conf.c b/src/ac/conf.c index 86fcdfb2..4b62b592 100644 --- a/src/ac/conf.c +++ b/src/ac/conf.c @@ -141,12 +141,13 @@ struct mod_ac * conf_mods[10]; static int init_mods() { - + conf_mods[0]=modload_ac("cisco"); - conf_mods[1]=modload_ac("cipwap"); - conf_mods[2]=modload_ac("capwap"); - conf_mods[3]=modload_ac("capwap80211"); - conf_mods[4]=NULL; + conf_mods[1]=modload_ac("fortinet"); + conf_mods[2]=modload_ac("cipwap"); + conf_mods[3]=modload_ac("capwap"); + conf_mods[4]=modload_ac("capwap80211"); + conf_mods[5]=NULL; diff --git a/src/mod/Makefile b/src/mod/Makefile index 21043b09..1274a77d 100644 --- a/src/mod/Makefile +++ b/src/mod/Makefile @@ -4,6 +4,7 @@ all: $(MAKE) -C capwap80211 $(MAKE) -C cipwap $(MAKE) -C cisco + $(MAKE) -C fortinet $(CC) -c modload_ac.c -I../ $(CC) -c modload_wtp.c -I../ @@ -12,4 +13,5 @@ clean: $(MAKE) -C capwap80211 clean $(MAKE) -C cipwap clean $(MAKE) -C cisco clean + $(MAKE) -C fortinet clean rm *.o diff --git a/src/mod/fortinet/Makefile b/src/mod/fortinet/Makefile new file mode 100644 index 00000000..c4559bb7 --- /dev/null +++ b/src/mod/fortinet/Makefile @@ -0,0 +1,21 @@ + +OBJS=\ + mod_fortinet_ac.o \ + mod_fortinet_wtp.o \ + fortinet_actions_ac.o \ + fortinet_actions_wtp.o \ +# cisco_out_ap_timesync.o \ +# cisco_in_wtp_descriptor.o \ +# cisco_out_ac_descriptor.o \ +# cisco_out_wtp_descriptor.o \ +# cisco_in_ac_descriptor.o\ +# cisco80211.o \ +# cisco_in_radio_administrative_state.o \ +# cisco_out_board_data_options.o + + +NAME=libfortinet.a + +include ../Mod.mak + + diff --git a/src/mod/fortinet/fortinet.h b/src/mod/fortinet/fortinet.h new file mode 100644 index 00000000..fd913b1e --- /dev/null +++ b/src/mod/fortinet/fortinet.h @@ -0,0 +1,29 @@ +#ifndef __FORTINET_H +#define __FORTINET_H + +#include "cw/conn.h" +#include "cw/action.h" + +#if 0 +extern int cisco_out_ap_timesync(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); +extern int cisco_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len, struct sockaddr *from); +extern int cisco_out_ac_descriptor(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); +extern int cisco_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); +extern int cisco_out_board_data_options(struct conn *conn, struct cw_action_out *a, + uint8_t * dst); + + + +extern int cisco_in_ac_descriptor(struct conn *conn, struct cw_action_in *a, + uint8_t * data, int len, struct sockaddr *from); + +extern int cisco_in_radio_administrative_state_wtp(struct conn *conn, + struct cw_action_in *a, uint8_t * data, + int len, struct sockaddr *from); +#endif + +#endif diff --git a/src/mod/fortinet/fortinet_actions_ac.c b/src/mod/fortinet/fortinet_actions_ac.c new file mode 100644 index 00000000..eb36533e --- /dev/null +++ b/src/mod/fortinet/fortinet_actions_ac.c @@ -0,0 +1,326 @@ +/* + This file is part of libcapwap. + + libcapwap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libcapwap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + +*/ + + +#include "cw/capwap.h" +#include "cw/cipwap.h" + +#include "cw/action.h" +#include "cw/capwap_items.h" +#include "cw/strheap.h" +#include "cw/radio.h" +#include "cw/capwap_cisco.h" +#include "cw/capwap80211.h" + +#include "mod_fortinet.h" +#include "fortinet.h" + +static cw_action_in_t actions_in[] = { + + + /* -------------------------------------------------------- + * Discovery Resquest + */ + + /* Message Discovery Request */ + { + .capwap_state = CW_STATE_DISCOVERY, + .msg_id = CW_MSG_DISCOVERY_REQUEST, + .end = cw_in_check_disc_req + } + , +#if 0 + /* Element WTP Descriptor */ + { + .capwap_state = CW_STATE_DISCOVERY, + .msg_id = CW_MSG_DISCOVERY_REQUEST, + .elem_id = CW_ELEM_WTP_DESCRIPTOR, + .start = cisco_in_wtp_descriptor, + .item_id = "wtp_descriptor", + .mand = 1, + } + , + + /* Element Cisco RAD Name */ + { + .capwap_state = CW_STATE_DISCOVERY, + .msg_id = CW_MSG_DISCOVERY_REQUEST, + .vendor_id = CW_VENDOR_ID_CISCO, + .elem_id = CW_CISCO_RAD_NAME, + .start=cw_in_generic2, + .item_id = "wtp_name", + .min_len=1, + .max_len=512, + .mand=1 + } + , + + + + + + /* -------------------------------------------------------- + * Discovery Resquest + */ + + /* WTP Descriptor - Join Request */ + { + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_WTP_DESCRIPTOR, + .start = cisco_in_wtp_descriptor, + .item_id = "wtp_descriptor", + .mand = 1, + } + , + + /* Session ID - Join Request */ + { + /* Cisco uses 4 byte session ids */ + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_SESSION_ID, + .start = cw_in_generic2, + .item_id = CW_ITEM_SESSION_ID, + .mand = 1, + .min_len = 4, + .max_len = 16 + } + , + + /* Local IPv4 Address - Join Request */ + { + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_WTP_IPV4_IP_ADDRESS, + .item_id = CW_ITEM_CAPWAP_LOCAL_IP_ADDRESS, + .start = cw_in_capwap_local_ipv4_address, + .mand = 1, + .min_len = 4, + .max_len = 4 + } + , + + /* Local IPv6 Address - Join Request */ + { + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_WTP_IPV6_IP_ADDRESS, + .item_id = CW_ITEM_CAPWAP_LOCAL_IP_ADDRESS, + .start = cw_in_capwap_local_ipv4_address, + .mand = 1, + .min_len = 16, + .max_len = 16 + } + , + + /* ECN Support - Join Request */ + { + /* Cisco (using draft 7) does nothing know + * about ECN support, so make it non-mandatory */ + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_ECN_SUPPORT, + .item_id = CW_ITEM_ECN_SUPPORT, + .start = cw_in_generic2, + .mand = 0, + .min_len = 1, + .max_len = 1 + } + , + + + /* -------------------------------------------------------- + * Configuration Status Request + */ + + /* AC Name - Config Status Request */ + { + /* We have to deal with zero-length strings */ + .capwap_state = CW_STATE_CONFIGURE, + .msg_id = CW_MSG_CONFIGURATION_STATUS_REQUEST, + .elem_id = CW_ELEM_AC_NAME, + .item_id = CW_ITEM_AC_NAME, + .start = cw_in_generic2, + .min_len = 0, + .max_len = 512, + .mand = 1 + + } + , + + +#endif + /* End of list */ + {0, 0} +}; + + +static cw_action_out_t actions_out[]={ + + /* -------------------------------------------------------- + * Discovery Response + */ + +#if 0 + /* Cisco AP Timesync - Discovery Request + * Important to get the WTP a DTLS connection established + */ + { + .msg_id = CW_MSG_DISCOVERY_RESPONSE, + .item_id = CW_ITEM_AC_TIMESTAMP, + .vendor_id = CW_VENDOR_ID_CISCO, + .elem_id = CW_CISCO_AP_TIMESYNC, + .out = cisco_out_ap_timesync, + .mand = 1 + } + , + /* AC Descriptor - Discovery Response */ + { + .msg_id = CW_MSG_DISCOVERY_RESPONSE, + .item_id = CW_ITEM_AC_DESCRIPTOR, + .elem_id = CW_ELEM_AC_DESCRIPTOR, + .out = cisco_out_ac_descriptor, + .mand = 1 + } + , + + + /* AC Descriptor - Join Response */ + { + .msg_id = CW_MSG_JOIN_RESPONSE, + .item_id = CW_ITEM_AC_DESCRIPTOR, + .elem_id = CW_ELEM_AC_DESCRIPTOR, + .out = cisco_out_ac_descriptor, + .mand = 1 + } + , + + + + /* ECN Support - Join Response */ + { + .msg_id = CW_MSG_JOIN_RESPONSE, + .elem_id = CW_ELEM_ECN_SUPPORT, + .item_id = CW_ITEM_ECN_SUPPORT + } + , + + /* -------------------------------------------------------- + * Echo Response + */ + /* AP Time Sync - Echo Response */ + { + .msg_id = CW_MSG_ECHO_RESPONSE, + .vendor_id = CW_VENDOR_ID_CISCO, + .item_id = CW_ITEM_AC_TIMESTAMP, + .elem_id = CW_CISCO_AP_TIMESYNC, + .out = cisco_out_ap_timesync, + .mand = 1 + } + , +#endif + {0,0} + +}; + +static cw_action_in_t actions80211_in[] = { + /* -------------------------------------------------------- + * Discovery Resquest + */ + + /* 802.11 Radio Inmformation - Discovery Request */ + { + /* Cisco doe't sned this message element in discovery request, + so make it non-mandatory */ + + .capwap_state = CW_STATE_DISCOVERY, + .msg_id = CW_MSG_DISCOVERY_REQUEST, + .elem_id = CW_ELEM80211_WTP_RADIO_INFORMATION, + .item_id = "radio_information", + .start = cw_in_radio_generic, + .mand = 0, + .min_len = 5, + .max_len = 5 + } + , + + +}; + + +#include "cw/item.h" + +static struct cw_itemdef _capwap_itemdefs[] = { + + {"wtp_name_cisco",CW_ITEM_NONE,MBAG_STR}, + + /* {"wtp_mac_type",CW_ITEM_NONE,MBAG_BYTE}, + {"discovery_type",CW_ITEM_NONE,MBAG_BYTE}, + {"wtp_frame_tunnel_mode",CW_ITEM_NONE,MBAG_BYTE}, +*/ {CW_ITEM_NONE} + +}; + + +#include "../modload.h" + +int fortinet_register_actions_ac(struct cw_actiondef *def) +{ + + int rc; + rc = cw_actionlist_in_register_actions(def->in, actions_in); + rc += cw_actionlist_out_register_actions(def->out, actions_out); + + rc += cw_strheap_register_strings(def->strmsg, capwap_strings_msg); + rc += cw_strheap_register_strings(def->strelem, cipwap_strings_elem); + + rc += cw_itemdefheap_register(def->items, _capwap_itemdefs); + rc += cw_itemdefheap_register(def->radioitems, capwap_radioitemdefs); + + intavltree_add(def->wbids, 0); + + + + return rc; +} + + + +int fortinet_register_actions80211_ac(struct cw_actiondef *def) +{ + + int rc; + rc=0; + rc = cw_actionlist_in_register_actions(def->in, actions80211_in); +/* rc += cw_actionlist_out_register_actions(def->out, actions_out); + + rc += cw_strheap_register_strings(def->strmsg, capwap_strings_msg); + rc += cw_strheap_register_strings(def->strelem, cipwap_strings_elem); + + rc += cw_itemdefheap_register(def->items, _capwap_itemdefs); + rc += cw_itemdefheap_register(def->radioitems, capwap_radioitemdefs); + + intavltree_add(def->wbids, 0); +*/ + + + return rc; +} + + diff --git a/src/mod/fortinet/fortinet_actions_wtp.c b/src/mod/fortinet/fortinet_actions_wtp.c new file mode 100644 index 00000000..5732ed9b --- /dev/null +++ b/src/mod/fortinet/fortinet_actions_wtp.c @@ -0,0 +1,317 @@ +/* + This file is part of libcapwap. + + libcapwap is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libcapwap is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + +*/ + + +#include "cw/cipwap.h" + +#include "cw/action.h" +#include "cw/capwap_items.h" +#include "cw/strheap.h" +#include "cw/radio.h" +#include "cw/capwap_cisco.h" +#include "cw/capwap80211.h" + +#include "mod_fortinet.h" + +#include "fortinet.h" + + +static cw_action_in_t actions_in[] = { + + /* ---------------------------------------------------------------- + * Discovery Response + */ + +#if 0 + /* AC Descriptor - Discovery Response */ + { + .capwap_state = CW_STATE_DISCOVERY, + .msg_id = CW_MSG_DISCOVERY_RESPONSE, + .elem_id = CW_ELEM_AC_DESCRIPTOR, + .item_id = CW_ITEM_AC_DESCRIPTOR, + .start = cisco_in_ac_descriptor, + .min_len = 12, + .max_len = 8192, + .mand = 1 + } + , + + + /* ---------------------------------------------------------------- + * Join Response + */ + + + /* ECN Support - Join Response */ + { + /* Make ECN Support non-mand */ + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_RESPONSE, + .elem_id = CW_ELEM_ECN_SUPPORT, + .item_id = CW_ITEM_ECN_SUPPORT, + .start = cw_in_generic2, + .mand = 0, + .min_len = 1, + .max_len = 1 + } + , + + /* AC Descriptor - Join Response */ + { + /* Cisco's AC Descriptor */ + .capwap_state = CW_STATE_JOIN, + .msg_id = CW_MSG_JOIN_RESPONSE, + .elem_id = CW_ELEM_AC_DESCRIPTOR, + .item_id = CW_ITEM_AC_DESCRIPTOR, + .start = cisco_in_ac_descriptor, + .min_len = 12, + .max_len = 8192, + .mand = 1 + } + , + + + /* ---------------------------------------------------------------- + * Configuration Update Request + */ + + /* Location Data - Conf Update Req */ + { + .capwap_state = CW_STATE_RUN, + .vendor_id = CW_VENDOR_ID_CISCO, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = LW_ELEM_LOCATION_DATA, + .item_id = CW_ITEM_LOCATION_DATA, + .start = cw_in_generic2, + .min_len = 0, + .max_len = 1024, + .mand = 0 + } + , + + /* WTP Name - Conf Update Req */ + { + .capwap_state = CW_STATE_RUN, + .vendor_id = CW_VENDOR_ID_CISCO, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_CISCO_RAD_NAME, + .item_id = CW_ITEM_WTP_NAME, + .start = cw_in_generic2, + .min_len = 0, + .max_len = 1024, + .mand = 0 + } + , + + /* Radio Admin State - Config Status Request */ + { + .capwap_state = CW_STATE_RUN, + .msg_id = CW_MSG_CONFIGURATION_UPDATE_REQUEST, + .elem_id = CW_ELEM_RADIO_ADMINISTRATIVE_STATE, + .item_id = CW_ITEM_RADIO_ADMINISTRATIVE_STATE, + .start = cisco_in_radio_administrative_state_wtp, + .mand = 1 + } + , + + +#endif + /* End of list */ + {0, 0} +}; + + +static cw_action_out_t actions_out[]={ + + /* ---------------------------------------------------------------- + * Message Discover Request + */ + +#if 0 + /* WTP Descriptor - Discovery */ + { + .msg_id = CW_MSG_DISCOVERY_REQUEST, + .elem_id = CW_ELEM_WTP_DESCRIPTOR, + .item_id = CW_ITEM_WTP_DESCRIPTOR, + .out = cisco_out_wtp_descriptor, + .mand = 1 + } + + , + + /* Cisco RAD Name (WTP Name) - Discovery */ + { + .msg_id = CW_MSG_DISCOVERY_REQUEST, + .vendor_id = CW_VENDOR_ID_CISCO, + .elem_id = CW_CISCO_RAD_NAME, + .item_id = CW_ITEM_WTP_NAME, + .out = cw_out_generic, + .get = cw_out_get_config, + .mand = 1 + } + , + + + /* ---------------------------------------------------------------- + * Message Join Rquest + */ + + /* CAPWAP Local IP Address - Join Request */ + { + /* use draft 7 elem ids */ + .msg_id = CW_MSG_JOIN_REQUEST, + .item_id = CW_ITEM_CAPWAP_LOCAL_IP_ADDRESS, + .out = cw_out_capwap_local_ip_address_7, + .mand = 1 + } + , + + /* WTP Descriptor - Join Request */ + { + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_WTP_DESCRIPTOR, + .item_id = CW_ITEM_WTP_DESCRIPTOR, + .out = cisco_out_wtp_descriptor, + .mand = 1 + } + , + + /* WTP Group Name (WTP Name) - Join Request */ + { + .msg_id = CW_MSG_JOIN_REQUEST, + .vendor_id = CW_VENDOR_ID_CISCO, + .elem_id = CW_CISCO_AP_GROUP_NAME, + .item_id = CW_ITEM_WTP_GROUP_NAME, + .out = cw_out_generic, + .get = cw_out_get_config, + .mand = 1 + } + , + + /* WTP Board Data Options - Join Request */ + { + .msg_id = CW_MSG_JOIN_REQUEST, + .vendor_id = CW_VENDOR_ID_CISCO, + .elem_id = CW_CISCO_BOARD_DATA_OPTIONS, + .item_id = CW_ITEM_CISCO_BOARD_DATA_OPTIONS, + .out = cisco_out_board_data_options, + .get = cw_out_get_config, + .mand = 1 + } + , + + + + /* ECN Support - Join Request */ + { + /* Cisco doesn't know ECN support, so we + define no output method */ + .msg_id = CW_MSG_JOIN_REQUEST, + .elem_id = CW_ELEM_ECN_SUPPORT, + .item_id = CW_ITEM_ECN_SUPPORT, + .mand = 0 + } + , + + + /* ---------------------------------------------------------------- + * Configuration Status Request + */ + { + .vendor_id = CW_VENDOR_ID_CISCO, + .msg_id = CW_MSG_CONFIGURATION_STATUS_REQUEST, + .elem_id = CW_ELEM80211_WTP_RADIO_INFORMATION, + .item_id = CW_ITEM_RADIO_CFG, + .out = cisco_out_80211_wtp_radio_cfg, + .get = cw_out_get_config, + .mand = 1 + } + , + +// {CW_MSG_CONFIGURATION_STATUS_REQUEST, CW_ITEM_RADIO_CFG, CW_VENDOR_ID_CISCO, +// CW_CISCO_AP_GROUP_NAME, NULL,cw_out_cisco_wtp_radio_cfg, cw_out_get_config, 1} +// , + + + +#endif + {0,0} + +}; + + +#include "cw/item.h" + +static struct cw_itemdef _capwap_itemdefs[] = { + + {"wtp_name_cisco",CW_ITEM_NONE,MBAG_STR}, + + /* {"wtp_mac_type",CW_ITEM_NONE,MBAG_BYTE}, + {"discovery_type",CW_ITEM_NONE,MBAG_BYTE}, + {"wtp_frame_tunnel_mode",CW_ITEM_NONE,MBAG_BYTE}, +*/ {CW_ITEM_NONE} + +}; + + +#include "../modload.h" + +int fortinet_register_actions_wtp(struct cw_actiondef *def) +{ + + int rc; + rc = cw_actionlist_in_register_actions(def->in, actions_in); + rc += cw_actionlist_out_register_actions(def->out, actions_out); + + rc += cw_strheap_register_strings(def->strmsg, capwap_strings_msg); + rc += cw_strheap_register_strings(def->strelem, cipwap_strings_elem); + + rc += cw_itemdefheap_register(def->items, _capwap_itemdefs); + rc += cw_itemdefheap_register(def->radioitems, capwap_radioitemdefs); + +// intavltree_add(def->wbids, 0); + + + + return rc; +} + + + +int fortinet_register_actions80211_wtp(struct cw_actiondef *def) +{ + + int rc; + rc=0; +// rc = cw_actionlist_in_register_actions(def->in, actions80211_in); +/* rc += cw_actionlist_out_register_actions(def->out, actions_out); + + rc += cw_strheap_register_strings(def->strmsg, capwap_strings_msg); + rc += cw_strheap_register_strings(def->strelem, cipwap_strings_elem); + + rc += cw_itemdefheap_register(def->items, _capwap_itemdefs); + rc += cw_itemdefheap_register(def->radioitems, capwap_radioitemdefs); + + intavltree_add(def->wbids, 0); +*/ + + + return rc; +} + + diff --git a/src/mod/fortinet/mod_fortinet.h b/src/mod/fortinet/mod_fortinet.h new file mode 100644 index 00000000..0cdc9338 --- /dev/null +++ b/src/mod/fortinet/mod_fortinet.h @@ -0,0 +1,8 @@ +#ifndef __MOD_FORTINET_H +#define __MOD_FORTINET_H + +struct mod_ac * mod_fortinet_ac(); +struct mod_ac * mod_fortinet_wtp(); + + +#endif diff --git a/src/mod/fortinet/mod_fortinet_ac.c b/src/mod/fortinet/mod_fortinet_ac.c new file mode 100644 index 00000000..ce9ad47e --- /dev/null +++ b/src/mod/fortinet/mod_fortinet_ac.c @@ -0,0 +1,121 @@ + +#include "cw/cw.h" +#include "cw/mod.h" +#include "cw/log.h" +#include "cw/dbg.h" + +#include "cw/action.h" + +#include "mod_fortinet.h" +#include "../modload.h" + +#include "cw/vendors.h" + + +extern int fortinet_register_actions80211_ac(struct cw_actiondef *def); +extern int fortinet_register_actions_ac(struct cw_actiondef *def); + +static int register_actions(struct cw_actiondef *actions, int mode) +{ + switch (mode) { + case MOD_MODE_CAPWAP: + { + + struct mod_ac *cmod = modload_ac("capwap"); + if (!cmod) { + cw_log(LOG_ERR, + "Can't initialize mod_fortinet, failed to load base mod mod_capwap"); + return 1; + } + cmod->register_actions(actions, MOD_MODE_CAPWAP); + int rc = fortinet_register_actions_ac(actions); + cw_dbg(DBG_INFO, "Initialized mod fortinet with %d actions", rc); + return 0; + } + case MOD_MODE_BINDINGS: + { + struct mod_ac *cmod = modload_ac("capwap80211"); + if (!cmod) { + cw_log(LOG_ERR, + "Can't initialize mod_fortinet, failed to load base mod mod_capwap80211"); + return 1; + } + cmod->register_actions(actions, MOD_MODE_BINDINGS); + int rc = fortinet_register_actions80211_ac(actions); + cw_dbg(DBG_INFO, "Initialized mod_fortinet 80211 with %d actions", rc); + return 0; + } + + + } + + + return 0; + + +} + + + +static int init() +{ + cw_dbg(DBG_INFO, "Initialiazing mod_fortineto ..."); +// struct mod_ac *cmod = modload_ac("capwap"); + return 1; +} + + +static int detect(struct conn *conn, const uint8_t * rawmsg, int rawlen, int elems_len, + struct sockaddr *from, int mode) +{ + + + int offset = cw_get_hdr_msg_offset(rawmsg); + const uint8_t *msg_ptr = rawmsg + offset; + + const uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr); + const uint8_t *elem; + + + /* To detect a Fortinet AP we look for any vendor + * specific payload Fortinet identifier */ + cw_foreach_elem(elem, elems_ptr, elems_len) { + int id = cw_get_elem_id(elem); + if (id == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) { + uint32_t vendor_id = cw_get_dword(cw_get_elem_data(elem)); + if (vendor_id == CW_VENDOR_ID_FORTINET) { + // conn->actions = &actions; + if (mode == MOD_MODE_CAPWAP) { + cw_dbg(DBG_MOD, "Fortinet capwap detected: yes"); + } else { + cw_dbg(DBG_MOD, "Fortinet bindings detected: yes"); + } + + return 1; + + } + + } + + } + + if (mode == MOD_MODE_CAPWAP) { + cw_dbg(DBG_MOD, "Fortinet capwap detected: no"); + } else { + cw_dbg(DBG_MOD, "Fortinet bindings detected: no"); + } + + return 0; +} + +static struct mod_ac capwap_ac = { + .name = "fortinet", + .init = init, + .detect = detect, + .register_actions = register_actions +}; + +struct mod_ac *mod_fortinet_ac() +{ + return &capwap_ac; +}; diff --git a/src/mod/fortinet/mod_fortinet_wtp.c b/src/mod/fortinet/mod_fortinet_wtp.c new file mode 100644 index 00000000..6eb6d793 --- /dev/null +++ b/src/mod/fortinet/mod_fortinet_wtp.c @@ -0,0 +1,167 @@ + +#include "cw/cw.h" +#include "cw/mod.h" +#include "cw/log.h" +#include "cw/dbg.h" +#include "cw/capwap_items.h" + +#include "cw/action.h" + +#include "mod_fortinet.h" +#include "../modload.h" + +#include "cw/vendors.h" + +extern int cisco_register_actions80211_wtp(struct cw_actiondef *def); +extern int cisco_register_actions_wtp(struct cw_actiondef *def); + +static int register_actions(struct cw_actiondef *actions, int mode) +{ + switch (mode) { + case MOD_MODE_CAPWAP: + { + + struct mod_wtp *cmod = modload_wtp("capwap"); + if (!cmod) { + cw_log(LOG_ERR, + "Can't initialize mod_fortinet, failed to load base mod mod_capwap"); + return 1; + } + + cmod->register_actions(actions, MOD_MODE_CAPWAP); + + int rc = cisco_register_actions_wtp(actions); + + + cw_dbg(DBG_INFO, "Initialized mod_fortinet with %d actions", rc); + return rc; + } + case MOD_MODE_BINDINGS: + { + struct mod_ac *cmod = modload_wtp("capwap80211"); + if (!cmod) { + cw_log(LOG_ERR, + "Can't initialize mod_fortinet, failed to load base mod mod_capwap80211"); + return 1; + } + cmod->register_actions(actions, MOD_MODE_BINDINGS); + int rc = cisco_register_actions80211_wtp(actions); + cw_dbg(DBG_INFO, "Initialized mod_fortinet 80211 with %d actions", rc); + return 0; + } + + + } + + + return 0; + + +} + +#include "cw/capwap_items.h" +mbag_t cisco_config_wtp; + + +static int init() +{ + cw_dbg(DBG_INFO, "Initialiazing mod_fortinet ..."); + +#if 0 +//ALG + cisco_config_wtp = mbag_create(); + + bstrv_t v; + v = bstrv_create_from_str(CW_VENDOR_ID_CISCO,".x01000000"); + mbag_set_bstr16(cisco_config_wtp,CW_ITEM_WTP_HARDWARE_VERSION,v); + + v = bstrv_create_from_str(CW_VENDOR_ID_CISCO,".x08007900"); + mbag_set_bstr16(cisco_config_wtp,CW_ITEM_WTP_SOFTWARE_VERSION,v); + + v = bstrv_create_from_str(CW_VENDOR_ID_CISCO,".x0C030800"); + mbag_set_bstr16(cisco_config_wtp,CW_ITEM_WTP_BOOTLOADER_VERSION,v); + +#endif +// struct mod_ac *cmod = modload_ac("capwap"); + return 1; +} + +static int init_config(mbag_t config) +{ +#if 0 + bstr16_t gname = mbag_get_bstr16(config,CW_ITEM_WTP_GROUP_NAME,NULL); + if (!gname){ + gname = bstr16_create_from_str("Entangled"); + mbag_set_bstr16(config,CW_ITEM_WTP_GROUP_NAME,gname); + } + + + mbag_t board_data = mbag_get_mbag_c(config,CW_ITEM_WTP_BOARD_DATA,mbag_create); + + mbag_set_dword(board_data, CW_ITEM_WTP_BOARD_VENDOR,CW_VENDOR_ID_CISCO); + + mbag_set_bstr16(board_data, CW_ITEM_WTP_BOARD_MODELNO,bstr16_create_from_str("AIR-LAP1131AG-E-K9")); + mbag_set_bstr16(board_data, CW_ITEM_WTP_BOARD_SERIALNO,bstr16_create_from_str("FCZ1441Q0XZ")); + mbag_set_bstr16(board_data, CW_ITEM_WTP_BOARD_ID,bstr16_create_from_cfgstr(".x0000")); + mbag_set_bstr16(board_data, CW_ITEM_WTP_BOARD_REVISION,bstr16_create_from_cfgstr(".x4230")); +// "F8 66 F2 A3 42 FC" +#endif + return 1; +} + + +static int detect(struct conn *conn, const uint8_t * rawmsg, int rawlen, int elems_len, + struct sockaddr *from, int mode) +{ + + + int offset = cw_get_hdr_msg_offset(rawmsg); + const uint8_t *msg_ptr = rawmsg + offset; + + const uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr); + const uint8_t *elem; + + + /* To detect a Fortinet AP we look for any vendor + * specific payload Fortinet identifier */ + cw_foreach_elem(elem, elems_ptr, elems_len) { + int id = cw_get_elem_id(elem); + if (id == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) { + uint32_t vendor_id = cw_get_dword(cw_get_elem_data(elem)); + if (vendor_id == CW_VENDOR_ID_FORTINET) { + // conn->actions = &actions; + if (mode == MOD_MODE_CAPWAP) { + cw_dbg(DBG_MOD, "Fortinet capwap detected: yes"); + } else { + cw_dbg(DBG_MOD, "Fortinet bindings detected: yes"); + } + + return 1; + + } + + } + + } + + if (mode == MOD_MODE_CAPWAP) { + cw_dbg(DBG_MOD, "Fortinet capwap detected: no"); + } else { + cw_dbg(DBG_MOD, "Fortinet bindings detected: no"); + } + + return 0; +} + +static struct mod_ac fortinet_wtp = { + .name = "fortinet", + .init = init, + .init_config = init_config, + .detect = detect, + .register_actions = register_actions +}; + +struct mod_ac *mod_fortinet_wtp() +{ + return &fortinet_wtp; +}; diff --git a/src/mod/modload.h b/src/mod/modload.h index 5b2f2576..82452c10 100644 --- a/src/mod/modload.h +++ b/src/mod/modload.h @@ -9,9 +9,10 @@ struct mod_wtp * modload_wtp(const char *name); #include "cipwap/mod_cipwap.h" #include "capwap/mod_capwap.h" #include "cisco/mod_cisco.h" +#include "fortinet/mod_fortinet.h" #include "capwap80211/mod_capwap80211.h" -#define MODS_AC { mod_capwap_ac,mod_cipwap_ac, mod_cisco_ac, mod_capwap80211_ac, NULL } -#define MODS_WTP { mod_capwap_wtp,mod_cisco_wtp, mod_capwap80211_wtp, NULL } +#define MODS_AC { mod_capwap_ac, mod_cipwap_ac, mod_cisco_ac, mod_capwap80211_ac, mod_fortinet_ac, NULL } +#define MODS_WTP { mod_capwap_wtp, mod_cisco_wtp, mod_capwap80211_wtp, mod_fortinet_wtp, NULL }