C-函数未执行。呼叫错误?
我正在尝试构建一个可以发送TCP数据包的程序,但是当我编译代码来测试发送函数时,它并没有按照应该的方式运行。当给定参数时,它跳转到getchar并退出程序,就好像根本没有调用函数一样。现在我并没有特别的经验,这可能是一个愚蠢的问题,但我还没有在其他地方找到解决办法。我的猜测是,不知何故,我把它称为错误的,可能send_tcp函数不能在forgepacket函数中 下面是我的代码(根本没有完成,但应该足够好,可以进行一点测试运行),给我带来问题的函数是伪造的C-函数未执行。呼叫错误?,c,function,network-programming,C,Function,Network Programming,我正在尝试构建一个可以发送TCP数据包的程序,但是当我编译代码来测试发送函数时,它并没有按照应该的方式运行。当给定参数时,它跳转到getchar并退出程序,就好像根本没有调用函数一样。现在我并没有特别的经验,这可能是一个愚蠢的问题,但我还没有在其他地方找到解决办法。我的猜测是,不知何故,我把它称为错误的,可能send_tcp函数不能在forgepacket函数中 下面是我的代码(根本没有完成,但应该足够好,可以进行一点测试运行),给我带来问题的函数是伪造的 #include <stdio.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#define VERSION "1.0"
#define PCKT_LEN 8192
/* Prototypes */
void forgepacket (unsigned int, unsigned int, unsigned short, unsigned short);
void usage();
/* Checksum */
unsigned short checksum (unsigned short *pac, int len)
{
unsigned long sum;
for (sum = 0; len > 0; len--)
sum += *pac++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return(~sum);
}
in_addr_t sip;
in_addr_t dip;
int sport;
int dport;
int main(int argc,char **argv)
{
int c;
/* Are we in root? */
if(geteuid() !=0)
{
printf("Root access is required to run this program.\n\n");
exit(0);
}
while (1)
{
static struct option long_options[] =
{
/* Options */
{"send", no_argument, 0, 's'}, /* args s, r and f have no function yet */
{"recieve", no_argument, 0, 'r'},
{"file", required_argument, 0, 'f'},
{"destip", required_argument, 0, 'i'},
{"destport", required_argument, 0, 'p'},
{"sourceip", required_argument, 0, 'o'},
{"sourceport", required_argument, 0, 't'},
{0, 0, 0, 0}
};
int option_index = 0;
c = getopt_long (argc, argv, "srf:d:i:p:o:t:",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 0:
/* If this option set a flag, do nothing else now. */
if (long_options[option_index].flag != 0)
break;
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case 's':
puts ("option -s\n");
break;
case 'r':
puts ("option -r\n");
break;
case 'f':
printf ("option -f with value `%s'\n", optarg);
break;
case 'i':
dip = inet_addr(optarg);
break;
case 'p':
dport = htons(atoi(optarg));
/* Add handling of bad/non number input here */
break;
case 'o':
sip = inet_addr(optarg);
break;
case 't':
sport = htons(atoi(optarg));
break;
case '?':
/* Error message printed */
break;
default:
abort ();
}
}
/* Print any remaining command line arguments (not options). */
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
putchar ('\n');
}
/* check if all mandatory options are set and for unknown arguments */
/* This REALLY needs changing... */
if (dip, sip, dport, sport == 0)
{
usage();
return (-1);
}
forgepacket(dip, sip, dport, sport);
getchar ();
exit (0);
}
void forgepacket(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
unsigned short destport)
{
/* IP header structure */
struct ipheader {
unsigned char iph_ihl:5,
iph_ver:4;
unsigned char iph_tos;
unsigned short int iph_len;
unsigned short int iph_id;
unsigned char iph_flags;
unsigned short int iph_offset;
unsigned char iph_ttl;
unsigned char iph_protocol;
unsigned short int iph_chksum;
unsigned int iph_sourceip;
unsigned int iph_destip;
};
/* TCP header structure */
struct tcpheader {
unsigned short int tcph_sourceport;
unsigned short int tcph_destport;
unsigned int tcph_seqnum;
unsigned int tcph_acknum;
unsigned char tcph_reserved:4, tcph_offset:4;
unsigned int
tcp_res1:4,
tcph_hlen:4,
tcph_fin:1,
tcph_syn:1,
tcph_rst:1,
tcph_psh:1,
tcph_ack:1,
tcph_urg:1,
tcph_res2:2;
unsigned short int tcph_win;
unsigned short int tcph_chksum;
unsigned short int tcph_urgptr;
};
int send_tcp()
{
int sock, one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin, din;
const int *val = &one;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if (sock < 0)
{
printf("\nError: socket()\n\n");
exit (-1);
}
else
printf ("\nsocket() - Using SOCK_RAW and TCP protocol is OK.\n\n");
/* Size of the headers */
struct ipheader *ip = (struct ipheader *) buffer;
struct tcpheader *tcp = (struct tcpheader *) (buffer + sizeof (struct ipheader));
memset (buffer, 0, PCKT_LEN);
/* IP attributes */
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;
ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
ip->iph_id = htons(54321);
ip->iph_offset = 0;
ip->iph_ttl = 64;
ip->iph_protocol = 6;
ip->iph_chksum = 0;
ip->iph_sourceip = sip;
ip->iph_destip = dip;
/* TCP attributes */
tcp->tcph_sourceport = sport;
tcp->tcph_destport = dport;
tcp->tcph_seqnum = htonl(1);
tcp->tcph_acknum = 0;
tcp->tcph_offset = 5;
tcp->tcph_syn = 1;
tcp->tcph_ack = 0;
tcp->tcph_win = htons(32767);
tcp->tcph_chksum = 0;
tcp->tcph_urgptr = 0;
ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct ipheader )+ sizeof (struct tcpheader)));
/* Address family */
sin.sin_family = AF_INET;
din.sin_family = AF_INET;
/* Source port */
sin.sin_port = sport;
din.sin_port = dport;
/* Source IP */
sin.sin_addr.s_addr = sip;
din.sin_addr.s_addr = dip;
/* Tell the Kernel we're building our own packet */
if ((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof (one))) < 0)
{
printf("\nError: Can't set socketoptions\n\n");
return (-1);
}
/* Send */
if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
printf("\nError: Can't send packet\n\n");
return (-1);
}
else
printf("Packet sent to %d", dip);
close(sock);
}
}
void usage()
{
/* This is the user manual */
printf("\nTCP project %s\n\n", VERSION);
printf("Usage: -s -f <file> -i <destip> -p <destport> -o <sourceip> -t <sourceport>\n\n");
printf("-s, --send, Puts program in send mode\n");
printf("-r, --recieve, Puts program in recieve mode\n");
printf("-f, --file, Specify file containing steganographic message\n");
printf("-i, --destip, Destination IP address\n");
printf("-p, --destport, Destination port\n");
printf("-o, --sourceip Source IP address\n");
printf("-t, --sourceport Source port\n");
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义版本“1.0”
#定义PCKT_LEN 8192
/*原型*/
无效数据包(无符号整数、无符号整数、无符号短、无符号短);
无效用法();
/*校验和*/
无符号短校验和(无符号短*pac,int len)
{
无符号长和;
对于(总和=0;len>0;len--)
总和+=*pac++;
总和=(总和>>16)+(总和&0xffff);
总和+=(总和>>16);
回报率(~sum);
}
输入地址sip;
内加倾斜;
国际体育;
int dport;
int main(int argc,字符**argv)
{
INTC;
/*我们在根吗?*/
如果(geteuid()!=0)
{
printf(“运行此程序需要根访问权限。\n\n”);
出口(0);
}
而(1)
{
静态结构选项长_选项[]=
{
/*选择权*/
{“send”,没有_参数,0,'s'},/*args,r和f还没有函数*/
{“receive”,无_参数,0,'r'},
{“文件”,必需的参数,0,'f'},
{“destp”,必选参数,0,'i'},
{“destport”,必需的参数,0,'p'},
{“sourceip”,必需的参数,0,'o'},
{“sourceport”,必需的参数,0,'t'},
{0, 0, 0, 0}
};
int option_index=0;
c=getopt_long(argc,argv,“srf:d:i:p:o:t:”,
多头期权和期权指数);
/*检测选项的结尾*/
如果(c==-1)
打破
开关(c)
{
案例0:
/*如果此选项设置了标志,则现在不执行其他操作*/
if(长选项[选项索引].flag!=0)
打破
printf(“选项%s”,长选项[选项索引].name);
如果(optarg)
printf(“带有参数%s”,optarg);
printf(“\n”);
打破
案例s:
看跌期权(“期权-s\n”);
打破
案例“r”:
看跌期权(“期权-r\n”);
打破
案例“f”:
printf(“选项-f,值为“%s”\n”,optarg);
打破
案例“i”:
dip=inet_addr(optarg);
打破
案例“p”:
dport=htons(atoi(optarg));
/*在此处添加对错误/非数字输入的处理*/
打破
案例“o”:
sip=内部地址(optarg);
打破
案例“t”:
sport=htons(atoi(optarg));
打破
案例“?”:
/*打印错误消息*/
打破
违约:
中止();
}
}
/*打印任何剩余的命令行参数(不是选项)*/
如果(选项D/* Prototype. */
int send_tcp(); /* add whatever parameters are required. */