* receive only one record from the routing table
@ 2005-06-17 13:51 Tomáš Macek
2005-06-17 14:15 ` Thomas Graf
0 siblings, 1 reply; 8+ messages in thread
From: Tomáš Macek @ 2005-06-17 13:51 UTC (permalink / raw)
To: netdev
Hi, I have this program (see below), and I want him to find a certain route record in the kernel routing table. I copied this somewhere from the internet and add the NetlinkAddAttr() function, that should add an request on the destination address. But the program prints always the WHOLE routing table.
But I would like to have a program, that would RECEIVE only one route from the kernel routing table for certain destination address only. Is it possible to do in rtnetlink?
I wasn't able to find the answer on google and my tries all failed.
Any help will be very appreciated!
Tomas
==================================================================================
#include <asm/types.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <net/if.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <sys/types.h>
#define BUFSIZE 8192
struct route_info {
u_int dstAddr;
u_int dstMask;
u_int srcAddr;
u_int gateWay;
char ifName[IF_NAMESIZE];
};
int NetlinkAddAttr(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) {
int len = RTA_LENGTH(alen);
struct rtattr *rta;
if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)
return -1;
rta = (struct rtattr *)(((char *)n) + NLMSG_ALIGN(n->nlmsg_len));
rta->rta_type = type;
rta->rta_len = len;
memcpy(RTA_DATA(rta), data, alen);
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
return 0;
}
int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId) {
struct nlmsghdr *nlHdr;
int readLen = 0, msgLen = 0;
do {
/* Recieve response from the kernel */
if((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0){
perror("SOCK READ: ");
return -1;
}
nlHdr = (struct nlmsghdr *)bufPtr;
/* Check if the header is valid */
if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR)) {
perror("Error in recieved packet");
return -1;
}
/* Check if the its the last message */
if(nlHdr->nlmsg_type == NLMSG_DONE){
break;
} else{
/* Else move the pointer to buffer appropriately */
bufPtr += readLen;
msgLen += readLen;
}
/* Check if its a multi part message */
if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0){
/* return if its not */
break;
}
} while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
return msgLen;
}
unsigned long netmask_from_bitcount(unsigned int bits) {
return 0xffffffff << (32 - bits);
}
/* For printing the routes. */
void printRoute(struct route_info *rtInfo) {
char tempBuf[512];
/* Print Destination address */
if(rtInfo->dstAddr != 0)
strcpy(tempBuf, (char *)inet_ntoa(rtInfo->dstAddr));
else
sprintf(tempBuf,"*.*.*.*\t\t");
fprintf(stdout,"%s\t\t", tempBuf);
/* Print Gateway address */
if(rtInfo->gateWay != 0)
strcpy(tempBuf, (char *)inet_ntoa(rtInfo->gateWay));
else
sprintf(tempBuf,"*.*.*.*\t\t");
fprintf(stdout,"%s\t\t", tempBuf);
/* Print Interface Name*/
fprintf(stdout,"%s\t\t", rtInfo->ifName);
/* Print Source address */
if (rtInfo->srcAddr != 0)
strcpy(tempBuf, (char *)inet_ntoa(rtInfo->srcAddr));
else
sprintf(tempBuf,"*.*.*.*\t\t");
if (rtInfo->dstMask != 0) {
struct in_addr ia;
ia.s_addr = htonl(netmask_from_bitcount(rtInfo->dstMask));
sprintf(tempBuf, "%s\t", inet_ntoa(ia));
} else {
sprintf(tempBuf, "0.0.0.0\t");
}
fprintf(stdout,"%s\n", tempBuf);
}
void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo, char *find) {
struct rtmsg *rtMsg;
struct rtattr *rtAttr;
int rtLen;
char *tempBuf = NULL;
struct in_addr ai;
if (!inet_aton(find, &ai)) {
return;
}
tempBuf = (char *)malloc(100);
rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
/* If the route is not for AF_INET or does not belong to main routing table
then return. */
if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
return;
/* get the rtattr field */
rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
rtLen = RTM_PAYLOAD(nlHdr);
rtInfo->dstMask = rtMsg->rtm_dst_len; /* Netmask */
for( ; RTA_OK(rtAttr,rtLen);rtAttr = RTA_NEXT(rtAttr,rtLen)) {
switch(rtAttr->rta_type){
case RTA_OIF:
if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);
break;
case RTA_GATEWAY:
rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr);
break;
case RTA_PREFSRC:
rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr);
break;
case RTA_DST:
rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr);
break;
}
}
/*
if (rtInfo->dstAddr == ai.s_addr) {
printf("match %s\n", inet_ntoa(rtInfo->dstAddr));
return;
}
*/
printRoute(rtInfo);
free(tempBuf);
return;
}
int main(int argc, char *argv[]) {
struct nlmsghdr *nlMsg;
struct rtmsg *rtMsg;
struct route_info *rtInfo;
char msgBuf[BUFSIZE];
int sock, len, msgSeq = 0;
char buff[1024];
/* Create Socket */
if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
perror("Socket Creation: ");
/* Initialize the buffer */
memset(msgBuf, 0, BUFSIZE);
/* point the header and the msg structure pointers into the buffer */
nlMsg = (struct nlmsghdr *)msgBuf;
rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
/* Fill in the nlmsg header*/
nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
nlMsg->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; // The message is a request for dump.
nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
char *cp;
unsigned int xx[4]; int i = 0;
unsigned char *ap = (unsigned char *)xx;
for (cp = argv[1], i = 0; *cp; cp++) {
if (*cp <= '9' && *cp >= '0') {
ap[i] = 10*ap[i] + (*cp-'0');
continue;
}
if (*cp == '.' && ++i <= 3)
continue;
return -1;
}
NetlinkAddAttr(nlMsg, sizeof(nlMsg), RTA_DST, &xx, 4);
/* Send the request */
if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0){
printf("Write To Socket Failed...\n");
return -1;
}
/* Read the response */
if((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0) {
printf("Read From Socket Failed...\n");
return -1;
}
/* Parse and print the response */
rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
fprintf(stdout, "Destination\t\tGateway\t\tInterface\t\tSource\t\tNetmask\n");
for( ; NLMSG_OK(nlMsg,len); nlMsg = NLMSG_NEXT(nlMsg,len)) {
memset(rtInfo, 0, sizeof(struct route_info));
parseRoutes(nlMsg, rtInfo, argv[1]);
}
free(rtInfo);
close(sock);
return 0;
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: receive only one record from the routing table
2005-06-17 13:51 receive only one record from the routing table Tomáš Macek
@ 2005-06-17 14:15 ` Thomas Graf
2005-06-17 18:57 ` Tomáš Macek
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Graf @ 2005-06-17 14:15 UTC (permalink / raw)
To: Tomá? Macek; +Cc: netdev
* Tom?? Macek <Pine.LNX.4.61.0506171359490.31631@localhost.localdomain> 2005-06-17 14:51
> nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
> nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
>
> nlMsg->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; // The message is a request for dump.
Omit NLM_F_DUMP and you'll be fine, see rfc3549.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: receive only one record from the routing table
2005-06-17 14:15 ` Thomas Graf
@ 2005-06-17 18:57 ` Tomáš Macek
2005-06-17 19:13 ` Thomas Graf
0 siblings, 1 reply; 8+ messages in thread
From: Tomáš Macek @ 2005-06-17 18:57 UTC (permalink / raw)
To: netdev
Part of my routing table is here:
3.3.0.0 * 255.255.0.0 U 0 0 0 eth1
default meric 0.0.0.0 UG 0 0 0 eth0
Ommiting NLM_F_DUMP and typing './a.out 3.3.0.0' gives
Error in recieved packet: Success
Read From Socket Failed...
and I don't see the reason why... I think, it should write something with the 3.3.0.0 destination, but writes the error above instead
On Fri, 17 Jun 2005, Thomas Graf wrote:
> * Tom?? Macek <Pine.LNX.4.61.0506171359490.31631@localhost.localdomain> 2005-06-17 14:51
>> nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
>> nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
>>
>> nlMsg->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; // The message is a request for dump.
>
> Omit NLM_F_DUMP and you'll be fine, see rfc3549.
>
>
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: receive only one record from the routing table
2005-06-17 18:57 ` Tomáš Macek
@ 2005-06-17 19:13 ` Thomas Graf
2005-06-18 18:55 ` Tomáš Macek
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Graf @ 2005-06-17 19:13 UTC (permalink / raw)
To: Tomá? Macek; +Cc: netdev
* Tom?? Macek <Pine.LNX.4.61.0506172057240.26739@localhost.localdomain> 2005-06-17 20:57
> Part of my routing table is here:
>
> 3.3.0.0 * 255.255.0.0 U 0 0 0 eth1
> default meric 0.0.0.0 UG 0 0 0 eth0
>
> Ommiting NLM_F_DUMP and typing './a.out 3.3.0.0' gives
>
> Error in recieved packet: Success
> Read From Socket Failed...
Bcause you don't set rtm_dst_len to the prefix length or 32,
and rtm_family (AF_INET). You could also use libnl, probably
easier to use.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: receive only one record from the routing table
2005-06-17 19:13 ` Thomas Graf
@ 2005-06-18 18:55 ` Tomáš Macek
2005-06-18 20:23 ` Thomas Graf
0 siblings, 1 reply; 8+ messages in thread
From: Tomáš Macek @ 2005-06-18 18:55 UTC (permalink / raw)
To: netdev
Thanks for your answers.
I just tried to compile the libnl, but some errors occured, so I'm just continuing without it.
But I've looked at the html documentation and it seems to be very good.
I repaired the main() function by adding the
rtMsg->rtm_family = AF_INET;
rtMsg->rtm_dst_len = 16;
but every request on any dst address in the routing table gives me this output:
Destination Gateway Interface Source Netmask
127.0.0.1 *.*.*.* lo 255.255.255.255
The 'rtm_dst_len = 16' should mean the mask of the route I'm looking for, correct? The whole code before sending the packet is below:
/* Create Socket */
if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
perror("Socket Creation: ");
/* Initialize the buffer */
memset(msgBuf, 0, BUFSIZE);
/* point the header and the msg structure pointers into the buffer */
nlMsg = (struct nlmsghdr *)msgBuf;
rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
rtMsg->rtm_family = AF_INET;
rtMsg->rtm_dst_len = 16;
/* Fill in the nlmsg header*/
nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
nlMsg->nlmsg_flags = NLM_F_REQUEST; // The message is a request for dump.
nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
char *cp;
unsigned int xx[4]; int i = 0;
unsigned char *ap = (unsigned char *)xx;
for (cp = argv[1], i = 0; *cp; cp++) {
if (*cp <= '9' && *cp >= '0') {
ap[i] = 10*ap[i] + (*cp-'0');
continue;
}
if (*cp == '.' && ++i <= 3)
continue;
return -1;
}
NetlinkAddAttr(nlMsg, sizeof(nlMsg), RTA_DST, &xx, 4);
On Fri, 17 Jun 2005, Thomas Graf wrote:
> * Tom?? Macek <Pine.LNX.4.61.0506172057240.26739@localhost.localdomain> 2005-06-17 20:57
>> Part of my routing table is here:
>>
>> 3.3.0.0 * 255.255.0.0 U 0 0 0 eth1
>> default meric 0.0.0.0 UG 0 0 0 eth0
>>
>> Ommiting NLM_F_DUMP and typing './a.out 3.3.0.0' gives
>>
>> Error in recieved packet: Success
>> Read From Socket Failed...
>
> Bcause you don't set rtm_dst_len to the prefix length or 32,
> and rtm_family (AF_INET). You could also use libnl, probably
> easier to use.
>
>
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: receive only one record from the routing table
2005-06-18 18:55 ` Tomáš Macek
@ 2005-06-18 20:23 ` Thomas Graf
2005-06-22 10:07 ` Tomáš Macek
2005-06-22 13:53 ` Print one record only - addition Tomáš Macek
0 siblings, 2 replies; 8+ messages in thread
From: Thomas Graf @ 2005-06-18 20:23 UTC (permalink / raw)
To: Tomá? Macek; +Cc: netdev
* Tom?? Macek <Pine.LNX.4.61.0506182042540.29813@localhost.localdomain> 2005-06-18 20:55
> The 'rtm_dst_len = 16' should mean the mask of the route I'm looking for, correct?
Yes.
> The whole code before sending the packet is below:
>
>
> /* Create Socket */
> if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
> perror("Socket Creation: ");
>
> /* Initialize the buffer */
> memset(msgBuf, 0, BUFSIZE);
>
> /* point the header and the msg structure pointers into the buffer */
> nlMsg = (struct nlmsghdr *)msgBuf;
> rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
> rtMsg->rtm_family = AF_INET;
> rtMsg->rtm_dst_len = 16;
>
> /* Fill in the nlmsg header*/
> nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
> nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
> nlMsg->nlmsg_flags = NLM_F_REQUEST; // The message is a request for dump.
> nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
> nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
>
> char *cp;
> unsigned int xx[4]; int i = 0;
> unsigned char *ap = (unsigned char *)xx;
> for (cp = argv[1], i = 0; *cp; cp++) {
> if (*cp <= '9' && *cp >= '0') {
> ap[i] = 10*ap[i] + (*cp-'0');
> continue;
> }
> if (*cp == '.' && ++i <= 3)
> continue;
> return -1;
> }
>
> NetlinkAddAttr(nlMsg, sizeof(nlMsg), RTA_DST, &xx, 4);
This looks good but your NetlinkAddAttr is bogus, it should
be something like this:
int nl_msg_append_tlv(struct nlmsghdr *n, int type, void *data, size_t len)
{
int tlen;
struct rtattr *rta;
tlen = NLMSG_ALIGN(n->nlmsg_len) + RTA_LENGTH(NLMSG_ALIGN(len));
rta = (struct rtattr *) NLMSG_TAIL(n);
rta->rta_type = type;
rta->rta_len = RTA_LENGTH(NLMSG_ALIGN(len));
memcpy(RTA_DATA(rta), data, len);
n->nlmsg_len = tlen;
return 0;
}
Your code is missing various alignment requirements. I can't tell
whether this is the last bug. I recommend you to read ip/iproute.c
in the iproute2 source or give libnl a second chance.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: receive only one record from the routing table
2005-06-18 20:23 ` Thomas Graf
@ 2005-06-22 10:07 ` Tomáš Macek
2005-06-22 13:53 ` Print one record only - addition Tomáš Macek
1 sibling, 0 replies; 8+ messages in thread
From: Tomáš Macek @ 2005-06-22 10:07 UTC (permalink / raw)
To: netdev
>> ...or give libnl a second chance
I would like to give it second change, but when typing 'make', it outputs this:
...
Entering lib
MAKE libnl.so.0.5.1
CC helpers.c
helpers.c:417: error: `ARPHRD_EUI64' undeclared here (not in a function)
helpers.c:417: error: initializer element is not constant
helpers.c:417: error: (near initialization for `llprotos[13].i')
helpers.c:417: error: initializer element is not constant
helpers.c:417: error: (near initialization for `llprotos[13]')
helpers.c:418: error: initializer element is not constant
helpers.c:418: error: (near initialization for `llprotos[14]')
helpers.c:419: error: initializer element is not constant
helpers.c:419: error: (near initialization for `llprotos[15]')
helpers.c:420: error: initializer element is not constant
helpers.c:420: error: (near initialization for `llprotos[16]')
helpers.c:421: error: initializer element is not constant
helpers.c:421: error: (near initialization for `llprotos[17]')
...
On Sat, 18 Jun 2005, Thomas Graf wrote:
> * Tom?? Macek <Pine.LNX.4.61.0506182042540.29813@localhost.localdomain> 2005-06-18 20:55
>> The 'rtm_dst_len = 16' should mean the mask of the route I'm looking for, correct?
>
> Yes.
>
>> The whole code before sending the packet is below:
>>
>>
>> /* Create Socket */
>> if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
>> perror("Socket Creation: ");
>>
>> /* Initialize the buffer */
>> memset(msgBuf, 0, BUFSIZE);
>>
>> /* point the header and the msg structure pointers into the buffer */
>> nlMsg = (struct nlmsghdr *)msgBuf;
>> rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
>> rtMsg->rtm_family = AF_INET;
>> rtMsg->rtm_dst_len = 16;
>>
>> /* Fill in the nlmsg header*/
>> nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
>> nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
>> nlMsg->nlmsg_flags = NLM_F_REQUEST; // The message is a request for dump.
>> nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
>> nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
>>
>> char *cp;
>> unsigned int xx[4]; int i = 0;
>> unsigned char *ap = (unsigned char *)xx;
>> for (cp = argv[1], i = 0; *cp; cp++) {
>> if (*cp <= '9' && *cp >= '0') {
>> ap[i] = 10*ap[i] + (*cp-'0');
>> continue;
>> }
>> if (*cp == '.' && ++i <= 3)
>> continue;
>> return -1;
>> }
>>
>> NetlinkAddAttr(nlMsg, sizeof(nlMsg), RTA_DST, &xx, 4);
>
> This looks good but your NetlinkAddAttr is bogus, it should
> be something like this:
>
> int nl_msg_append_tlv(struct nlmsghdr *n, int type, void *data, size_t len)
> {
> int tlen;
> struct rtattr *rta;
>
> tlen = NLMSG_ALIGN(n->nlmsg_len) + RTA_LENGTH(NLMSG_ALIGN(len));
>
> rta = (struct rtattr *) NLMSG_TAIL(n);
> rta->rta_type = type;
> rta->rta_len = RTA_LENGTH(NLMSG_ALIGN(len));
> memcpy(RTA_DATA(rta), data, len);
> n->nlmsg_len = tlen;
>
> return 0;
> }
>
> Your code is missing various alignment requirements. I can't tell
> whether this is the last bug. I recommend you to read ip/iproute.c
> in the iproute2 source or give libnl a second chance.
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Print one record only - addition
2005-06-18 20:23 ` Thomas Graf
2005-06-22 10:07 ` Tomáš Macek
@ 2005-06-22 13:53 ` Tomáš Macek
1 sibling, 0 replies; 8+ messages in thread
From: Tomáš Macek @ 2005-06-22 13:53 UTC (permalink / raw)
To: netdev
On Sat, 18 Jun 2005, Thomas Graf wrote:
> * Tom?? Macek <Pine.LNX.4.61.0506182042540.29813@localhost.localdomain> 2005-06-18 20:55
>> The 'rtm_dst_len = 16' should mean the mask of the route I'm looking for, correct?
>
> Yes.
>
>> The whole code before sending the packet is below:
>>
>>
>> /* Create Socket */
>> if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
>> perror("Socket Creation: ");
>>
>> /* Initialize the buffer */
>> memset(msgBuf, 0, BUFSIZE);
>>
>> /* point the header and the msg structure pointers into the buffer */
>> nlMsg = (struct nlmsghdr *)msgBuf;
>> rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
>> rtMsg->rtm_family = AF_INET;
>> rtMsg->rtm_dst_len = 16;
>>
>> /* Fill in the nlmsg header*/
>> nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
>> nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
>> nlMsg->nlmsg_flags = NLM_F_REQUEST; // The message is a request for dump.
>> nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
>> nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
>>
>> char *cp;
>> unsigned int xx[4]; int i = 0;
>> unsigned char *ap = (unsigned char *)xx;
>> for (cp = argv[1], i = 0; *cp; cp++) {
>> if (*cp <= '9' && *cp >= '0') {
>> ap[i] = 10*ap[i] + (*cp-'0');
>> continue;
>> }
>> if (*cp == '.' && ++i <= 3)
>> continue;
>> return -1;
>> }
>>
>> NetlinkAddAttr(nlMsg, sizeof(nlMsg), RTA_DST, &xx, 4);
>
> This looks good but your NetlinkAddAttr is bogus, it should
> be something like this:
>
> int nl_msg_append_tlv(struct nlmsghdr *n, int type, void *data, size_t len)
> {
> int tlen;
> struct rtattr *rta;
>
> tlen = NLMSG_ALIGN(n->nlmsg_len) + RTA_LENGTH(NLMSG_ALIGN(len));
>
> rta = (struct rtattr *) NLMSG_TAIL(n);
> rta->rta_type = type;
> rta->rta_len = RTA_LENGTH(NLMSG_ALIGN(len));
> memcpy(RTA_DATA(rta), data, len);
> n->nlmsg_len = tlen;
>
> return 0;
> }
>
> Your code is missing various alignment requirements. I can't tell
> whether this is the last bug. I recommend you to read ip/iproute.c
> in the iproute2 source or give libnl a second chance.
>
The code now works this way:
[root@localhost route]# route
1.1.1.0 * 255.255.255.0 U 0 0 0 eth0
3.3.0.0 * 255.255.0.0 U 0 0 0 eth1
default meric 0.0.0.0 UG 0 0 0 eth0
[root@localhost route]# ./a.out 2.2.2.2 16
Destination Gateway Interface Source Netmask
2.2.2.2 213.250.192.33 eth0 255.255.255.255
[root@localhost route]# ./a.out 1.1.1.2 16
Destination Gateway Interface Source Netmask
1.1.1.2 *.*.*.* eth0 255.255.255.255
[root@localhost route]# ./a.out 3.3.3.2 16
Destination Gateway Interface Source Netmask
3.3.3.2 *.*.*.* eth1 255.255.255.255
so it returns the route, where the data would go, if their DST address would be the one given by the argv[1] with mask argv[2].
I don't know now, if we understood to each other and if this is you thought it should be.
If I will write on the command line './a.out 3.3.0.0 16', it should print the line like this if the record is present:
3.3.0.0 * 255.255.0.0 U 0 0 0 eth1
if I would write './a.out 3.3.3.1 32' it MUST print nothing! :)
Thank you for help
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2005-06-22 13:53 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-17 13:51 receive only one record from the routing table Tomáš Macek
2005-06-17 14:15 ` Thomas Graf
2005-06-17 18:57 ` Tomáš Macek
2005-06-17 19:13 ` Thomas Graf
2005-06-18 18:55 ` Tomáš Macek
2005-06-18 20:23 ` Thomas Graf
2005-06-22 10:07 ` Tomáš Macek
2005-06-22 13:53 ` Print one record only - addition Tomáš Macek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).