LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 09-10-2004, 06:34 PM   #1
gio123
LQ Newbie
 
Registered: Sep 2004
Posts: 1

Rep: Reputation: 0
Unhappy Netlink Sockets Problem


Hi all.

I'm trying to make a function that will take an IPv6 IP address as an argument (RTA_DST), send it to the Kernel via Netlink, and return its gateway from the routing table (RTA_GATEWAY). Unfortunatelly it only returns part of the Gateway address (although it is the correct one) any suggestions?

For example I've set a route in the IPv6 table where the address ee81::21c:76ff:fe51:74d2 has the gateway 4ffe:ffff:0:f102::2 When I use my code Netlink returns that the Gateway for this address is 4ffe:ffff:: which is half of what I actually wanted...
Below is the output of the code. Just ignore the last 3 lines.


SPLIT message received from -> ::1
MN Address Sent To Kernel is -> ee81::21c:76ff:fe51:74d2
Gateway Received for MN from Kernel is -> 4ffe:ffff::
Default Gateway is -> 4ffe:ffff:0:f102::2
Destination Gateway for MN is NOT the Deafult Gateway
Direct Route Found for MN


Below is the code (parts of which were found on the internet but for IPv4). Any help will be really appreciated.


void
*route_find(arg)
void *arg;
{
int nlsockfd, len;
static char errbuf[256];
char temp[MAXLINE];
struct split *split_arga = NULL;
struct sockaddr_in6 mnaddr, addr;

struct {
struct nlmsghdr n;
struct rtmsg r;
char data[1024];
} req;
struct rtattr *attr;


if(pthread_mutex_lock(&mutex))
err_sys("pthread_mutex_lock error");

split_arga = (struct split*) malloc(sizeof(struct split));
memcpy(split_arga, arg, sizeof(struct split));

if(pthread_mutex_unlock(&mutex))
err_sys("pthread_mutex_unlock error");

bzero(&mnaddr, sizeof(mnaddr));
mnaddr.sin6_family = AF_INET6;
mnaddr.sin6_addr = split_arga->split_MNaddress;

/*Open the Netlink Socket*/

nlsockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (nlsockfd < 0) {
sprintf(
errbuf, "Error Openning Netlink Socket: %.128s",
strerror(errno)
);
return errbuf;
}

/*Construct the mesage and copy the address i want to check to the message*/

memset(&req, 0, sizeof(req));
req.n.nlmsg_len =
NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))) +
RTA_LENGTH(sizeof(mnaddr.sin6_addr));
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_GETROUTE;
req.r.rtm_family = AF_INET6;
req.r.rtm_dst_len = 128;
attr = (void *) (
((char *) &req) + NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r)))
);
attr->rta_type = RTA_DST;
attr->rta_len = RTA_LENGTH(sizeof(mnaddr.sin6_addr));

memcpy(RTA_DATA(attr), &mnaddr.sin6_addr, sizeof(mnaddr.sin6_addr));
printf("MN Address Sent To Kernel is-> %s\n", inet_ntop(AF_INET6, &mnaddr.sin6_addr, temp, sizeof(temp)));


/*Send the message*/

if (send(nlsockfd, &req, req.n.nlmsg_len, 0) < 0) {
sprintf(
errbuf, "error sending netlink message: %.128s",
strerror(errno)
);
err:
close(nlsockfd);
return errbuf;
}

/*Receive the answer from the Kernel*/

len = recv(nlsockfd, &req, sizeof(req), 0);

if (len < 0) {
sprintf(
errbuf, "Error Receiving Netlink Message: %.128s",
strerror(errno)
);
goto err;
}
close(nlsockfd);
if (len < sizeof(struct nlmsghdr)) {
sprintf(errbuf, "Received Short Netlink Message: %d", len);
return errbuf;
}
if (len < req.n.nlmsg_len) {
sprintf(
errbuf, "Netlink Message Size Error: %d < %d",
len, req.n.nlmsg_len
);
return errbuf;
}
if (req.n.nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA(&req.n);
sprintf(
errbuf, "Netlink Error: %.128s",
strerror(-err->error)
);
return errbuf;
}

