当我运行原始套接字程序时,它会生成无效的参数错误

时间:2009-05-18 11:32:29

标签: c linux network-programming

请帮助我。
经过2天的长篇大论后,我找不到答案。请帮我 我对socket编程很新,我写了一个小代码来转发tcp层的数据包,因为我使用了ip_queue和netlinks与NETLINK_FIREWALL协议。 我所做的是

iptables -I OUTPUT -j QUEUE -p udp --destination-port 19989

我按命令提示跑了 我的代码是(只接收数据包不多)
只是它避免了远程的icmp错误和打印包信息而没有传递到应用程序层。


1 #include<asm/types.h>  
2 #include<sys/socket.h>  
3 #include<linux/netlink.h>  
4 #include<linux/netfilter_ipv4/ip_queue.h>  
5 #include<stdio.h>  
6 #include<stdlib.h>  
7 #include<netinet/in.h>  
8 #include<arpa/inet.h>  
9 #include<netdb.h>    
10 #include<linux/ip.h>    
11 #include<linux/icmp.h>  
12 #include<string.h>  
13 #include<unistd.h>  
14   
15 int nl_sock_fd = 0;  
16 struct sockaddr_nl nl_addr;  
17 int seq = 0;  
18 struct ipq_mode_msg* modeMessage;  
19 struct ipq_verdict_msg *ver_data = NULL;  
20 struct nlmsghdr* netlinkHeader =NULL;  
21 struct ipq_packet_msg* packet = NULL;  
22 char buf1[128] ={0};  
23 char buf[4096] = {0};  
24 char buf2[8192] = {0};  
25   
26 int addrSize;  
27 int len,i;  
28   
29   
30 int main(int argc, char *argv[])  
31 {  
32 int iter= 0;  
33 
34 /******* create and set the values for netlink sockets*************/  
35 if((nl_sock_fd = socket( AF_NETLINK, SOCK_RAW, NETLINK_FIREWALL))<0)  
36 {  
37 printf("socket creation failed!\n");  
38 return ;  
39 }  
40 printf("socket fd =%d\n", nl_sock_fd);  
41   
42 // Set up the kernels address structure:  
43 memset(&nl_addr, 0, sizeof( struct sockaddr_nl ) );    
44 nl_addr.nl_family = AF_NETLINK;    
45 nl_addr.nl_pid = 0; // The with address 0 in netlink /getpid();    
46 nl_addr.nl_groups = 0; // we dont need any multicast groups  
47 nl_addr.nl_pad = 0;  
48 if(bind(nl_sock_fd, (struct sockaddr*)&nl_addr, sizeof(nl_addr))<0)  
49 {  
50 printf("bind failed");  
51 }  
52 /******************* set mode values ***************************/  
53 memset(buf1, 0, 128 );  
54 netlinkHeader = (struct nlmsghdr*)buf1;  
55 netlinkHeader->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_mode_msg));  
56 //NLMSG_LENGTH size of the ancilliary data  
57 netlinkHeader->nlmsg_type = IPQM_MODE; //IPQM Packet  
58 netlinkHeader->nlmsg_flags = NLM_F_REQUEST; //request message   
59 netlinkHeader->nlmsg_seq = seq++; //to allow response correlation  
60 netlinkHeader->nlmsg_pid = getpid();  
61   
62 // modeMessage=(struct ipq_mode_msg*)NLMSG_DATA(netlinkHeader);  
63 modeMessage=NLMSG_DATA(netlinkHeader);  
64 //NLMSG_DATA returns a pointer to the ancilliary data which it contains  
65 modeMessage->value = IPQ_COPY_PACKET; //copy metadata and range 0 is entire packet  
66 modeMessage->range = 0; // copy the entire payload  
67   
68 if(sendto( nl_sock_fd, (void*)buf1, netlinkHeader->nlmsg_len, 0, (struct   sockaddr*)&nl_addr, s izeof(struct sockaddr_nl) ) < 0 )  
69 {  
70 printf("unable to set netlink mode ...\n");  
71 exit(0);  
72 }  
73 printf("portion of data sent to netlink\n");  
74 for(iter = 0; iter < 24; iter++ )  
75 {  
76 printf(" %x",(unsigned int)buf1[iter]);  
77 if(!(iter%10) && iter !=0)  
78 printf("\n");  
79 }   
80 printf("\n");  
81   
82 /*********** receiving msg ******************/  
83 printf("socket is up and waiting for messages....\n");  
84   
85 while(1)  
86 {  
87 //struct nlmsghdr* netlinkHeader = buf1;  
88   
89 //netlinkHeader = buf1;  
90 printf(" iam at recvfrom \n");  
91 len = recvfrom(nl_sock_fd, buf2, NLMSG_LENGTH(sizeof(struct ipq_packet_msg)), 0,   (struct soc kaddr*)&nl_addr, &addrSize );  
92 printf(" NLMSG_LENGTH = %d\n",NLMSG_LENGTH(sizeof(struct ipq_packet_msg)));  
93 if( len < 0 )  
94 {  
95 printf("unable to recive packet from the kernel\n");  
96 return 0;  
97 }  
98   
99 netlinkHeader = ( struct nlmsghdr* ) buf2;  
100   
101 printf("message received with pid=%d \n", nl_addr.nl_pid);  
102   
103 if( netlinkHeader->nlmsg_type == NLMSG_ERROR )  
104 {  
105 struct nlmsgerr* pError = (struct nlmsgerr*)NLMSG_DATA( netlinkHeader );  
106 if( pError->error != 0 ) // Error number 0 is an acknowledgement not an error.  
107 {  
108 printf("error occured while receiving the message from the kernel.\n");  
109 printf("error code %d \n ", pError->error);  
110 printf("\n****** %s ********\n",strerror( -1 * pError->error));       
111 printf("msg->nlmsg_len %d\n", pError->msg.nlmsg_len);  
112 printf("msg->nlmsg_type %x\n", pError->msg.nlmsg_type);  
113 printf("msg->nlmsg_flags %x\n",pError->msg.nlmsg_flags);  
114 printf("msg->nlmsg_seq: %d\n", pError->msg.nlmsg_seq);  
115 printf("msg->nlmsg_pid: %d\n", pError->msg.nlmsg_pid);  
116 return 0;  
117 }  
118 }  
119 else  
120 {  
121   
122 printf("Message from kernel:\n ");  
123 printf("Packet ID: %d\n",packet->packet_id);  
124 printf("Payload size:%d\n", packet->data_len);  
125 for(i = 0; i < packet->data_len; ++i )  
126 {  
127 printf("%c ", packet->payload[ i ]);  
128 }  
129 printf("\n");  
130   
131 }  
132 printf("\n dumping packets over \n");  
133 netlinkHeader=(struct nlmsghdr *)buf1;  
134 packet=NLMSG_DATA(netlinkHeader);  
135 /*for the example just forward all packets*/  
136 //netlinkHeader = (struct nlmsghdr*)buf2;  
137 netlinkHeader->nlmsg_type=IPQM_VERDICT;  
138 netlinkHeader->nlmsg_len=NLMSG_LENGTH(sizeof(struct ipq_verdict_msg));  
139 netlinkHeader->nlmsg_flags=(NLM_F_REQUEST);/*this is a request, don’t ask for an answer*/  
140 netlinkHeader->nlmsg_pid=getpid();  
141 netlinkHeader->nlmsg_seq=seq++;/*arbitrary unique value to allow response correlation*/  
142 ver_data=(struct ipq_verdict_msg *)NLMSG_DATA(netlinkHeader);  
143   
144 //ver_data->value=NF_ACCEPT;  
145 //ver_data->value=NF_QUEUE;  
146 ver_data->id=packet->packet_id;  
147 if(sendto(nl_sock_fd,(void *)netlinkHeader,netlinkHeader->nlmsg_len,0,
148 (struct sockaddr *)&nl_addr,sizeof(struct sockaddr_nl)) < 0)  
149 {  
150 perror("unable to send mode message");  
151 exit(0);  
152 }  
153   
154   
155 }  
156   
157 return 0;  
158 }  

输出就像

socket fd =3  
portion of data sent to netlink  
18 0 0 0 11 0 1 0 0 0 0  
0 38 30 0 0 2 0 0 0 0  
0 0 0  
socket is up and waiting for messages....  
iam at recvfrom   
NLMSG_LENGTH = 88  
message received with pid=0   
error occured while receiving the message from the kernel.  
error code -22  



****** Invalid argument ********  
msg->nlmsg_len 24  
msg->nlmsg_type 11  
msg->nlmsg_flags 1  
msg->nlmsg_seq: 0  
msg->nlmsg_pid: 12344  

请帮帮我 并提供一些有助于学习原始插座的最佳书籍

1 个答案:

答案 0 :(得分:1)

Thisthis可能对您有所帮助。

要获取描述性错误代码类型man recv,或查看errno.h。如果使用perror()函数,它将打印出包含错误描述的字符串。