📄 tlv.c
字号:
/*
* LICENSE NOTICE.
*
* Use of the Microsoft Windows Rally Development Kit is covered under
* the Microsoft Windows Rally Development Kit License Agreement,
* which is provided within the Microsoft Windows Rally Development
* Kit or at http://www.microsoft.com/whdc/rally/rallykit.mspx. If you
* want a license from Microsoft to use the software in the Microsoft
* Windows Rally Development Kit, you must (1) complete the designated
* "licensee" information in the Windows Rally Development Kit License
* Agreement, and (2) sign and return the Agreement AS IS to Microsoft
* at the address provided in the Agreement.
*/
/*
* Copyright (c) Microsoft Corporation 2005. All rights reserved.
* This software is provided with NO WARRANTY.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "globals.h"
#include "tlv.h"
/************************* E X T E R N A L S f o r T L V _ G E T _ F N s ***************************/
#define TLVDEF(_type, _name, _repeat, _number, _access, _inHello) \
extern int get_ ## _name ();
#include "tlvdef.h"
#undef TLVDEF
static int
write_lg_icon_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
lg_icon_t* icon = (lg_icon_t*) data;
int num_read;
off_t curOffset;
int remaining;
IF_TRACED(TRC_TLVINFO)
printf("write-lg_icon: tlvnum:%d isHello:%s isLarge:%s offset:" FMT_SIZET "\n",
number, isHello==TRUE?"true":"false", isLarge==TRUE?"true":"false", offset);
END_TRACE
if (icon->fd_icon < 0)
{
DEBUG({printf("write-lg_icon: No icon FD, nothing written\n");})
return 0; // No jumbo icon was correctly declared.
}
if (isHello==TRUE)
{
/* Jumbo icon - always force to a large-TLV */
/* write header in Hello's small-TLV format */
*buf++ = (uint8_t)number;
*buf = (uint8_t)0;
close(icon->fd_icon);
icon->fd_icon = -1;
return 2;
}
/* try to read as much as will fit in the buffer, allowing 2 bytes for the header */
curOffset = lseek(icon->fd_icon, (off_t) offset, SEEK_SET);
if (curOffset != (off_t)offset)
{
/* the seek on the icon file failed... whine and cleanup the buffer */
warn("write_lg_icon_t: lseek to byte " FMT_SIZET " on the iconfile FAILED, errno: %s",
offset, strerror(errno));
close(icon->fd_icon);
icon->fd_icon = -1;
return 0;
}
num_read = read(icon->fd_icon, buf+2, bytes_free-2);
if (num_read < 0)
{
/* the read of the icon failed... whine and cleanup the buffer */
warn("write_lg_icon_t: read of the jumbo iconfile FAILED, errno: %s", strerror(errno));
close(icon->fd_icon);
icon->fd_icon = -1;
return 0;
}
/* adjust the number, length and/or the flag appropriately */
/* write header in QueryLargeTlvResp large-TLV format */
remaining = read(icon->fd_icon, buf, 1); // Check for more...
IF_TRACED(TRC_TLVINFO)
printf("writing jumbo-tlv of %d bytes, with %s remaining\n",
num_read+2, remaining<=0?"none":"some");
END_TRACE
if (remaining <= 0)
{
/* EOF or error - no more to read, so more -flag is 0 */
/* replace: *(uint16_t*)buf = htons((uint16_t)num_read); with: */
g_short_reorder_buffer = htons((uint16_t)num_read);
memcpy(buf, &g_short_reorder_buffer, 2);
} else {
/* found at least one more byte... set the more-flag */
/* replace: *(uint16_t*)buf = htons((uint16_t)(0x8000) | (uint16_t)num_read); with: */
g_short_reorder_buffer = htons((uint16_t)(0x8000) | (uint16_t)num_read);
memcpy(buf, &g_short_reorder_buffer, 2);
}
IF_TRACED(TRC_TLVINFO)
printf("txbuf: %02X, %02X, %02X, %02X\n",buf[0],buf[1],buf[2],buf[3]);
END_TRACE
close(icon->fd_icon);
icon->fd_icon = -1;
return num_read + 2;
}
static int
write_icon_file_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
icon_file_t* icon = (icon_file_t*) data;
int num_read;
off_t curOffset;
IF_TRACED(TRC_TLVINFO)
printf("write-icon-file: tlvnum:%d isHello:%s isLarge:%s offset:" FMT_SIZET "\n",
number, isHello==TRUE?"true":"false", isLarge==TRUE?"true":"false", offset);
END_TRACE
if (icon->fd_icon < 0)
{
DEBUG({printf("write-icon-file: No icon FD, nothing written\n");})
return 0; // No iconfile was correctly declared.
}
if (isHello==TRUE)
{
if ((icon->sz_iconfile > (size_t)255) || (bytes_free < 2 + (int)icon->sz_iconfile) || isLarge==TRUE)
{
IF_TRACED(TRC_TLVINFO)
printf("write_icon_file: not enuff room - bytes_free=%d, and icon_sz=" FMT_SIZET "\n",
bytes_free, icon->sz_iconfile);
printf("writing small-tlv of 0 bytes to notify of large-tlv value\n");
END_TRACE
/* Not enough room - force to a large-TLV */
/* write header in Hello's small-TLV format */
*buf++ = (uint8_t)number;
*buf = (uint8_t)0;
close(icon->fd_icon);
icon->fd_icon = -1;
return 2;
}
}
/* try to read as much as will fit in the buffer, allowing 2 bytes for the header, small or large */
curOffset = lseek(icon->fd_icon, (off_t) offset, SEEK_SET);
if (curOffset != (off_t)offset)
{
/* the seek on the icon file failed... whine and cleanup the buffer */
warn("write_icon_file_t: lseek to byte " FMT_SIZET " on the iconfile FAILED, errno: %s",
offset, strerror(errno));
close(icon->fd_icon);
icon->fd_icon = -1;
return 0;
}
num_read = read(icon->fd_icon, buf+2, bytes_free-2);
if (num_read < 0)
{
/* the read of the icon failed... whine and cleanup the buffer */
warn("write_icon_file_t: read of the iconfile FAILED, errno: %s", strerror(errno));
close(icon->fd_icon);
icon->fd_icon = -1;
return 0;
}
/* adjust the number, length and/or the flag appropriately */
if (isHello==TRUE)
{
/* write header in Hello's small-TLV format */
IF_TRACED(TRC_TLVINFO)
printf("writing small-tlv of %d bytes\n",num_read+2);
END_TRACE
*buf++ = (uint8_t)number;
*buf-- = (uint8_t)num_read;
} else {
/* write header in QueryLargeTlvResp large-TLV format */
int remaining = read(icon->fd_icon, buf, 1); // Check for more...
IF_TRACED(TRC_TLVINFO)
printf("writing large-tlv of %d bytes, with %s remaining\n",
num_read+2, remaining<=0?"none":"some");
END_TRACE
if (remaining <= 0)
{
/* EOF or error - no more to read, so more -flag is 0 */
/* replace: *(uint16_t*)buf = htons((uint16_t)num_read); with: */
g_short_reorder_buffer = htons((uint16_t)num_read);
memcpy(buf, &g_short_reorder_buffer, 2);
} else {
/* found at least one more byte... set the more-flag */
/* replace: *(uint16_t*)buf = htons((uint16_t)(0x8000) | (uint16_t)num_read); with: */
g_short_reorder_buffer = htons((uint16_t)(0x8000) | (uint16_t)num_read);
memcpy(buf, &g_short_reorder_buffer, 2);
}
}
IF_TRACED(TRC_TLVINFO)
printf("txbuf: %02X, %02X, %02X, %02X\n",buf[0],buf[1],buf[2],buf[3]);
END_TRACE
close(icon->fd_icon);
icon->fd_icon = -1;
return num_read + 2;
}
static int
write_etheraddr_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
if (bytes_free < (int)(2 + sizeof(etheraddr_t)))
return 0;
IF_TRACED(TRC_TLVINFO)
dbgprintf("write_etheraddr_t(%s): addr=" ETHERADDR_FMT "\n", isLarge?"LTLV":"TLV",
ETHERADDR_PRINT(((etheraddr_t*)data)));
END_TRACE
if (isHello)
{
/* write hdr in Hello-tlv format */
*buf = (uint8_t)number;
if (isLarge)
{
*(buf+1) = 0;
return 2;
} else {
*(buf+1) = sizeof(etheraddr_t);
}
} else {
/* write in QueryLargeTlvResp LTLV format */
/* replace: *(uint16_t*)buf = htons(sizeof(etheraddr_t)); with: */
g_short_reorder_buffer = htons(sizeof(etheraddr_t));
memcpy(buf, &g_short_reorder_buffer, 2);
}
/* replace: *((etheraddr_t*)(buf+2)) = *(etheraddr_t*)data; with: */
memcpy(buf+2, data, sizeof(etheraddr_t));
return sizeof(etheraddr_t) + 2;
}
static int
write_uint8_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
if (bytes_free < (int)(2 + sizeof(uint8_t)))
return 0;
if (isHello)
{
/* write hdr in Hello-tlv format */
*buf = (uint8_t)number;
if (isLarge)
{
*(buf+1) = 0;
return 2;
} else {
*(buf+1) = sizeof(uint8_t);
}
} else {
/* write in QueryLargeTlvResp LTLV format */
/* replace: *(uint16_t*)buf = htons(sizeof(etheraddr_t)); with: */
g_short_reorder_buffer = htons(sizeof(uint8_t));
memcpy(buf, &g_short_reorder_buffer, 2);
}
*(buf+2) = *(uint8_t*)data;
return sizeof(uint8_t) + 2;
}
static int
write_uint16_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
if (bytes_free < (int)(2 + sizeof(uint16_t)))
return 0;
if (isHello)
{
/* write hdr in Hello-tlv format */
*buf = (uint8_t)number;
if (isLarge)
{
*(buf+1) = 0;
return 2;
} else {
*(buf+1) = sizeof(uint16_t);
}
} else {
/* write in QueryLargeTlvResp LTLV format */
/* replace: *(uint16_t*)buf = htons(sizeof(uint16_t)); with: */
g_short_reorder_buffer = htons(sizeof(uint16_t));
memcpy(buf, &g_short_reorder_buffer, 2);
}
/* replace: *((uint16_t*)(buf+2)) = *(uint16_t*)data; with: */
memcpy(buf+2, data, sizeof(uint16_t));
return sizeof(uint16_t) + 2;
}
static int
write_uint32_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
if (bytes_free < (int)(2 + sizeof(uint32_t)))
return 0;
if (isHello)
{
/* write hdr in Hello-tlv format */
*buf = (uint8_t)number;
if (isLarge)
{
*(buf+1) = 0;
return 2;
} else {
*(buf+1) = sizeof(uint32_t);
}
} else {
/* write in QueryLargeTlvResp LTLV format */
/* replace: *(uint16_t*)buf = htons(sizeof(uint32_t)); with: */
g_short_reorder_buffer = htons(sizeof(uint32_t));
memcpy(buf, &g_short_reorder_buffer, 2);
}
/* replace: *((uint32_t*)(buf+2)) = *(uint32_t*)data; with: */
memcpy(buf+2, data, sizeof(uint32_t));
return sizeof(uint32_t) + 2;
}
static int
write_uint64_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
if (bytes_free < (int)(2 + sizeof(uint64_t)))
return 0;
if (isHello)
{
/* write hdr in Hello-tlv format */
*buf = (uint8_t)number;
if (isLarge)
{
*(buf+1) = 0;
return 2;
} else {
*(buf+1) = sizeof(uint64_t);
}
} else {
/* write in QueryLargeTlvResp LTLV format */
/* replace: *(uint16_t*)buf = htons(sizeof(uint64_t)); with: */
g_short_reorder_buffer = htons(sizeof(uint64_t));
memcpy(buf, &g_short_reorder_buffer, 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -