Modify

Opened 3 years ago

Closed 3 years ago

#17689 closed task (not_a_bug)

Failed to get eth0 interface using "ioctl" systemcall

Reported by: vinikiri@… Owned by: developers
Priority: normal Milestone: Attitude Adjustment 12.09.1
Component: packages Version: Trunk
Keywords: Cc:

Description

Hi,

I am writing multicast routing daemon in userspace which does adding VIf entry and MFC entry to multicat routing table.so tried get all the network interface available using "getifaddrs" system call and also tried with ioctl system call . i am getting wlan (wifi interface ) and loop back lo interafce but "eth0" interface (upstream ) is missing. below are code snippet and network interface details.

below etc/config/network entries

config interface 'loopback'

option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config interface 'lan'

option ifname 'eth0'
option proto 'static'
option ipaddr '192.168.15.1'
option netmask '255.255.255.0'
option force 'true'
option _tec_preferred_id '1'
option _tec_br_id 'tecbr_1065484874325433_649346062'
option _tec_br_iid '1'
list _tec_br_port_iids '1'
list _tec_br_port_iids '2'

config interface 'lan_debug'

option ifname 'eth1'
option proto 'static'
option ipaddr '192.168.16.1'
option netmask '255.255.255.0'
option force 'true'
option _tec_preferred_id '2'
option _tec_br_id 'tecbr_1065484874339552_1887091196'
option _tec_br_iid '2'
list _tec_br_port_iids '1'

config interface 'wlan'

option proto 'static'
option ipaddr '192.168.20.1'
option netmask '255.255.255.0'
option ifname 'uap0'
option _tec_preferred_id '3'
option _tec_br_id 'tecbr_1065484874343562_1987487178'
option _tec_br_iid '3'
list _tec_br_port_iids '1'
list _tec_br_port_iids '2'

config interface 'wan1'

option ifname 'icc0.1121'
option proto 'dhcp'
option ipaddr '0.0.0.0'
option netmask '255.255.255.255'
option send_rs '1'
option accept_ra '1'
option sendopts '0x7D:00000DE91B01063030313630380206303030303033030928756E6B6E6F776E29'
option _tec_br_id 'tecbr_1065484874351123_590897050'
option _tec_br_iid '4'
option _tec_preferred_id '1'
list _tec_br_port_iids '1'
list _tec_br_port_iids '3'
option bandwidth '20MHz'
option scanMode 'EARFCN'

config interface 'wan2'

option ifname 'icc0.1122'
option proto 'dhcp'
option ipaddr '0.0.0.0'
option netmask '255.255.255.255'
option send_rs '1'
option accept_ra '1'
option sendopts '0x7D:00000DE91B01063030313630380206303030303033030928756E6B6E6F776E29'
option _tec_br_id 'tecbr_1065484874355373_591761417'
option _tec_br_iid '5'
list _tec_br_port_iids '1'
list _tec_br_port_iids '2'
option _tec_preferred_id '1'

config interface 'wan3'

option ifname 'icc0.1123'
option proto 'dhcp'
option ipaddr '0.0.0.0'
option netmask '255.255.255.255'
option send_rs '1'
option accept_ra '1'
option sendopts '0x7D:00000DE91B01063030313630380206303030303033030928756E6B6E6F776E29'
option _tec_br_id 'tecbr_1065484874359649_1832587210'
option _tec_br_iid '6'
list _tec_br_port_iids '1'
list _tec_br_port_iids '2'
option _tec_preferred_id '1'

config interface 'wan4'

option ifname 'icc0.1124'
option proto 'dhcp'
option ipaddr '0.0.0.0'
option netmask '255.255.255.255'
option send_rs '1'
option accept_ra '1'
option sendopts '0x7D:00000DE91B01063030313630380206303030303033030928756E6B6E6F776E29'
option _tec_br_id 'tecbr_1065484874363796_1389399583'
option _tec_br_iid '7'
list _tec_br_port_iids '1'
list _tec_br_port_iids '2'
option _tec_preferred_id '1'

Below is ifconfig

