运行参数:./snmp_proxy 161 192.168.5.74 161 #./snmp_proxy [本地端口] [转发目的IP] [转发目的Port]
程序分析:
if (argc == 4){ };else (); //解析命令行,得到listern端口及forward的IP/port
//创建两个udp socket,得到描述符
sock_recv = socket(AF_INET, SOCK_DGRAM, 0);
sock_send = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
//设置sock_send的状态选项
if( setsockopt(sock_send,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)) <0 )();
//清空监听,转发套接字结构体
memset((void *)&listen,0,sizeof(listen));
memset((void *)&forward,0,sizeof(forward));
/*
struct sockaddr_in listen,forward;
*/
//初始化listen结构体的本地IP及port
listen.sin_family = AF_INET;
listen.sin_port = htons(listenport);
listen.sin_addr.s_addr = htonl(INADDR_ANY);
//初始化forward(转发结构体)的IP及port,由命令行输入得到
forward.sin_family = AF_INET;
forward.sin_port = htons(forwardport);
if(inet_pton(AF_INET,argv[2],&forward.sin_addr) != 1 )(); //字符转网络地址,存在forward.sin_addr
//绑定listen的ip,port到sock_recv套接字
if (bind(sock_recv, (struct sockaddr *)&listen, sizeof(struct sockaddr_in)) == -1)
{exit(0)};
//一个循环体,接受管理机发送的snmp包,解析包,转发
while(1)
{
;
}
//清空sockaddr_in及snmp_packet结构体,获取其len
fromlen = tolen = sizeof(struct sockaddr_in);
memset(&from, 0, sizeof(from));
memset(&to, 0, sizeof(to));
memset(recv_buf,0,sizeof(recv_buf)); //nsigned char
memset(send_buf,0,sizeof(send_buf));
memset(&snmp,0,sizeof(struct snmp_packet));
//调用recvfromto不断接受数据包
int recvfromto(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen,
struct sockaddr *to, socklen_t *tolen)
{break;}
/*
参数:
s是sock_recv套接字描符
buf是recv_buf保存接受到的字符
len是sizeof(recv_buf)字符len
......
*/
//from,to内容暂时为空,判断from,to空间足够大,从s套接字里获取及ip/port
if (to) {
struct sockaddr_in si;
socklen_t l = sizeof(si);
((struct sockaddr_in *)to)->sin_family = AF_INET;
((struct sockaddr_in *)to)->sin_port = 0;