len -= NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r)));
while (len > sizeof(*attr) && len > attr->rta_len) {

/*Read the Reply and copy the address of the received Gateway*/

if (
attr->rta_type == RTA_GATEWAY &&
RTA_PAYLOAD(attr) == sizeof(addr.sin6_addr)
) {
memcpy(&addr.sin6_addr, RTA_DATA(attr), sizeof(attr));
printf("Gateway Received for MN form Kernel is -> %s\n", inet_ntop(AF_INET6, &addr.sin6_addr, temp, sizeof(temp)));
printf("Default Gateway is -> %s\n", inet_ntop(AF_INET6, &defrouter_ipaddr.s6_addr, temp, sizeof(temp)));


/*Compare the Gateway address with another one statically passed in the code*/

if(IN6_ARE_ADDR_EQUAL(addr.sin6_addr.s6_addr, defrouter_ipaddr.s6_addr)){
printf("Destination Gateway for MN is the Default Gateway\n");
printf(" Direct Route Not Found for MN\n" );
printf("-------------------------------------------------\n");
}
else{
printf("Destination Gateway for MN is NOT the Deafult Gateway\n");
printf(" Direct Route Found for MN\n");
printf(" \n");
/*if(pthread_create(&route_tid, NULL, &proc_split, (void*)split_arga))
err_sys("pthread_create error");*/
proc_split(split_arga);
}
return 0;
}
len -= attr->rta_len;
attr = (void *) (((char *) attr) + attr->rta_len);
}
strcpy(errbuf, "Netlink did not Return a Gateway Address");
return errbuf;
}
 
Old 09-11-2004, 01:37 PM   #2
infamous41md
Member
 
Registered: Mar 2003
Posts: 804

Rep: Reputation: 30
i haven't worked with netlink in a long time, but i wrote a tutorial about it when i did.
http://www.1nfamus.netfirms.com/netlink_tut.html

and also, iirc, messages could be split into multi parts. meaning you had to call read multiple times. here's an excerpt of my code:
Code:
//read a netlink reply in it's entirety
//responsibility of caller to make buf must at least NL_BUFSIZE 
inline int
readnl(int sock, char *buf, int seq, pid_t pid)
{
    int nread = 0, ntread = 0;
    u_char  flag = 0;
    char    *tmp = buf;
    struct nlmsghdr *nlhdrp = NULL;

    //read the reply, check for multi-part reply
    //fill up buffer to NL_BUFSIZE bytes at most
    do{
            //we can't read more than NL_BUFSIZE bytes  
        if( (nread = read(sock, tmp, NL_BUFSIZE - ntread )) < 0)
            perr_quit("read");

        nlhdrp = (struct nlmsghdr *)tmp;

            //FIRST ALWAYS: check to make sure the message structure is ok
            //then check to make sure type isn't error type
        if( (NLMSG_OK(nlhdrp, nread) == 0) || (nlhdrp->nlmsg_type == NLMSG_ERROR) )
                    return -1;

        //if this is the last message then it contains no data
        //so we dont want to return it
        if(nlhdrp->nlmsg_type == NLMSG_DONE)
            flag = 1;
        else{
            tmp += nread;
            ntread += nread;
        }

        //in this case we never had a multipart message 
        if( (nlhdrp->nlmsg_flags & NLM_F_MULTI) == 0 )
            flag = 1;

    }while(nlhdrp->nlmsg_seq != seq || nlhdrp->nlmsg_pid != pid || flag == 0);

    return ntread;
}
 
Old 11-29-2004, 07:12 AM   #3
guam
LQ Newbie
 
Registered: Feb 2004
Location: Korea
Posts: 25

Rep: Reputation: 15
Hello infamous41md,

I trying to do some experiments with netlink using NETLINK_USERSOCK. I am new to Kernel programming and netlink usage.

I saw your post and the information about the netlink tutorial. I could not reach to the web site you have mentioned in your post.

If possible can you provide the same tutorial again.

Thanks.

Devel.
 
Old 01-23-2005, 07:17 PM   #4
gr33ndata
Member
 
Registered: Aug 2003
Location: DMZ
Distribution: Ubuntu
Posts: 144

Rep: Reputation: 15
Hello Guam
I believe that Infamous has changed his home page
And here is his new address
http://www.infsec.net
http://www.infsec.net/netlink_tut.html
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Erratic PC Netlink 2.0 (on Solaris 9) - Windows XP printing problem Radu Negut Solaris / OpenSolaris 2 09-25-2006 06:07 AM
Kernel module using netlink sockets arunka Programming 1 03-31-2005 08:42 AM
'RT netlink socket initialing problem' menaka Linux - Hardware 3 02-22-2005 04:35 AM
Adding Routes using Netlink Sockets mpls_linux Linux - Networking 0 05-22-2004 10:14 PM
comments and opinions on linux netlink routing sockets tutorial infamous41md Programming 3 11-20-2003 06:54 PM


All times are GMT -5. The time now is 07:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration