【发布时间】:2015-02-20 08:35:43
【问题描述】:
我编写了一个简单的 C 函数,它连接到交换机(通过使用 Telnet 套接字),并且 运行各种cli命令并退出。 我想使用 Cisco 和 Edge-Core 交换机。
使用 Edge-Core 交换机,此功能可以正常工作,但在 Cisco 中不起作用,因为它挂在“登录”过程中。
这里是提到的 C 函数:
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
char *telnet_switch( char *switch_ip, char *cmd, char cmd_out[] ) {
char buf[5000];
int sock;
int bytes;
struct sockaddr_in sw;
sock = socket( PF_INET, SOCK_STREAM, 0 );
sw.sin_family = AF_INET;
sw.sin_port = htons( 23 );
sw.sin_addr.s_addr = inet_addr( switch_ip );
if ( sock < 0 ) {
perror("Socket creation error!");
return (cmd_out);
}
if ( connect( sock, (struct sockaddr *) &sw, sizeof( sw ) ) < 0 ) {
perror("Connect process error!");
return (cmd_out);
}
send( sock, "admin\n\r", 7, 0 );
usleep(250000);
bytes = recv( sock, buf, sizeof( buf ), 0 );
printf("Bytes: %d\n", bytes); // DEBUG MESSAGE 1.
send( sock, "test\n\r", 6, 0 );
usleep(250000);
bytes = recv( sock, buf, sizeof( buf ), 0 );
printf("Bytes: %d\n", bytes); // DEBUG MESSAGE 2.
send( sock, cmd, strlen( cmd ), 0 );
send( sock, "\n\r", 2, 0 );
memset( buf, 0, sizeof( buf ) );
memset( cmd_out, 0, sizeof( cmd_out ) );
usleep(250000);
recv( sock, buf, sizeof( buf ), 0 );
sprintf( cmd_out, buf );
close( sock );
return (cmd_out);
}
以及主要(测试)功能:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *telnet_switch( char *, char *, char [] );
int main( int argc, char **argv ) {
char cmd_out[1000000];
telnet_switch("192.168.16.18", "?", cmd_out);
printf("%s\n", cmd_out);
exit (0);
}
Edge-Core 开关处的输出:
szpal@testnms:~/tmp$ ./test
Bytes: 35
Bytes: 110
edge-core:/>
General Commands:
-----------------
Help/?: Get help on a group or a specific command
Up : Move one command level up
Logout: Exit CLI
Command Groups:
---------------
System : System settings and reset options
IP : IP configuration and Ping
Port : Port management
MAC : MAC address table
VLAN : Virtual LAN
...
VCL : VLAN Control List
Debug : Switch debug facilities
Type '<group>' to enter command group, e.g. 'port'.
Type '<group> ?' to get list of group commands, e.g. 'port ?'.
Type '<command> ?' to get help on a command, e.g. 'port mode ?'.
Commands may be abbreviated, e.g. 'por co' instead of 'port configuration'.
edge-core:/>
Nyomjon meg egy billentyűt...
以及 Cisco 交换机的输出:
szpal@testnms:~/tmp$ ./test
Bytes: 12
所以我不知道为什么它无法登录到 Cisco 交换机,我尝试增加 'usleep' 超时,我尝试了 '\r\n' 字符但没有成功。
有解决这个问题的Debug进程吗?
【问题讨论】:
-
您从未实现过任何协议。您不能调用
recv并期望它接收完整的telnet 协议或登录消息。这是一个 TCP 功能。如果您需要阅读直到出现提示或阅读一些行数或其他内容,则需要编写代码来执行此操作。您不能将 sleeps 用作同步功能——它永远不会可靠。你还应该至少看看你收到了什么 12 个字节。 -
您可以尝试打印从 Cisco 路由器返回的字节吗? .您可以将此与使用常规 telnet 客户端接收到的字节进行比较。它应该给你一个线索。另外,这是哪个路由器/交换机?一些开关倾向于在准备好接收身份验证请求之前提供更多数据。我建议将整个内容放在一个选择循环中并继续阅读套接字。
-
0xFFFD 0xFFFD 0xFFFD 0xFFFD 0x020 0xFFFD 0xFFFD 0x023 0xFFFD 0xFFFD 0x027
这是 Cisco SG220-26 交换机。 -
如果您使用常规的 telnet 客户端会怎样?连接后立即获得的 o/p 是什么?如果您与之相比,这个o / p有什么意义吗?此外,将逻辑放在一个选择循环中并尝试在 recv 中等待,看看在连接超时时是否获得更多数据。如果服务器正在等待任何特殊序列,它将给出一个想法。
-
@joe,我会尽快尝试..