1999-02-19 03:21:36 +03:00
/*
* Copyright ( c ) 1993 , 1994 , 1995 , 1996 Rick Sladkey < jrs @ world . std . com >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "defs.h"
# include <sys/socket.h>
2004-07-12 11:13:06 +04:00
# include <linux/sockios.h>
# include <arpa/inet.h>
2012-02-25 05:47:15 +04:00
# if defined(ALPHA) || defined(SH) || defined(SH64)
2012-03-16 15:02:22 +04:00
# if defined(HAVE_SYS_IOCTL_H)
2012-02-25 05:47:15 +04:00
# include <sys / ioctl.h>
# elif defined(HAVE_IOCTLS_H)
# include <ioctls.h>
# endif
1999-05-09 04:29:58 +04:00
# endif
2004-07-12 11:13:06 +04:00
# include <net/if.h>
2014-04-26 03:30:54 +04:00
# include "xlat/iffflags.h"
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
static void
2015-07-04 14:01:08 +03:00
print_ifreq_addr ( struct tcb * tcp , const struct ifreq * ifr , const long addr )
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
{
2015-07-04 14:01:08 +03:00
tprintf ( " { " ) ;
printxval ( addrfams , ifr - > ifr_addr . sa_family , " AF_??? " ) ;
tprints ( " , " ) ;
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
if ( ifr - > ifr_addr . sa_family = = AF_INET ) {
2015-07-04 14:01:08 +03:00
const struct sockaddr_in * sinp =
( struct sockaddr_in * ) & ifr - > ifr_addr ;
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
tprintf ( " inet_addr( \" %s \" ) " , inet_ntoa ( sinp - > sin_addr ) ) ;
} else
2015-07-04 14:01:08 +03:00
printstr ( tcp , addr + offsetof ( struct ifreq , ifr_addr . sa_data ) ,
sizeof ( ifr - > ifr_addr . sa_data ) ) ;
tprints ( " } " ) ;
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
}
2015-01-24 23:58:23 +03:00
static void
print_ifname ( const char * ifname )
{
print_quoted_string ( ifname , IFNAMSIZ + 1 , QUOTE_0_TERMINATED ) ;
}
2015-07-04 14:01:08 +03:00
static void
print_ifreq ( struct tcb * tcp , const unsigned int code , const long arg ,
const struct ifreq * ifr )
{
switch ( code ) {
case SIOCSIFADDR :
case SIOCGIFADDR :
tprints ( " ifr_addr= " ) ;
print_ifreq_addr ( tcp , ifr , arg ) ;
break ;
case SIOCSIFDSTADDR :
case SIOCGIFDSTADDR :
tprints ( " ifr_dstaddr= " ) ;
print_ifreq_addr ( tcp , ifr , arg ) ;
break ;
case SIOCSIFBRDADDR :
case SIOCGIFBRDADDR :
tprints ( " ifr_broadaddr= " ) ;
print_ifreq_addr ( tcp , ifr , arg ) ;
break ;
case SIOCSIFNETMASK :
case SIOCGIFNETMASK :
tprints ( " ifr_netmask= " ) ;
print_ifreq_addr ( tcp , ifr , arg ) ;
break ;
case SIOCSIFHWADDR :
case SIOCGIFHWADDR : {
/* XXX Are there other hardware addresses
than 6 - byte MACs ? */
const unsigned char * bytes =
( unsigned char * ) & ifr - > ifr_hwaddr . sa_data ;
tprintf ( " ifr_hwaddr=%02x:%02x:%02x:%02x:%02x:%02x " ,
bytes [ 0 ] , bytes [ 1 ] , bytes [ 2 ] ,
bytes [ 3 ] , bytes [ 4 ] , bytes [ 5 ] ) ;
break ;
}
case SIOCSIFFLAGS :
case SIOCGIFFLAGS :
tprints ( " ifr_flags= " ) ;
printflags ( iffflags , ifr - > ifr_flags , " IFF_??? " ) ;
break ;
case SIOCSIFMETRIC :
case SIOCGIFMETRIC :
tprintf ( " ifr_metric=%d " , ifr - > ifr_metric ) ;
break ;
case SIOCSIFMTU :
case SIOCGIFMTU :
tprintf ( " ifr_mtu=%d " , ifr - > ifr_mtu ) ;
break ;
case SIOCSIFSLAVE :
case SIOCGIFSLAVE :
tprints ( " ifr_slave= " ) ;
print_ifname ( ifr - > ifr_slave ) ;
break ;
case SIOCSIFTXQLEN :
case SIOCGIFTXQLEN :
tprintf ( " ifr_qlen=%d " , ifr - > ifr_qlen ) ;
break ;
case SIOCSIFMAP :
case SIOCGIFMAP :
tprintf ( " ifr_map={mem_start=%#lx, "
" mem_end=%#lx, base_addr=%#x, "
" irq=%u, dma=%u, port=%u} " ,
ifr - > ifr_map . mem_start ,
ifr - > ifr_map . mem_end ,
( unsigned ) ifr - > ifr_map . base_addr ,
( unsigned ) ifr - > ifr_map . irq ,
( unsigned ) ifr - > ifr_map . dma ,
( unsigned ) ifr - > ifr_map . port ) ;
break ;
}
}
static unsigned int
print_ifc_len ( int len )
{
const unsigned int n = ( unsigned int ) len / sizeof ( struct ifreq ) ;
if ( len < 0 | | n * sizeof ( struct ifreq ) ! = ( unsigned int ) len )
tprintf ( " %d " , len ) ;
else
tprintf ( " %u * sizeof(struct ifreq) " , n ) ;
return n ;
}
static int
decode_ifconf ( struct tcb * tcp , const long addr )
1999-02-19 03:21:36 +03:00
{
2004-07-12 11:13:06 +04:00
struct ifconf ifc ;
if ( entering ( tcp ) ) {
2015-07-04 14:01:08 +03:00
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , addr , & ifc ) )
return RVAL_DECODED | 1 ;
if ( ifc . ifc_buf ) {
tprints ( " { " ) ;
print_ifc_len ( ifc . ifc_len ) ;
2004-07-12 11:13:06 +04:00
}
2015-07-04 14:01:08 +03:00
return 1 ;
}
if ( syserror ( tcp ) | | umove ( tcp , addr , & ifc ) < 0 ) {
if ( ifc . ifc_buf )
tprints ( " } " ) ;
else
printaddr ( addr ) ;
return RVAL_DECODED | 1 ;
2004-07-12 11:13:06 +04:00
}
1999-02-19 03:21:36 +03:00
2015-07-04 14:01:08 +03:00
if ( ! ifc . ifc_buf ) {
tprints ( " { " ) ;
print_ifc_len ( ifc . ifc_len ) ;
tprints ( " , NULL} " ) ;
return RVAL_DECODED | 1 ;
}
tprints ( " => " ) ;
const unsigned int nifra = print_ifc_len ( ifc . ifc_len ) ;
if ( ! nifra ) {
tprints ( " } " ) ;
return RVAL_DECODED | 1 ;
}
struct ifreq ifra [ nifra > max_strlen ? max_strlen : nifra ] ;
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , ( unsigned long ) ifc . ifc_buf , & ifra ) ) {
tprints ( " } " ) ;
return RVAL_DECODED | 1 ;
}
tprints ( " [ " ) ;
unsigned int i ;
for ( i = 0 ; i < ARRAY_SIZE ( ifra ) ; + + i ) {
if ( i > 0 )
tprints ( " , " ) ;
tprints ( " {ifr_name= " ) ;
print_ifname ( ifra [ i ] . ifr_name ) ;
tprints ( " , " ) ;
if ( verbose ( tcp ) ) {
tprints ( " ifr_addr= " ) ;
print_ifreq_addr ( tcp , & ifra [ i ] ,
addr + i * sizeof ( ifra [ 0 ] ) ) ;
} else
tprints ( " ... " ) ;
tprints ( " } " ) ;
}
if ( i < nifra )
tprints ( " , ... " ) ;
tprints ( " ]} " ) ;
return RVAL_DECODED | 1 ;
}
int
sock_ioctl ( struct tcb * tcp , const unsigned int code , const long arg )
{
struct ifreq ifr ;
1999-02-19 03:21:36 +03:00
switch ( code ) {
2015-07-04 14:01:08 +03:00
case SIOCGIFCONF :
return decode_ifconf ( tcp , arg ) ;
# ifdef SIOCBRADDBR
case SIOCBRADDBR :
case SIOCBRDELBR :
tprints ( " , " ) ;
printstr ( tcp , arg , - 1 ) ;
break ;
1999-02-19 03:21:36 +03:00
# endif
2015-07-04 14:01:08 +03:00
1999-02-19 03:21:36 +03:00
# ifdef FIOSETOWN
case FIOSETOWN :
# endif
# ifdef SIOCSPGRP
case SIOCSPGRP :
2015-07-04 14:01:08 +03:00
# endif
tprints ( " , " ) ;
printnum_int ( tcp , arg , " %d " ) ;
break ;
# ifdef FIOGETOWN
case FIOGETOWN :
1999-02-19 03:21:36 +03:00
# endif
# ifdef SIOCGPGRP
case SIOCGPGRP :
# endif
# ifdef SIOCATMARK
case SIOCATMARK :
# endif
2015-07-04 14:01:08 +03:00
if ( entering ( tcp ) )
return 0 ;
tprints ( " , " ) ;
printnum_int ( tcp , arg , " %d " ) ;
break ;
# ifdef SIOCBRADDIF
case SIOCBRADDIF :
# endif
# ifdef SIOCBRDELIF
case SIOCBRDELIF :
# endif
/* no arguments */
break ;
2014-10-31 22:36:01 +03:00
case SIOCSIFNAME :
2015-07-04 14:01:08 +03:00
case SIOCSIFADDR :
case SIOCSIFDSTADDR :
case SIOCSIFBRDADDR :
case SIOCSIFNETMASK :
case SIOCSIFFLAGS :
case SIOCSIFMETRIC :
case SIOCSIFMTU :
case SIOCSIFSLAVE :
case SIOCSIFHWADDR :
case SIOCSIFTXQLEN :
case SIOCSIFMAP :
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , arg , & ifr ) )
break ;
tprints ( " {ifr_name= " ) ;
print_ifname ( ifr . ifr_name ) ;
tprints ( " , " ) ;
if ( code = = SIOCSIFNAME ) {
tprints ( " ifr_newname= " ) ;
print_ifname ( ifr . ifr_newname ) ;
} else {
print_ifreq ( tcp , code , arg , & ifr ) ;
}
tprints ( " } " ) ;
break ;
2004-07-12 11:13:06 +04:00
case SIOCGIFNAME :
case SIOCGIFINDEX :
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
case SIOCGIFADDR :
case SIOCGIFDSTADDR :
case SIOCGIFBRDADDR :
case SIOCGIFNETMASK :
case SIOCGIFFLAGS :
case SIOCGIFMETRIC :
case SIOCGIFMTU :
case SIOCGIFSLAVE :
case SIOCGIFHWADDR :
2007-03-21 16:52:14 +03:00
case SIOCGIFTXQLEN :
2007-03-21 16:57:50 +03:00
case SIOCGIFMAP :
2015-07-04 14:01:08 +03:00
if ( entering ( tcp ) ) {
tprints ( " , " ) ;
if ( umove_or_printaddr ( tcp , arg , & ifr ) )
break ;
if ( SIOCGIFNAME = = code ) {
tprintf ( " {ifr_index=%d " , ifr . ifr_ifindex ) ;
2014-10-21 16:34:08 +04:00
} else {
2015-07-04 14:01:08 +03:00
tprints ( " {ifr_name= " ) ;
2015-01-24 23:58:23 +03:00
print_ifname ( ifr . ifr_name ) ;
2014-10-21 16:34:08 +04:00
}
2015-07-04 14:01:08 +03:00
return 1 ;
2014-10-21 16:34:08 +04:00
} else {
2015-07-04 14:01:08 +03:00
if ( syserror ( tcp ) ) {
2011-09-01 12:00:28 +04:00
tprints ( " } " ) ;
2005-02-02 Roland McGrath <roland@redhat.com>
* sock.c (iffflags): New variable, table of IFF_* values.
(print_addr): New function.
(sock_ioctl): Handle SIOCGIFADDR, SIOCGIFDSTADDR, SIOCGIFBRDADDR,
SIOCGIFNETMASK, SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFSLAVE,
SIOCGIFHWADDR. Use print_addr for SIOCGIFCONF, SIOCGIFNAME, and
SIOCGIFINDEX, and fix their output.
From Ulrich Drepper <drepper@redhat.com>.
Fixes RH#138223.
2005-02-02 23:25:17 +03:00
break ;
}
2009-11-03 17:38:44 +03:00
2015-07-04 14:01:08 +03:00
tprints ( " , " ) ;
if ( umove ( tcp , arg , & ifr ) < 0 ) {
tprints ( " ???} " ) ;
break ;
2009-11-03 17:38:44 +03:00
}
2015-07-04 14:01:08 +03:00
if ( SIOCGIFNAME = = code ) {
tprints ( " ifr_name= " ) ;
print_ifname ( ifr . ifr_name ) ;
} else {
print_ifreq ( tcp , code , arg , & ifr ) ;
2004-07-12 11:13:06 +04:00
}
2011-09-01 12:00:28 +04:00
tprints ( " } " ) ;
2015-07-04 14:01:08 +03:00
break ;
2004-07-12 11:13:06 +04:00
}
2015-07-04 14:01:08 +03:00
1999-02-19 03:21:36 +03:00
default :
2015-07-04 14:01:08 +03:00
return RVAL_DECODED ;
1999-02-19 03:21:36 +03:00
}
2015-07-04 14:01:08 +03:00
return RVAL_DECODED | 1 ;
1999-02-19 03:21:36 +03:00
}