/*
* This program tries how to set an ip to a network interface without having to call extra commands
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
typedef unsigned char u8;
typedef unsigned short u16;
int fd;
int set_interface(char *interface);
struct ifreq *req;
//Get the ip string from a sockaddr_in
char *addr2str(struct sockaddr_in *sock) {
char *ret;
union {
char car[4];
__u32 ent;
} ipv4_addr;
ipv4_addr.ent=sock->sin_addr.s_addr;
union {
char car[4];
__u32 ent;
} ipv4_port;
ipv4_port.ent=sock->sin_port;
asprintf(&ret, "%hhu.%hhu.%hhu.%hhu", ipv4_port.car[0], ipv4_port.car[1], ipv4_addr.car[0], ipv4_addr.car[1]);
return ret;
}
//Get a sockaddr_in structure, with an ip string
struct sockaddr_in *str2addr(char *addresse) {
struct sockaddr_in *ret=malloc(sizeof(struct sockaddr_in));
ret->sin_family=AF_INET;
//Separate both parts of the address
//Get the port part
union {
char car[4];
__u32 ent;
} ipv4_port;
ipv4_port.car[2]=0;
ipv4_port.car[3]=0;
sscanf(addresse, "%hhu.%hhu.%hhu.%hhu", &(ipv4_port.car[0]), &(ipv4_port.car[1]), &(ipv4_port.car[2]), &(ipv4_port.car[3]));
ret->sin_addr.s_addr=ipv4_port.ent;
return ret;
}
//Takes the interface and the ip as arguments and set the ip to the interface
int setaddr(char *interface, char *ip) {
if(set_interface(interface)!=0)
return -1;
if(ioctl(fd, SIOCGIFADDR, req)!=0)
return -1;
struct sockaddr *socket=(struct sockaddr*)str2addr(ip);
req->ifr_addr=*socket;
if(ioctl(fd, SIOCSIFADDR, req)!=0)
return -1;
return 0;
}
//Set the current if_req
int set_interface(char *interface) {
strcpy(req->ifr_name, interface);
if(ioctl(fd, SIOCGIFFLAGS, req)!=0) {
return -1;
}
return 0;
}
//Get the current address of a network interface
char *getaddr(char *interface) {
if(set_interface(interface)==-1)
return NULL;
if(ioctl(fd, SIOCGIFADDR, req)!=0)
return NULL;
return addr2str((struct sockaddr_in*)req->ifr_addr.sa_data);
}
int main(int argc, char **argv, char **envp) {
int i;
struct if_nameindex *index;
fd=socket(PF_PACKET, SOCK_RAW, 0);
req=malloc(sizeof(struct ifreq));
index=if_nameindex();
//Let's navigate into available interfaces
for(i=0;index[i].if_name!=NULL;i++) {
if(strstr(index[i].if_name, "ath")==index[i].if_name ) {
struct sockaddr_ll addr;
bzero(&addr, sizeof(addr));
addr.sll_family=AF_PACKET;
addr.sll_protocol=htons(0x03);
addr.sll_pkttype=PACKET_HOST;
addr.sll_ifindex=index[i].if_index;
addr.sll_halen=0;
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
char str[]="\5\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0";
str[0]=index[i].if_index;
setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, str, 16);
{
u8 *framehdr=malloc(60);
int i;
for(i=0;i<60;i++)
framehdr[i]=0;
((u16*)framehdr)[0]=0x0008;
memcpy(((u8*)framehdr)+4 , "\xff\xff\xff\xff\xff\xff",6);
memcpy(((u8*)framehdr)+10, "\x01\x1a\xe9\x1e\xb7\xf8",6);
memcpy(((u8*)framehdr)+16, "\xff\xff\xff\xff\xff\xff",6);
//char str[]="\xaa\xaa\x03\x00\x00\x00\x08\xfe\x01\x00\x00\x1a\xe9\x1e\xb7\xf9\x68\x75\x73\x73\x6f\x6e\x00\x00";
char str[]="plop";
memcpy(framehdr+24, str, sizeof(str)-1);
framehdr[22]=0xb0;
framehdr[23]=0x02;
write(fd, framehdr, 24+sizeof(str)-1);
free(framehdr);
}
}
}
if_freenameindex(index);
close(fd);
free(req);
return 0;
}