论坛: 编程破解 标题: 我写的一个程序,希望此方面高手指正一下 复制本贴地址    
作者: NetDemon [netdemon]    ADMIN   登录
因为是准备用于商业用途,所以小心点。虽然是在我的知识范围内考虑过了,不过一个人的力量总是有限的

代码:

/*
 * ddnsd - 20CN DDNS Server Process Daemon for *BSD.
 *
 * This software is NOT free of charge, 
 * Copyright (C) 20CN Security Group 2003.
 * By NetDemon <netdemon@20cn.org>
 * http://www.20cn.net/
 * @(#)ddnsd.c 0.1 (20CN) 28/5/03
 */

#define SYSLOG_NAMES

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>

#include "ddnsd.h"

#define DEFAULT_SERVICE "ddnsd"
#define SERVICE_PORT 553
#define MAX_PACKET 128

/*
 * Function prototypes.
 */

static void DoProcessing (int fd, int direction);
static void DaemonMode (void);
static void Usage (void);
static void InitiateShutdown (int);
static void Shutdown (int);
static void RefreshAddr (int);
static void ParseOption (const char* option, const char* parms);
static void ReadConfigFile (const char* fileName);
static void StrToAddr (const char* str, struct in_addr* addr);
static u_short  StrToPort (const char* str, const char* proto);
static int  StrToProto (const char* str);
static void ParseArgs (int argc, char** argv);


/*
 * Globals.
 */

static int verbose;
static  int background;
static int running;
static char* ifName;
static int assignAliasAddr;
static  int dynamicMode;
static int logFacility;