eth0 Link encap:Ethernet HWaddr 86:89:01:74:29:73

inet addr:192.168.15.1 Bcast:192.168.15.255 Mask:255.255.255.0
inet6 addr: fe80::8489:1ff:fe74:2973/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7410 errors:0 dropped:0 overruns:0 frame:0
TX packets:3458 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:393795 (384.5 KiB) TX bytes:745984 (728.5 KiB)

icc0 Link encap:Ethernet HWaddr 00:16:08:00:00:03

inet6 addr: fe80::216:8ff:fe00:3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1536 Metric:1
RX packets:9473 errors:0 dropped:0 overruns:0 frame:0
TX packets:9491 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:780577 (762.2 KiB) TX bytes:459462 (448.6 KiB)
Interrupt:32

lo Link encap:Local Loopback

inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:39396 errors:0 dropped:0 overruns:0 frame:0
TX packets:39396 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2673791 (2.5 MiB) TX bytes:2673791 (2.5 MiB)

uap0 Link encap:Ethernet HWaddr AC:3F:A4:21:77:F9

inet addr:192.168.20.1 Bcast:192.168.20.255 Mask:255.255.255.0
inet6 addr: fe80::ae3f:a4ff:fe21:77f9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2580 errors:0 dropped:0 overruns:0 frame:0
TX packets:1405 errors:1 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:202902 (198.1 KiB) TX bytes:111079 (108.4 KiB)

Log :-
buildIfVc: Interface lo Addr: 127.0.0.1, Flags: 0x0049, Network: 127/8
buildIfVc: Interface uap0 Addr: 192.168.20.1, Flags: 0x0043, Network: 192.168.20/24

Code snippet:-

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include<malloc.h>
Linked list of networks...
struct SubnetList {

uint32_t subnet_addr;
uint32_t subnet_mask;
struct SubnetList* next;

};

struct IfDesc {

char Name[IF_NAMESIZE];
struct in_addr InAdr; /* == 0 for non IP interfaces */
short Flags;
short state;
struct SubnetList* allowednets;
unsigned int robustness;
unsigned char threshold; /* ttl limit */
unsigned int ratelimit;
unsigned int index;

};

struct IfDesc IfDescVc[ 40 ], *IfDescEp = IfDescVc;

char s1[19];

char *fmtInAdr( char *St, struct in_addr InAdr ) {

sprintf( St, "%u.%u.%u.%u",

((uint8_t *)&InAdr.s_addr)[ 0 ],
((uint8_t *)&InAdr.s_addr)[ 1 ],
((uint8_t *)&InAdr.s_addr)[ 2 ],
((uint8_t *)&InAdr.s_addr)[ 3 ] );


return St;

}

/*

  • Convert an IP address in u_long (network) format into a printable string. */

char *inetFmt(uint32_t addr, char *s) {

register u_char *a;

a = (u_char *)&addr;
sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
return(s);

}

char *inetFmts(uint32_t addr, uint32_t mask, char *s) {

register u_char *a, *m;
int bits;

if ((addr == 0) && (mask == 0)) {

sprintf(s, "default");
return(s);

}
a = (u_char *)&addr;
m = (u_char *)&mask;
bits = 33 - ffs(ntohl(mask));

if (m[3] != 0) sprintf(s, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3],

bits);

else if (m[2] != 0) sprintf(s, "%u.%u.%u/%d", a[0], a[1], a[2], bits);
else if (m[1] != 0) sprintf(s, "%u.%u/%d", a[0], a[1], bits);
else sprintf(s, "%u/%d", a[0], bits);

return(s);

}

