Correct fragment handling when sendig fragmented packets
This commit is contained in:
parent
ae686f4634
commit
435b3f823e
@ -150,34 +150,51 @@ cw_init_capwap_packet( uint8_t * buf, int wbid ,int rid, bstr_t rmac, bstr_t wd)
|
|||||||
return hlen*4;
|
return hlen*4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a CAPWAP packet and fragment it if nececerry
|
||||||
|
* @param conn connection where to send packet over
|
||||||
|
* @param buf pointer to a buffer initialized with #cw_init_capwap_packet
|
||||||
|
* @param hlen length of header, which is the value returned by #cw_init_capwap_packet
|
||||||
|
* @param data payload
|
||||||
|
* @param len length of payload
|
||||||
|
*/
|
||||||
int cw_send_capwap_packet(struct cw_Conn * conn, uint8_t * buf, int hlen, uint8_t * data, int len)
|
int cw_send_capwap_packet(struct cw_Conn * conn, uint8_t * buf, int hlen, uint8_t * data, int len)
|
||||||
{
|
{
|
||||||
int fragoffset,mtu;
|
int fragoffset,mtu;
|
||||||
|
int fragid;
|
||||||
|
|
||||||
/* get mtu and align it to 8 */
|
/* get mtu and align it to 8 */
|
||||||
mtu = conn->mtu;
|
mtu = conn->mtu;
|
||||||
mtu &= ~3;
|
mtu &= ~3;
|
||||||
|
|
||||||
|
/* initialize fragid and fragoffset */
|
||||||
fragoffset = 0;
|
fragoffset = 0;
|
||||||
|
if (len + hlen > mtu)
|
||||||
|
fragid = conn->fragid++;
|
||||||
|
else
|
||||||
|
fragid = 0;
|
||||||
|
|
||||||
|
/* create all fragments */
|
||||||
while (len + hlen > mtu){
|
while (len + hlen > mtu){
|
||||||
memcpy(buf+hlen,data+(fragoffset*8),mtu-hlen);
|
memcpy(buf+hlen,data+(fragoffset*8),mtu-hlen);
|
||||||
len -= (mtu - hlen);
|
len -= (mtu - hlen);
|
||||||
|
|
||||||
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F,1);
|
cw_set_hdr_flags(buf,CAPWAP_FLAG_HDR_F,1);
|
||||||
cw_set_dword(buf+4, conn->fragid<<16 | fragoffset<<3 );
|
cw_set_dword(buf+4, fragid<<16 | fragoffset<<3 );
|
||||||
|
|
||||||
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,mtu,(struct sockaddr*)&conn->addr);
|
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,mtu,(struct sockaddr*)&conn->addr);
|
||||||
if (conn->write(conn,buf,mtu)<0)
|
if (conn->write(conn,buf,mtu)<0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fragoffset+=(mtu-hlen)/8;
|
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);
|
|
||||||
|
|
||||||
|
/* put rmac and wireless data only into the 1st fragment */
|
||||||
|
if (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)
|
if (fragoffset)
|
||||||
@ -187,13 +204,11 @@ int cw_send_capwap_packet(struct cw_Conn * conn, uint8_t * buf, int hlen, uint8_
|
|||||||
|
|
||||||
memcpy(buf+hlen,data+(fragoffset*8),mtu-hlen);
|
memcpy(buf+hlen,data+(fragoffset*8),mtu-hlen);
|
||||||
|
|
||||||
cw_set_dword(buf+4, conn->fragid<<16 | fragoffset<<3 );
|
cw_set_dword(buf+4, fragid<<16 | fragoffset<<3 );
|
||||||
|
|
||||||
|
|
||||||
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,len+hlen,(struct sockaddr*)&conn->addr);
|
cw_dbg_pkt(DBG_PKT_OUT,conn,buf,len+hlen,(struct sockaddr*)&conn->addr);
|
||||||
|
|
||||||
return conn->write(conn,buf,len + hlen);
|
return conn->write(conn,buf,len + hlen);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -201,7 +216,6 @@ cw_send_msg( struct cw_Conn * conn, uint8_t *msg)
|
|||||||
{
|
{
|
||||||
uint8_t buf[MAX_MTU];
|
uint8_t buf[MAX_MTU];
|
||||||
int hlen,msglen;
|
int hlen,msglen;
|
||||||
|
|
||||||
hlen = cw_init_capwap_packet(buf,1,0,NULL,NULL);
|
hlen = cw_init_capwap_packet(buf,1,0,NULL,NULL);
|
||||||
msglen = cw_get_msg_elems_len(msg) + 8;
|
msglen = cw_get_msg_elems_len(msg) + 8;
|
||||||
return cw_send_capwap_packet(conn,buf,hlen,msg,msglen);
|
return cw_send_capwap_packet(conn,buf,hlen,msg,msglen);
|
||||||
|
Loading…
Reference in New Issue
Block a user