是否可以通过udp / snmp发送多少个字符?

我正在尝试通过UDP / SNMP从服务器向客户端发送字符串。 但是,如果我将长度为86的字符串复制到pdu packet->value_value一切正常,我在客户端获取字符串。 如果我只在字符串中添加一个char,则长度为87 ,数据包无法传递给客户端。 数据包大小正确提升。 是否可以发送多少个字符? 我的数据包小于1500。

此代码段显示了如何将字符串复制到packet->value_value

 value_value = "asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd asd as"; printf("String length: %d\n",strlen(value_value)); // 86 OK, 87or greater NOK packet->value_length = strlen(value_value); packet->value_value = malloc(packet->value_length); strcpy(packet->value_value, value_value); 

对于某些信息,这里是一个终端输出,其中包含有关数据包长度的更多信息

字符串长度为86输出

 src/agent.c:69:parse_request(): Input length=43 src/agent.c:116:perform_snmp_request(): OID is: 1.3.6.1.2.1.1.1.0 String length: 86 src/mibservice.c:90:snmpget(): packet->value_type=04 src/mibservice.c:91:snmpget(): packet->value_length=56 src/mibservice.c:93:snmpget(): packet->value_value=61 ... src/mibservice.c:93:snmpget(): packet->value_value=73 src/mibservice.c:95:snmpget(): Before packet->length=41 src/mibservice.c:97:snmpget(): After packet->length=127 src/mibservice.c:99:snmpget(): Before packet->pdu_length=28 src/mibservice.c:101:snmpget(): After packet->pdu_length=114 src/mibservice.c:103:snmpget(): Before packet->variablebindings_length=14 src/mibservice.c:105:snmpget(): After packet->variablebindings_length=100 src/mibservice.c:107:snmpget(): Before packet->varbind_length=12 src/mibservice.c:109:snmpget(): After packet->varbind_length=98 src/agent.c:96:create_response(): Output length=129 

字符串长度为87输出

 src/agent.c:69:parse_request(): Input length=43 src/agent.c:116:perform_snmp_request(): OID is: 1.3.6.1.2.1.1.1.0 String length: 87 src/mibservice.c:90:snmpget(): packet->value_type=04 src/mibservice.c:91:snmpget(): packet->value_length=57 src/mibservice.c:93:snmpget(): packet->value_value=61 ... src/mibservice.c:93:snmpget(): packet->value_value=64 src/mibservice.c:95:snmpget(): Before packet->length=41 src/mibservice.c:97:snmpget(): After packet->length=128 src/mibservice.c:99:snmpget(): Before packet->pdu_length=28 src/mibservice.c:101:snmpget(): After packet->pdu_length=115 src/mibservice.c:103:snmpget(): Before packet->variablebindings_length=14 src/mibservice.c:105:snmpget(): After packet->variablebindings_length=101 src/mibservice.c:107:snmpget(): Before packet->varbind_length=12 src/mibservice.c:109:snmpget(): After packet->varbind_length=99 src/agent.c:96:create_response(): Output length=130 

