首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

3.6  基于UDP套接字的网络扫描

这一节将详细分析一个实用程序,使用UDP协议和BSD套接字API,实现简单网络管理协议(Simple Network Management ProtocolSNMP)社区名(community name)扫描。SNMP可用于获取和设置互连计算机和设备上各种类型的管理数据,具有广泛的支持。管理数据的获取和配置通过向远程主机发送封装在UDP数据报中的SNMP GetRequestSetRequest请求报文来实现。

对于SNMP GetRequest请求,源主机将请求报文发送到远程主机,远程主机接收和验证请求,并将包含应答信息的GetResponse报文封装在一个UDP数据报中发回请求方。对于SNMP SetRequeset请求,源主机将请求报文发送到远程主机,远程主机接收和验证请求,并修改相应的配置。

要获取或修改的信息在SNMP GetRequestSetRequest报文体中给出。可通过SNMP获取或修改的信息包括远程主机的主机名、IP地址配置以及统计信息。处理SNMP请求的软件称为SNMP代理。SNMP代理软件在161UDP端口上运行,并监听GetRequestSetRequest请求。SNMP代理要求收到的请求报文必须包含一个社区名且能与它已知的社区名相匹配,在SNMP请求中社区名在一定程度上起到了口令的作用,如果请求报文提供的社区名不合法,SNMP代理将忽略该请求报文。

好在大部分的SNMP代理软件在默认情况下都有一个名为public的社区名,这对于发现和枚举大量支持SNMP的设备十分有用。例3-9说明了怎样在一个完整的程序中使用UDP套接字发送和接收SNMP GetRequest请求,以获取远程主机的主机名。

3-9  SNMP扫描器(snmp1.c)

1   /*

2    * snmp1.c

3    *

4    * snmp scanner example program #1.

5    *

6    * foster <jamescfoster@gmail.com>

7    */

8

9   #include <stdio.h>

10 #include <stdlib.h>

11 #include <unistd.h>

12 #include <string.h>

13 #include <ctype.h>

14

15 #include <sys/socket.h>

16 #include <netinet/in.h>

17 #include <arpa/inet.h>

18

19 #define      SNMP1_DEF_PORT 161

20 #define     SNMP1_DEF_COMN "public"

21

22 #define      SNMP1_BUF_SIZE 0x0400

23

24 /*

25   * hexdisp()

26   *

27   *

28 */

29 void hexdisp (char *buf, int len)

30 {

31      char tmp[16];

32      int x = 0;

33      int y = 0;

34

35      printf("\n");

36

37      for(x=0; x < len; ++x)

38      {

39              tmp[x % 16] = buf[x];

40

41              if((x + 1) % 16 == 0)

42              {

43                      for(y=0; y < 16; ++y)

44                      {

45                              printf("%02X ", tmp[y] & 0xFF);

46                      }

47

48                      for(y=0; y < 16; ++y)

49                      {

50                              printf("%c", isprint(tmp[y]) ?

51                                                tmp[y] : '.');

52                      }

53                      printf("\n");

54              }

55      }

56

57      if((x % 16) != 0)

58      {

59              for(y=0; y < (x % 16); ++y)

60              {

61                      printf("%02X ", tmp[y] & 0xFF);

62             }

63

64              for(y=(x % 16); y < 16 ; ++y)

65              {

66                      printf(" ");

67              }

68

69              for(y=0; y < (x % 16); ++y)

70              {

71                      printf("%c", isprint(tmp[y]) ? tmp[y] : '.');

72              }

73      }

74

75      printf("\n");

76 }

77

78 /*

79   * makegetreq()

80   *

81   *

82 */

83

84 #define SNMP1_PDU_HEAD "\x30\x00\x02\x01\x00\x04"

85 #define SNMP1_PDU_TAIL "\xa0\x1c\x02\x04\x7e\x16\xa2\x5e" \

86                          "\x02\x01\x00\x02\x01\x00\x30\x0e" \

87                          "\x30\x0c\x06\x08\x2b\x06\x01\x02" \

88                          "\x01\x01\x05\x00\x05\x00"

89

90 int makegetreq (char *buf, int blen, int *olen, char *comn)

91 {

92      int hlen = sizeof(SNMP1_PDU_HEAD) - 1;

93      int tlen = sizeof(SNMP1_PDU_TAIL) - 1;

94      int clen = strlen(comn);

95      int len = 0;

96

97      len = hlen + 1 + clen + tlen;

98      if(len > blen)

99      {

100              printf("insufficient buffer space (%d,%d).\n",

101                      blen, len);

102              return(-1);

103     }

104

105     memset(buf, 0x00, blen);

106     memcpy(buf, SNMP1_PDU_HEAD, hlen);

107     memcpy(buf + hlen + 1, comn, clen);

108     memcpy(buf + hlen + 1 + clen, SNMP1_PDU_TAIL, tlen);

109

110     buf[0x01] = 0x23 + clen;

111     buf[hlen] = (char) clen;

112

113     *olen = len;

114

115     return(0);

116 }

