Netlink programming problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I try to use netlink to receive (retrieve) the packets which are
stored in QUEUE by iptables.

However, every time when recvfrom() is executed, my program will get a
message (ipq_packet_msg) whose length is 0.
After apply iptables rules, I'm sure the filtered (ICMP) packets are
not passed to network stack anymore, but my program seems not get the
message. Following is my program, is there something wrong? I
appreciate your suggestions:

===================================
	struct sockaddr_nl addr_nl;
	struct nlmsghdr *nl_hdr = NULL;
	struct ipq_mode_msg *mode_data = NULL;
	struct ipq_packet_msg *pkt_data = NULL;
	struct ipq_verdict_msg *ver_data = NULL;
	socklen_t len;
	
	buffer1 = (void *)malloc(BUF_SIZE);
	buffer2 = (void *)malloc(BUF_SIZE);	

	if ((netlink_sockfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_FIREWALL)) < 0){
		perror("socket(): fail to open NETLINK_FIREWALL socket\n");
		exit(1);
	}
	
	/* set up the socket address structure */
	memset(&addr_nl,0,sizeof(struct sockaddr_nl));
	addr_nl.nl_family = AF_NETLINK;
	addr_nl.nl_pid = 0; /* packets are destined for the kernel */
	addr_nl.nl_groups = 0; /* no any multicast groups*/
	
	/* We need establish the operational mode to the queue by sending a
mode message,
	 * so fill out the nlmsghdr structures as such.
	 */
	nl_hdr = (struct nlmsghdr *)buffer1;
	nl_hdr->nlmsg_type = IPQM_MODE;
	nl_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_mode_msg));
	nl_hdr->nlmsg_flags = NLM_F_REQUEST; // A request, no answer required
	nl_hdr->nlmsg_pid = getpid();
	nl_hdr->nlmsg_seq = seq++; /*arbitrary unique value to allow response
correlatio */
	mode_data = (struct ipq_mode_msg *)NLMSG_DATA(nl_hdr);/* return a
pointer to the payload associated with the passed nlmsghdr*/
	mode_data->value = IPQ_COPY_META; /* sends only metadata about the
frame to userspace */
	mode_data->range = 0; /* copy whole packet */
	
	cout << "Sending MODE message... " << endl;
	if(sendto(netlink_sockfd, (void *)nl_hdr,nl_hdr->nlmsg_len,0,(struct
sockaddr *)&addr_nl,
			sizeof(struct sockaddr_nl)) < 0) {
		perror("sendto():unable to send mode message");
		exit(1);
	}
	
	len = sizeof(addr_nl);

  while(1){
		/* Wait for incoming packet... */
		if(recvfrom(netlink_sockfd, buffer1, NLMSG_LENGTH(sizeof(struct
ipq_packet_msg)),0,
				(struct sockaddr *)&addr_nl, &len) < 0) {
			perror("recvfrom():error occurred when receiving packet messages");
			exit(1);
		}
		
		total_callback++;
		/* once we have the packet message, extract the header and ancillary data */
		nl_hdr = (struct nlmsghdr *)buffer1;
		pkt_data = (struct ipq_packet_msg *)NLMSG_DATA(nl_hdr);
		
		if (pkt_data->data_len > 0){
			print_mac_addr(pkt_data->hw_addr);
			cout << "data_len is " << dec << pkt_data->data_len << endl;
		}
			
		/* Output some information of the packet */
		
		/* For the example, just forward all packets */
		/* Fill out a new nlmsgehdr structure */
		nl_hdr = (struct nlmsghdr *)buffer2;
		nl_hdr->nlmsg_type = IPQM_VERDICT; // Release the packet from ip_queue
		nl_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_verdict_msg));
		nl_hdr->nlmsg_flags = NLM_F_REQUEST; // A request, no answer required
		nl_hdr->nlmsg_pid = getpid();
		nl_hdr->nlmsg_seq = seq++;
		ver_data = (struct ipq_verdict_msg *)NLMSG_DATA(nl_hdr);
		ver_data->value = NF_ACCEPT; // Send the packet through on the
network stack without any further iptables tests
		ver_data->id = pkt_data->packet_id;
		
		if(sendto(netlink_sockfd,(void *)nl_hdr,nl_hdr->nlmsg_len,0,(struct
sockaddr *)&addr_nl,
				sizeof(struct sockaddr_nl)) < 0 ){
			perror("sendto():unable to send the packet back to networ stack");
			exit(1);
		}
  }
--
To unsubscribe from this list: send the line "unsubscribe netfilter" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux