2013-07-15 2 views
3

J'essaie de définir la passerelle par défaut de ma machine via SIOCADDRT et ioctl(). J'ai trouvé l'extrait suivant en ligne qui fonctionne très bien:Spécifier l'interface lors de l'ajout de la passerelle par défaut via SIOCADDRT

int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 

struct rtentry route; 
memset(&route, 0, sizeof(route)); 

struct sockaddr_in *addr = (struct sockaddr_in *)&route.rt_gateway; 
addr->sin_family = AF_INET; 
addr->sin_addr.s_addr = inet_addr("10.0.2.2"); 

addr = (struct sockaddr_in*) &route.rt_dst; 
addr->sin_family = AF_INET; 
addr->sin_addr.s_addr = INADDR_ANY; 

addr = (struct sockaddr_in*) &route.rt_genmask; 
addr->sin_family = AF_INET; 
addr->sin_addr.s_addr = INADDR_ANY; 

// TODO Add the interface name to the request 
route.rt_flags = RTF_UP | RTF_GATEWAY; 
route.rt_metric = 0; 

int rc = ioctl(fd, SIOCADDRT, &route); 
// [...] 

Maintenant pour le TODO dans cet extrait ... Comment spécifier en fait l'interface à utiliser? Quand j'exécute ce code, il semble par défaut eth0 sur ma machine (qui est ma seule interface). La définition de la struct rt_entry dans l'en-tête route.h est le suivant (Également disponible here):

/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ 
    struct rtentry { 
    unsigned long rt_pad1; 
    struct sockaddr rt_dst;  /* target address  */ 
    struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ 
    struct sockaddr rt_genmask; /* target network mask (IP) */ 
    unsigned short rt_flags; 
    short  rt_pad2; 
    unsigned long rt_pad3; 
    void  *rt_pad4; 
    short  rt_metric; /* +1 for binary compatibility! */ 
    char *rt_dev; /* forcing the device at add */ 
    unsigned long rt_mtu;  /* per route MTU/Window  */ 
    #define rt_mss rt_mtu   /* Compatibility :-(   */ 
    unsigned long rt_window; /* Window clamping  */ 
    unsigned short rt_irtt; /* Initial RTT   */ 
}; 

thx pour toute aide.

Répondre

4

Apparemment, il y a deux champs que vous pouvez utiliser pour spécifier l'interface:

struct IFNET * rt_ifp;

struct ifaddr * rt_ifa;

Ces deux champs représentent la "réponse", pour ainsi dire, à la question posée par une recherche de route ; c'est-à-dire qu'ils nomment l'interface et l'adresse d'interface utilisés pour envoyer un paquet à la destination ou à l'ensemble de destinations que représente cette route.

Mise à jour: Il y a un champ rt_dev dans le sturct, je pense que vous pouvez définir au nom de l'interface:

char ifname[] = "eth1"; 
rtentry.rt_dev = ifname; 
+0

Je l'ai vu ces drapeaux dans les specs en ligne aussi, mais ma version du les en-têtes n'ont pas ces champs. Je vais éditer ma question. – DeX3

+0

mine non plus, je pense que c'est 'rt_dev' pas sûr de la façon de le configurer, probablement un index d'interface, pouvez-vous essayer cela? – iabdalkader

+1

c'est en fait un 'char *' donc je pense que c'est le nom de l'interface – iabdalkader

Questions connexes