2020-03-30 00:30:11 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2013,2020, The PLANIX Project
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
|
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
2015-04-10 17:16:33 +02:00
|
|
|
#include <errno.h>
|
|
|
|
|
2018-03-17 17:29:09 +01:00
|
|
|
|
2015-04-10 17:16:33 +02:00
|
|
|
#include "conn.h"
|
2016-03-11 22:23:00 +01:00
|
|
|
#include "cw.h"
|
2015-04-10 17:52:01 +02:00
|
|
|
#include "log.h"
|
2015-04-14 07:42:23 +02:00
|
|
|
#include "dbg.h"
|
2015-04-10 17:16:33 +02:00
|
|
|
#include "sock.h"
|
2015-04-11 19:00:51 +02:00
|
|
|
#include "timer.h"
|
2015-04-10 17:16:33 +02:00
|
|
|
|
2015-04-14 07:42:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
int conn_send_data_msg(struct cw_Conn * conn, uint8_t *rawmsg,int len)
|
2016-03-27 04:53:12 +02:00
|
|
|
{
|
|
|
|
int packetlen = len;
|
2018-03-25 10:07:39 +02:00
|
|
|
int fragoffset;
|
|
|
|
int hlen;
|
|
|
|
|
|
|
|
uint8_t * ptr;
|
|
|
|
int mtu;
|
|
|
|
|
2016-03-27 04:53:12 +02:00
|
|
|
cw_dbg_msg(DBG_MSG_OUT, conn,rawmsg, packetlen,(struct sockaddr*)&conn->addr);
|
|
|
|
|
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
ptr = rawmsg;
|
2016-03-27 04:53:12 +02:00
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
fragoffset = 0;
|
2016-03-27 04:53:12 +02:00
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
hlen = cw_get_hdr_hlen(rawmsg)*4;
|
2016-03-27 04:53:12 +02:00
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
mtu = conn->mtu;
|
2016-03-27 04:53:12 +02:00
|
|
|
|
|
|
|
while (packetlen>mtu){
|
2018-02-23 09:30:10 +01:00
|
|
|
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F,1);
|
2018-03-25 10:35:53 +02:00
|
|
|
cw_set_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
|
2016-03-27 04:53:12 +02:00
|
|
|
|
|
|
|
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,mtu,(struct sockaddr*)&conn->addr);
|
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
/* if (conn->write_data(conn,ptr,mtu)<0)*/
|
2016-03-27 04:53:12 +02:00
|
|
|
return -1;
|
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
/* // XXX Fragmentation stuff..*/
|
2016-03-27 04:53:12 +02:00
|
|
|
ptr +=mtu-hlen;
|
|
|
|
fragoffset+=(mtu-hlen)/8;
|
2015-04-14 07:42:23 +02:00
|
|
|
|
2016-03-27 04:53:12 +02:00
|
|
|
packetlen-=mtu-hlen;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (fragoffset)
|
2018-02-23 09:30:10 +01:00
|
|
|
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F | CAPWAP_FLAG_HDR_L,1);
|
2016-03-27 04:53:12 +02:00
|
|
|
else
|
2018-02-23 09:30:10 +01:00
|
|
|
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F,0);
|
2016-03-27 04:53:12 +02:00
|
|
|
|
2018-03-25 10:35:53 +02:00
|
|
|
cw_set_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
|
2016-03-27 04:53:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,packetlen,(struct sockaddr*)&conn->addr);
|
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
/*// return conn->write_data(conn,ptr,packetlen-0);*/
|
2016-03-27 04:53:12 +02:00
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
return 0;
|
2016-03-27 04:53:12 +02:00
|
|
|
}
|
2015-04-14 07:42:23 +02:00
|
|
|
|
|
|
|
|
2022-07-28 01:36:16 +02:00
|
|
|
#define MAX_MTU 9500
|
2020-04-02 07:25:56 +02:00
|
|
|
int
|
2022-08-09 22:35:47 +02:00
|
|
|
cw_send_msg( struct cw_Conn * conn, uint8_t *msg)
|
2020-04-02 07:25:56 +02:00
|
|
|
{
|
|
|
|
uint8_t buf[MAX_MTU];
|
|
|
|
int fragoffset,hlen,mtu;
|
2022-08-14 12:26:34 +02:00
|
|
|
int msglen;
|
2020-04-02 07:25:56 +02:00
|
|
|
|
|
|
|
mtu = conn->mtu;
|
|
|
|
|
|
|
|
/* align mtu to 8 */
|
|
|
|
mtu &= ~3;
|
|
|
|
|
|
|
|
/* zero the first 8 bytes */
|
|
|
|
cw_set_dword(buf + 0, 0);
|
|
|
|
cw_set_dword(buf + 4, 0);
|
|
|
|
|
|
|
|
/* unencrypted */
|
|
|
|
cw_set_hdr_preamble(buf, CAPWAP_VERSION << 4 | 0);
|
|
|
|
|
|
|
|
/* set rmac, wireless binding id, and radio id */
|
|
|
|
cw_set_hdr_rmac(buf, conn->base_rmac);
|
|
|
|
cw_set_hdr_wbid(buf, conn->wbid);
|
|
|
|
cw_set_hdr_rid(buf, 0);
|
|
|
|
|
|
|
|
|
|
|
|
fragoffset = 0;
|
|
|
|
|
|
|
|
hlen = cw_get_hdr_hlen(buf)*4;
|
|
|
|
|
2022-08-14 12:26:34 +02:00
|
|
|
//packetlen = hlen + cw_get_msg_elems_len(msg) + 8;
|
2020-04-02 07:25:56 +02:00
|
|
|
|
|
|
|
msglen = cw_get_msg_elems_len(msg) + 8;
|
|
|
|
|
|
|
|
|
|
|
|
while (msglen + hlen > mtu){
|
|
|
|
memcpy(buf+hlen,msg+(fragoffset*8),mtu-hlen);
|
|
|
|
msglen -= (mtu - hlen);
|
|
|
|
|
|
|
|
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F,1);
|
|
|
|
cw_set_dword(buf+4, conn->fragid<<16 | fragoffset<<3 );
|
|
|
|
|
|
|
|
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,mtu,(struct sockaddr*)&conn->addr);
|
|
|
|
if (conn->write(conn,buf,mtu)<0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
fragoffset+=(mtu-hlen)/8;
|
|
|
|
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_M,0);
|
|
|
|
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_W,0);
|
|
|
|
hlen = 8;
|
|
|
|
cw_set_hdr_hlen(buf,hlen/4);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fragoffset)
|
|
|
|
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F | CAPWAP_FLAG_HDR_L,1);
|
|
|
|
else
|
|
|
|
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F,0);
|
|
|
|
|
|
|
|
memcpy(buf+hlen,msg+(fragoffset*8),mtu-hlen);
|
|
|
|
|
|
|
|
cw_set_dword(buf+4, conn->fragid<<16 | fragoffset<<3 );
|
|
|
|
|
|
|
|
|
2022-07-28 01:36:16 +02:00
|
|
|
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,msglen+hlen,(struct sockaddr*)&conn->addr);
|
2020-04-02 07:25:56 +02:00
|
|
|
|
|
|
|
return conn->write(conn,buf,msglen + hlen);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-04-14 07:42:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-09 22:35:47 +02:00
|
|
|
int cw_send_request(struct cw_Conn *conn,int msg_id)
|
2015-04-10 17:16:33 +02:00
|
|
|
{
|
2018-03-25 10:07:39 +02:00
|
|
|
time_t timer;
|
|
|
|
int i;
|
|
|
|
int rc;
|
2018-03-05 12:23:16 +01:00
|
|
|
char sock_buf[SOCK_ADDR_BUFSIZE];
|
2015-04-10 17:16:33 +02:00
|
|
|
cw_init_request(conn, msg_id);
|
2022-08-17 18:41:17 +02:00
|
|
|
if ( cw_compose_message(conn, conn->req_buffer) == -1 ){
|
2016-03-05 09:03:52 +01:00
|
|
|
errno=ENOMSG;
|
|
|
|
return -1;
|
|
|
|
}
|
2020-04-03 00:44:01 +02:00
|
|
|
/* conn_send_msg(conn, conn->req_buffer);*/
|
2015-04-10 17:16:33 +02:00
|
|
|
|
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
|
|
|
|
rc=-1;
|
2015-04-10 17:16:33 +02:00
|
|
|
for (i=0; i<conn->max_retransmit && rc<0; i++){
|
2020-04-03 00:44:01 +02:00
|
|
|
conn_send_msg(conn, conn->req_buffer);
|
2015-04-11 19:00:51 +02:00
|
|
|
if ( i>0 ){
|
|
|
|
cw_log(LOG_WARNING,"Retransmitting request ... %d",i);
|
|
|
|
}
|
2018-03-25 10:07:39 +02:00
|
|
|
timer = cw_timer_start(conn->retransmit_interval);
|
2015-04-10 17:16:33 +02:00
|
|
|
while (!cw_timer_timeout(timer) && rc<0){
|
|
|
|
|
|
|
|
rc =cw_read_messages(conn);
|
|
|
|
if(rc<0){
|
|
|
|
if (errno!=EAGAIN)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if (rc<0){
|
|
|
|
if(errno!=EAGAIN)
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-04-11 19:00:51 +02:00
|
|
|
if ( rc <0 && errno != EAGAIN) {
|
2018-03-05 12:23:16 +01:00
|
|
|
cw_log(LOG_ERR,"Can't read from %s: %s",sock_addr2str(&conn->addr,sock_buf),strerror(errno));
|
2015-04-10 17:16:33 +02:00
|
|
|
}
|
2015-04-11 19:00:51 +02:00
|
|
|
if ( rc <0 && errno == EAGAIN) {
|
|
|
|
errno=ETIMEDOUT;
|
|
|
|
rc=-1;
|
|
|
|
}
|
2015-04-10 17:16:33 +02:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
2015-04-30 14:10:59 +02:00
|
|
|
|
|
|
|
|
2018-03-25 10:07:39 +02:00
|
|
|
/*// XXX find a better name for this function */
|
2022-08-09 22:35:47 +02:00
|
|
|
int cw_send_custom_request_2(struct cw_Conn *conn,int msg_id)
|
2015-04-30 14:10:59 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|