void buildIfVc() {

struct ifreq IfVc[10];
struct ifreq *IfEp;

int Sock;

if ( (Sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )

printf( "RAW socket open\n" );

/* get If vector

*/

{

struct ifconf IoCtlReq;

IoCtlReq.ifc_buf = (void *)IfVc;
IoCtlReq.ifc_len = sizeof( IfVc );

if ( ioctl( Sock, SIOCGIFCONF, &IoCtlReq ) < 0 )

printf( "ioctl SIOCGIFCONF\n");

IfEp = (void *)((char *)IfVc + IoCtlReq.ifc_len);

}

/* loop over interfaces and copy interface info to IfDescVc

*/

{

struct ifreq *IfPt, *IfNext;

Temp keepers of interface params...
int addr, subnet, mask;

for ( IfPt = IfVc; IfPt < IfEp; IfPt = IfNext ) {

struct ifreq IfReq;
char FmtBu[ 32 ];

IfNext = (struct ifreq *)((char *)&IfPt->ifr_addr +

#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
IfPt->ifr_addr.sa_len
#else

sizeof(struct sockaddr_in)

#endif

);

if (IfNext < IfPt + 1)

IfNext = IfPt + 1;

strncpy( IfDescEp->Name, IfPt->ifr_name, sizeof( IfDescEp->Name ) );

Currently don't set any allowed nets...
IfDescEp->allowednets = NULL;

Set the index to -1 by default.

IfDescEp->index = -1;

/* don't retrieve more info for non-IP interfaces

*/

if ( IfPt->ifr_addr.sa_family != AF_INET ) {

IfDescEp->InAdr.s_addr = 0; /* mark as non-IP interface */
IfDescEp++;
continue;

}

Get the interface adress...
IfDescEp->InAdr = ((struct sockaddr_in *)&IfPt->ifr_addr)->sin_addr;
addr = IfDescEp->InAdr.s_addr;

memcpy( IfReq.ifr_name, IfDescEp->Name, sizeof( IfReq.ifr_name ) );
IfReq.ifr_addr.sa_family = AF_INET;
((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr = addr;

Get the subnet mask...
if (ioctl(Sock, SIOCGIFNETMASK, &IfReq ) < 0)

printf( "ioctl SIOCGIFNETMASK for %s\n", IfReq.ifr_name);

mask = ((struct sockaddr_in *)&IfReq.ifr_addr)->sin_addr.s_addr;
subnet = addr & mask;

/* get if flags

typical flags:
lo 0x0049 -> Running, Loopback, Up
ethx 0x1043 -> Multicast, Running, Broadcast, Up
ipppx 0x0091 -> NoArp, PointToPoint, Up
grex 0x00C1 -> NoArp, Running, Up
ipipx 0x00C1 -> NoArp, Running, Up
*/
if ( ioctl( Sock, SIOCGIFFLAGS, &IfReq ) < 0 )

printf("ioctl SIOCGIFFLAGS\n");

IfDescEp->Flags = IfReq.ifr_flags;

Insert the verified subnet as an allowed net...
IfDescEp->allowednets = (struct SubnetList *)malloc(sizeof(struct SubnetList));
if(IfDescEp->allowednets == NULL) printf("iOut of memory !");

Create the network address for the IF..
IfDescEp->allowednets->next = NULL;
IfDescEp->allowednets->subnet_mask = mask;
IfDescEp->allowednets->subnet_addr = subnet;

Set the default params for the IF...
IfDescEp->state = 1;
IF_STATE_DOWNSTREAM;
IfDescEp->robustness = 1;DEFAULT_ROBUSTNESS;
IfDescEp->threshold = 1;
DEFAULT_THRESHOLD; /* ttl limit */
IfDescEp->ratelimit =1; DEFAULT_RATELIMIT;

Debug log the result...

printf("\nibuildIfVc: Interface %s Addr: %s, Flags: 0x%d, Network: %s\n",

IfDescEp->Name,
fmtInAdr( FmtBu, IfDescEp->InAdr ),
IfDescEp->Flags,
inetFmts(subnet,mask, s1));

IfDescEp++;

}

}

close( Sock );


}

void main()
{

buildIfVc();

}

Thanks
Vinay N

Attachments (0)

Change History (1)

comment:1 Changed 3 years ago by nbd

  • Resolution set to not_a_bug
  • Status changed from new to closed

This code is quite convoluted and confusing. Since ifconfig works, you can assume that the ioctls themselves work properly as well. This does not seem like an openwrt bug to me.

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.