117

118 /*

119   * dores()

120   *

121   *

122 */

123 int dores (int sock)

124 {

125 char buf[SNMP1_BUF_SIZE];

126      int ret = 0;

127

128      ret = recvfrom(sock, buf, SNMP1_BUF_SIZE, 0, NULL, NULL);

129      if(ret < 0)

130      {

131              printf("recv() failed.\n");

132              return(-1);

133      }

134

135      hexdisp(buf, ret);

136

137     return(0);

138 }

139

140 /*

141   * doreq()

142   *

143   *

144 */

145 int doreq (int sock, char *comn)

146 {

147     char buf[SNMP1_BUF_SIZE];

148     int len = 0;

149     int ret = 0;

150

151     ret = makegetreq(buf, SNMP1_BUF_SIZE, &len, comn);

152     if(ret < 0)

153     {

154                printf("makegetreq() failed.\n");

155                return(-1);

156     }

157

158     hexdisp(buf, len);

159

160     ret = send(sock, buf, len, 0);

161     if(ret != len)

162     {

163             printf("send() failed.\n");

164             return(-1);

165     }

166

167     return(0);

168 }

169

170 /*

171   * makeudpsock()

172   *

173   *

174 */

175 int makeudpsock (char *targ, unsigned short port)

176 {

177      struct sockaddr_in sin;

178      unsigned int taddr = 0;

179      int sock = 0;

180      int ret = 0;

181

182      taddr = inet_addr(targ);

183      if(taddr == INADDR_NONE)

184      {

185              printf("inet_addr() failed.\n");

186              return(-1);

187 }

188

189      sock = socket(AF_INET, SOCK_DGRAM, 0);

190     if(sock < 0)

191      {

192              printf("socket() failed.\n");

193              return(-1);

194      }

195

196      memset(&sin, 0x0, sizeof(sin));

197

198      sin.sin_family = AF_INET;

199      sin.sin_port = htons(port);

200      sin.sin_addr.s_addr = taddr;

201

202      ret = connect(sock, (struct sockaddr *) &sin, sizeof(sin));

203     if(ret < 0)

204     {

205             printf("connect() failed.\n");

206             return(-1);

207     }

208

209     return(sock);

210 }

211

212 /*

213 * scan()

214 *

215 *

216 */

217 int scan (char *targ, unsigned short port, char *cname)

218 {

219     int sock = 0;

220     int ret  = 0;

221

222     sock = makeudpsock(targ, port);

223     if(sock < 0)

224     {

225             printf("makeudpsocket() failed.\n");

226             return(-1);

227     }

228

229     ret = doreq(sock, cname);

230     if(ret < 0)

231     {

232             printf("doreq() failed.\n");

233             return(-1);

234     }

235

236     ret = dores(sock);

237     if(ret < 0)

238      {

239             printf("dores() failed.\n");

240             return(-1);

241      }

242 

243      return(0);

244     }

245

246 /*

247 * usage()

248 *

249 *

250 */

251 void usage(char *prog)

252 {

253     printf("snmp1 00.00.01\r\n");

254     printf("usage  : %s -t target_ip <-p target_port> " \

255            " <-c community_name>\n", prog);

256     printf("example: %s -t 127.0.0.1 -p 161 -c public\n\n",

257             prog);

258 }

259

260      int

261      main(int argc, char *argv[])

262      {

263              unsigned short port = SNMP1_DEF_PORT;

264              char *targ = NULL;

265              char *comn = SNMP1_DEF_COMN;

266              char ch = 0;

267              int ret = 0;

268

269              opterr = 0;

270              while((ch = getopt(argc, argv, "t:p:c:")) != -1)

271              {

272                       switch(ch)

273                       {

274                       case 't':

275

276                               targ = optarg;

277                              break;

278

279                       case 'p':

280

281                               port = atoi(optarg);

282                               break;

283

284                       case 'c':

285

286                               comn = optarg;

287                               break;

288

289                       case '?':

290                       default:

291

292                               usage(argv[0]);

293                               return(1);

294                       }

295               }

296

297               if(targ == NULL)

298               {

299                       usage(argv[0]);

300                       return(1);

301               }

302

303               printf("using: target: %s; port: %d; " \

304                        community name: \"%s\"\n", targ, port, comn);

305

306               ret = scan(targ, port, comn);

307               if(ret < 0)

308               {

309                       printf("scan() failed.\n");

310                       return(1);

311              }

312

313               printf("scan complete.\n");

314

315               return(0);

316      }

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论