更新这是一个关于我的问题的可运行的例子。 数据包out_buf_0表示有效的SNMP数据包,可以通过UDP发送。 数据包out_buf_1out_buf_0相同,只有一个字符在结尾out_buf_0处。 此外,由于附加角色,我提高了所有长度+ 1。 为什么out_buf_1不是有效的SNMP数据包/为什么它不能通过UDP发送? 注意:SNMP请求无法在终端中显示,因为来自客户端的request idout_buf_0out_buf_1不同,请查看wireshark以查看请求/响应。

 #include  #include  #include  #include  #include  #include  #define MESSAGE_MAX_LEN 1500 /* MTU, IEEE Std 802.3TM-2015 */ #define PORT 161 /* RFC 1157 */ int out_buf_0_len = 129; /* 0x7f + 2 */ char out_buf_0[] = { 0x30, /* SNMP Packet start */ 0x7f, /* SNMP Packet length */ 0x02, 0x01, 0x00, /* Version */ 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, /* Community*/ 0xa2, /* GetResponsePDU */ 0x72, /* GetResponsePDU Length */ 0x02, 0x04, 0x2c, 0x80, 0x7e, 0x2f, /* Request id */ 0x02, 0x01, 0x00, /*Error status */ 0x02, 0x01, 0x00, /*Error index */ 0x30, /* Varbind list start */ 0x64, /* Varbind list length*/ 0x30, /* Varbind value start */ 0x62, /* Varbind value length */ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, /* OID */ 0x04, /* Value start, type octet-string*/ 0x56, /* Value length */ 0x61, 0x73, 0x64, 0x20, 0x61, /* Value */ 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73 }; int out_buf_1_len = 130; /* 0x80 + 2 */ char out_buf_1[] = { 0x30, /* SNMP Packet start */ 0x80, /* SNMP Packet length */ 0x02, 0x01, 0x00, /* Version */ 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, /* Community*/ 0xa2, /* GetResponsePDU */ 0x73, /* GetResponsePDU Length */ 0x02, 0x04, 0x2c, 0x80, 0x7e, 0x2f, /* Request id */ 0x02, 0x01, 0x00, /*Error status */ 0x02, 0x01, 0x00, /*Error index */ 0x30, /* Varbind list start */ 0x65, /* Varbind list length*/ 0x30, /* Varbind value start */ 0x63, /* Varbind value length */ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, /* OID */ 0x04, /* Value start, type octet-string*/ 0x57, /* Value length */ 0x61, 0x73, 0x64, 0x20, 0x61, /* Value */ 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64 }; int my_socket; struct sockaddr_in remote_addr; int socket_create() { printf("Create socket\n"); struct sockaddr_in socket_addr; if ((my_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("Cannot create socket. Exit.\n"); return -1; } memset((char *)&socket_addr, 0, sizeof(socket_addr)); socket_addr.sin_family = AF_INET; socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); socket_addr.sin_port = htons(PORT); if (bind(my_socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr))  0) if (sendto(my_socket, out_buf_1, out_buf_1_len, 0, (struct sockaddr *)&remote_addr, addr_len) < 0) printf("Cannot send data to destination.\n"); } } /* Disable SNMP on local machine. # systemctl stop snmpd * Execute main(): gcc .c && ./a.out * Run SNMP Request: $ snmpget -v 1 -c public 0.0.0.0:161 1.3.6.1.2.1.1.1.0 */ char in_buf[MESSAGE_MAX_LEN]; int main(int argc, char **argv) { if (socket_create() == -1) exit(2); socket_listen(in_buf); } 

包括我的SNMPv1数据包out_buf_0在内的整个帧长度是1368位, out_buf_1应该是1376位。

正如有人在评论中指出的那样,strcpy是邪恶的,不应该用于任何事情。 你的malloc实际上分配了一个小于原始数组的数组,因为你没有考虑尾随空值。 当你使用strcpy时,你用尾随的空值写过已分配数组的末尾。

由于您没有包含与数据包结构相关的代码,因此我不知道它是如何被使用的,但如果此后的任何代码需要C null终止字符串,则可能无法按预期工作。

SNMP数据包长度0x80是错误的,请参见此处

ASN.1长度字段0x80是错误的。 解码器看到你的数据包的前两个八位字节是0x30 0x80,并从0x80确定不应该有更多的八位字节。 然而,有更多的八位字节,因此它是一个无效的编码,而且还没有有效的SNMP消息。 这里的0x80对于内容并不意味着128个八位字节,这意味着你的长度字段在这个八位字节之后是0x80&~0x80 = = 0个八位字节。 相反,0x81表示您的长度字段在八位字节后为0x81&~0x80 == 1,而在0x80八位字节之后表示内容长度为128。

这是SNMP数据包的样子,

 char out_buf_1[] = { 0x30, /* SNMP Packet start */ 0x81, 0x80, /* SNMP Packet length */ 0x02, 0x01, 0x00, /* Version */ 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, /* Community*/ 0xa2, /* GetResponsePDU */ 0x73, /* GetResponsePDU Length */ 0x02, 0x04, 0x2c, 0x80, 0x7e, 0x2f, /* Request id */ 0x02, 0x01, 0x00, /*Error status */ 0x02, 0x01, 0x00, /*Error index */ 0x30, /* Varbind list start */ 0x65, /* Varbind list length*/ 0x30, /* Varbind value start */ 0x63, /* Varbind value length */ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, /* OID */ 0x04, /* Value start, type octet-string*/ 0x57, /* Value length */ 0x61, 0x73, 0x64, 0x20, 0x61, /* Value */ 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64, 0x20, 0x61, 0x73, 0x64 };