rota definida :SIOCADDRT falha:Inadequado ioctl para dispositivo
-
20-12-2019 - |
Pergunta
Este típico "route add default gw IP" programa dá-me erro :
SIOCADDRT falha:Inadequado ioctl para dispositivo
Eu fiz ifconfig para verificar o nome da interface.Existe um caminho para a lista de todos os approprieate ioctl para o meu dispositivo ?
int main(char** args) {
int sockfd;
struct rtentry route;
struct sockaddr_in *addr;
int err = 0;
// create the socket
if(sockfd = socket(AF_INET, SOCK_DGRAM, 0)<0){
perror("socket");
exit(1);
}
memset(&route, 0, sizeof(route));
addr = (struct sockaddr_in*) &route.rt_gateway;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr("192.168.10.1");
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;
route.rt_dev = "eth0";
route.rt_flags = RTF_UP | RTF_GATEWAY;
route.rt_metric = 0;
if ((err = ioctl(sockfd, SIOCADDRT, &route)) != 0) {
perror("SIOCADDRT failed");
exit(1);
}
}
Novo erro depois de alterar o código para:
addr = (struct sockaddr_in*) &route.rt_gateway;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr("192.168.10.1");
addr = (struct sockaddr_in*) &route.rt_dst;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr("192.168.10.3");
addr = (struct sockaddr_in*) &route.rt_genmask;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr("255.255.255.0");
gdb saída :
37 if ((err = ioctl(sockfd, SIOCADDRT, &route)) != 0) {
(gdb) p route
$1 = {rt_pad1 = 0, rt_dst = {sa_family = 2, sa_data = "\000\000\300\250\n\003\000\000\000\000\000\000\000"},
rt_gateway = {sa_family = 2, sa_data = "\000\000\300\250\n\001\000\000\000\000\000\000\000"},
rt_genmask = {sa_family = 2, sa_data = "\000\000\377\377\377\000\000\000\000\000\000\000\000"},
rt_flags = 3, rt_pad2 = 0, rt_pad3 = 0, rt_tos = 0 '\000', rt_class = 0 '\000', rt_pad4 = {0, 0, 0},
rt_metric = 0, rt_dev = 0x4008af "em1", rt_mtu = 0, rt_window = 0, rt_irtt = 0}
(gdb) n
38 perror("SIOCADDRT failed");
(gdb)
SIOCADDRT failed: Invalid argument
Solução
Eu acho que o erro está aqui:
// create the socket
if(sockfd = socket(AF_INET, SOCK_DGRAM, 0)<0)
A expressão socket(AF_INET, SOCK_DGRAM, 0)<0
é avaliada antes de atribuição.Isso acontece porque atribuição os operadores de menor precedência de chamadas de função e comparações.Você pode ler mais sobre isso nesse artigo da wikipédia:
Então, o que você realmente é:
// create the socket
if(sockfd = (socket(AF_INET, SOCK_DGRAM, 0)<0))
Que avalia:
// create the socket
if(sockfd = 0)
Então você está tentando executar um ioctl()
no descritor de arquivo inválido.
Enrole a atribuição em parênteses ou mover a expressão de condição, como este:
// create the socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0)
Pelo caminho, o GCC ou o Clang deve detectá-lo se você passar -Wall
opção.