任何人都可以解释这种不起眼的行为吗?

cla*_*ven 2 c sockets linux ubuntu gcc

我正在尝试为安全课程编写端口扫描程序.我决定在Linux上使用C编写它,因为我从未在Java之外做任何与网络相关的事情.我在Ubuntu 10.10上使用GCC 4.4.5.我有一个主函数解析参数,然后用结果变量调用扫描函数.这是我的完整程序:http://pastebin.com/DHU7SEQR

我遇到的问题是它无法正常工作(报告所有端口都打开),除非我在调用函数之前打印出从用户收到的变量(或者重新排列传递给可执行文件的参数的顺序) ,这对我来说毫无意义.请注意注释掉的行(150),将此行注释掉并使用该命令进行编译

gcc scanner.c -o scanner
Run Code Online (Sandbox Code Playgroud)

然后运行该程序

./scanner -a 127.0.0.1 -b 0 -e 1000 -t 1000
Run Code Online (Sandbox Code Playgroud)

导致它报告所有端口都是打开的.但是,取消注释该行(即,在调用函数之前打印出所有变量)会导致正确报告端口的状态.重新排列参数的顺序

./scanner -b 0 -e 1000 -t 1000 -a 127.0.0.1
Run Code Online (Sandbox Code Playgroud)

似乎也可以工作,就像在每个case块中添加一个printf语句一样(即使不自己打印变量).

use*_*653 5

$ valgrind ./scanner -a 127.0.0.1 -b 0 -e 1000 -t 1000
==3800== Memcheck, a memory error detector
==3800== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==3800== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==3800== Command: ./scanner -a 127.0.0.1 -b 0 -e 1000 -t 1000
==3800== 
==3800== Syscall param socketcall.getsockopt(optlen) points to uninitialised byte(s)
==3800==    at 0x4F15DCA: getsockopt (syscall-template.S:82)
==3800==    by 0x400BC5: scan (scanner.c:83)
==3800==    by 0x400DBB: main (scanner.c:152)
==3800==  Address 0x7ff000330 is on thread 1's stack
==3800== 
==3800== Syscall param socketcall.getsockopt(optlen_out) points to uninitialised byte(s)
==3800==    at 0x4F15DCA: getsockopt (syscall-template.S:82)
==3800==    by 0x400BC5: scan (scanner.c:83)
==3800==    by 0x400DBB: main (scanner.c:152)
==3800==  Address 0x7ff000330 is on thread 1's stack
==3800== 
Run Code Online (Sandbox Code Playgroud)

检查联机帮助页getsockopt(2).

对于getsock- opt(),optlen是一个value-result参数,最初包含optval指向的缓冲区大小,并在返回时修改以指示返回值的实际大小.如果没有提供或返回选项值,optval可能为NULL."

所以你需要len在第82行初始化.

注意:代码可能存在其他问题.