int main (int argc, char** argv)
{
int sockfd;
struct sockaddr_in addr;
fd_set readMask;
int fdMax;
/*
 * Parse options.
 */
verbose  = 0;
ifName = NULL;
background = 0;
running = 1;
dynamicMode = 0;
  logFacility = LOG_DAEMON;
ParseArgs (argc, argv);
/*
 * Open syslog channel.
 */
openlog ("ddnsd", LOG_CONS | LOG_PID | (verbose ? LOG_PERROR : 0),
 logFacility);

/*
 * Create sockets. 
 */
sockfd = socket (AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
Quit ("Unable to create socket.");
/*
 * Bind socket.
 */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(SERVICE_PORT);

if (bind (sockfd,(struct sockaddr*) &addr,sizeof addr) == -1)
Quit ("Unable to bind socket.");
/*
 * Become a daemon unless verbose mode was requested.
 */
if (!verbose)
DaemonMode ();
/*
 * Catch signals to manage shutdown and
 * refresh of interface address.
 */
siginterrupt(SIGTERM, 1);
siginterrupt(SIGHUP, 1);
signal (SIGTERM, InitiateShutdown);
signal (SIGHUP, RefreshAddr);
/*
 * We need largest descriptor number for select.
 */

fdMax = -1;

if (sockfd > fdMax)
fdMax = sockfd;

while (running) {

/* 
 * Build read mask from socket descriptors to select.
 */
FD_ZERO (&readMask);
/*
 * Check if new packets are available.
 */
if (sockfd != -1)
FD_SET (sockfd, &readMask);

if (select (fdMax + 1, &readMask, NULL, NULL, NULL) == -1) {
if (errno == EINTR)
continue;
Quit ("Select failed.");
}

if (sockfd != -1) 
if (FD_ISSET (sockfd, &readMask))
DoProcessing (sockfd, DONT_KNOW);
}

if (background)
unlink (PIDFILE);
return 0;
}

static void DaemonMode ()
{
FILE* pidFile;

daemon (0, 0);
background = 1;

pidFile = fopen (PIDFILE, "w");
if (pidFile) {

fprintf (pidFile, "%d\n", getpid ());
fclose (pidFile);
}
}

static void ParseArgs (int argc, char** argv)
{
int arg;
char* opt;
char parmBuf[256];
int len; /* bounds checking */

for (arg = 1; arg < argc; arg++) {

opt  = argv[arg];
if (*opt != '-') {

warnx ("invalid option %s", opt);
Usage ();
}

parmBuf[0] = '\0';
len = 0;

while (arg < argc - 1) {

if (argv[arg + 1][0] == '-')
break;

if (len) {
strncat (parmBuf, " ", sizeof(parmBuf) - (len + 1));
len += strlen(parmBuf + len);
}

++arg;
strncat (parmBuf, argv[arg], sizeof(parmBuf) - (len + 1));
len += strlen(parmBuf + len);

}

ParseOption (opt + 1, (len ? parmBuf : NULL));

}
}

static void DoProcessing (int fd, int direction)
{
int bytes;
int origBytes;
char buf[MAX_PACKET];
struct sockaddr_in addr;
int wrote;
int status;
int addrSize;
struct ip* ip;
char msgBuf[80];
char domain[256];

/*
 * Get packet from socket.
 */
addrSize  = sizeof addr;
origBytes = recvfrom (fd, buf, sizeof buf, 0, (struct sockaddr*) &addr, &addrSize);
if (origBytes == -1) {
if (errno != EINTR)
Warn ("read from socket failed");
return;
}

// if (verbose) {
/*
 * Print All addresses msg to syslog.
 */

// SyslogPacket (ip, LOG_WARNING, "require");
// }

/*
 * Decoder Buf MSG 
 */
 
 //decoder(buf,status,domain,passwd);
 
//if (status==1){
/*
 * check passwd.
 */
//}else{

/*
 * check ip and update ip.
 */

//}

/*
 * Put packet back for processing.
 */
wrote = sendto (fd, buf, bytes, 0, (struct sockaddr*) &addr, sizeof addr);

if (wrote != bytes) {
if (errno == EACCES ) {
sprintf (msgBuf, "failed to write packet back");
Warn (msgBuf);
}
}
}

///////////////////////////////////////////
void Quit (const char* msg)
{
Warn (msg);
exit (1);
}

void Warn (const char* msg)
{
if (background)
syslog (LOG_ALERT, "%s (%m)", msg);
else
warn ("%s", msg);
}

static void RefreshAddr (int sig)
{
if (ifName)
assignAliasAddr = 1;
}

static void InitiateShutdown (int sig)
{
/*
 * Start timer to allow kernel gracefully
 * shutdown existing connections when system
 * is shut down.
 */
siginterrupt(SIGALRM, 1);
signal (SIGALRM, Shutdown);
alarm (10);
}

static void Shutdown (int sig)
{
running = 0;
}

/* 
 * Different options recognized by this program.
 */

enum Option {

Verbose,
ConfigFile,
DynamicMode,
LogFacility
};

enum Param {

YesNo,
String,
None,
};

/*
 * Option information structure (used by ParseOption).
 */

struct OptionInfo {

enum Option type;
enum Param parm;
const char* parmDescription;
const char* description;
const char* name;
const char* shortName;

};

/*
 * Table of known options.
 */

static struct OptionInfo optionTable[] = {

{ Verbose,
YesNo,
"[yes|no]",
"verbose mode, dump packet information",
"verbose",
"v" },

{ DynamicMode,
YesNo,
"[yes|no]",
"dynamic mode, automatically detect interface address changes",
"dynamic",
NULL },

{ ConfigFile,
String,
"file_name",
"read options from configuration file",
"config",
"f" },

{ LogFacility,
String,
        "facility",
"name of syslog facility to use for logging",
"log_facility",
NULL },
};

static void ParseOption (const char* option, const char* parms)
{
int i;
struct OptionInfo* info;
int yesNoValue;
const char* strValue;
int max;
char* end;
CODE*  fac_record = NULL;
/*
 * Find option from table.
 */
max = sizeof (optionTable) / sizeof (struct OptionInfo);
for (i = 0, info = optionTable; i < max; i++, info++) {

if (!strcmp (info->name, option))
break;

if (info->shortName)
if (!strcmp (info->shortName, option))
break;
}

if (i >= max) {

warnx ("unknown option %s", option);
Usage ();
}

yesNoValue = 0;
strValue = NULL;
/*
 * Check parameters.
 */
switch (info->parm) {
case YesNo:
if (!parms)
parms = "yes";

if (!strcmp (parms, "yes"))
yesNoValue = 1;
else
if (!strcmp (parms, "no"))
yesNoValue = 0;
else
errx (1, "%s needs yes/no parameter", option);
break;

case String:
strValue = parms;
if (!strValue)
errx (1, "%s needs parameter", option);
break;

case None:
if (parms)
errx (1, "%s does not take parameters", option);
break;

}

switch (info->type) {
case Verbose:
verbose = yesNoValue;
break;

case DynamicMode:
dynamicMode = yesNoValue;
break;

case ConfigFile:
ReadConfigFile (strValue);
break;

case LogFacility:

fac_record = facilitynames;
while (fac_record->c_name != NULL) {

if (!strcmp (fac_record->c_name, strValue)) {

logFacility = fac_record->c_val;
break;

}
else
fac_record++;
}

if(fac_record->c_name == NULL)
errx(1, "Unknown log facility name: %s", strValue);

break;
}
}

void ReadConfigFile (const char* fileName)
{
FILE* file;
char *buf;
size_t len;
char *ptr, *p;
char* option;

file = fopen (fileName, "r");
if (!file)
err(1, "cannot open config file %s", fileName);

while ((buf = fgetln(file, &len)) != NULL) {
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
else
errx(1, "config file format error: "
"last line should end with newline");

/*
 * Check for comments, strip off trailing spaces.
 */
if ((ptr = strchr(buf, '#')))
*ptr = '\0';
for (ptr = buf; isspace(*ptr); ++ptr)
continue;
if (*ptr == '\0')
continue;
for (p = strchr(buf, '\0'); isspace(*--p);)
continue;
*++p = '\0';

/*
 * Extract option name.
 */
option = ptr;
while (*ptr && !isspace (*ptr))
++ptr;

if (*ptr != '\0') {

*ptr = '\0';
++ptr;
}
/*
 * Skip white space between name and parms.
 */
while (*ptr && isspace (*ptr))
++ptr;

ParseOption (option, *ptr ? ptr : NULL);
}

fclose (file);
}

static void Usage ()
{
int i;
int max;
struct OptionInfo* info;

fprintf (stderr, "Recognized options:\n\n");

max = sizeof (optionTable) / sizeof (struct OptionInfo);
for (i = 0, info = optionTable; i < max; i++, info++) {

fprintf (stderr, "-%-20s %s\n", info->name,
info->parmDescription);

if (info->shortName)
fprintf (stderr, "-%-20s %s\n", info->shortName,
info->parmDescription);

fprintf (stderr, "      %s\n\n", info->description);
}

exit (1);
}

void StrToAddr (const char* str, struct in_addr* addr)
{
struct hostent* hp;

if (inet_aton (str, addr))
return;

hp = gethostbyname (str);
if (!hp)
errx (1, "unknown host %s", str);

memcpy (addr, hp->h_addr, sizeof (struct in_addr));
}

u_short StrToPort (const char* str, const char* proto)
{
u_short port;
struct servent* sp;
char* end;

port = strtol (str, &end, 10);
if (end != str)
return htons (port);

sp = getservbyname (str, proto);
if (!sp)
errx (1, "unknown service %s/%s", str, proto);

return sp->s_port;
}

int StrToProto (const char* str)
{
if (!strcmp (str, "tcp"))
return IPPROTO_TCP;

if (!strcmp (str, "udp"))
return IPPROTO_UDP;

errx (1, "unknown protocol %s. Expected tcp or udp", str);
}




地主 发表时间: 05/29 05:55

回复: shesh [shesh]   版主   登录
我看得头晕了,能不能加点中文注释?

B1层 发表时间: 05/29 11:05

回复: group [group]   论坛用户   登录
累~,代码太长,加点注释吧

B2层 发表时间: 05/30 09:35

回复: imstone [imstone]   论坛用户   登录
是啊
呵呵~`

B3层 发表时间: 05/30 18:39

回复: darkhorse [darkhorse]   论坛用户   登录
版主,是用什么语言写出来的?

B4层 发表时间: 05/30 19:34

回复: NetDemon [netdemon]   ADMIN   登录
我更昏阿,我不是都有注释了么,而且是很详细的注释呢


B5层 发表时间: 05/30 22:35

回复: hanzhixuan [hanzhixuan]   论坛用户   登录
55555555老大,能不能加点中文注释啊,藕的鹰语很不毫啊!!!!!!!

B6层 发表时间: 07/01 10:07

回复: changfeng [changfeng]   论坛用户   登录
你的代码可读性很差
我建议你去看看外文的书
他们的代码条理很清晰!

B7层 发表时间: 07/02 17:46

回复: harry007 [harry007]   论坛用户   登录
上面的兄弟你敢批判老netdemon的原代码!!!!佩服佩服

B8层 发表时间: 07/02 18:32

回复: NetDemon [netdemon]   ADMIN   登录
我也确实是很佩服迈克老狼的,因为上述程序中用于处理命令行参数和读取配置文件的函数都是直接在freeBSD的原码中拷贝的,程序的框架也是依照named的框架来的。这世界上能说出如此自相矛盾以及认为BSD及named的代码不清晰的恐怕也只有这位仁兄了。
不过说实话,这个程序是并没有完成的,看不懂什么意思也是在所难免,而且从应用的角度说,需要考虑很多可能发生的事情,很多代码也许一辈子都没有执行过但却必须存在,很多漏洞的发生就是因为少了这些代码的存在,而这些代码的存在必将和实际要实现的功能混到一起,比较难以阅读。这不能和一个用于教学的例子程序拿来相提并论。

B9层 发表时间: 07/03 00:20

回复: shesh [shesh]   版主   登录
这话有道理.

B10层 发表时间: 07/03 09:02

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号