t0x1n
09.05.2006, 20:24
t0x1n
http://www.security.e-gloryon.com
security@shamkir.net
Сокеты бывают трех типов:
SOCK_DGRAM датаграмные сокеты - сокеты которые отсылаются в сеть без запроса на соединение (к ним относятся UDP сокеты)
SOCK_STREAM потоковые сокеты - сокеты требующие соединение (TCP сокеты)
SOCK_RAW сырые сокеты - то что хотим, т.е. пишем сокеты с нуля.
В этой статье нас будут интересовать RAW (сырые) сокеты.
В качестве примера я напишу программу которая посылает обычный UDP пакет.
Если вы пользуетесь операционной системой Linux то код программы нужно компилировать с параметром
-D_BSD_SOURCE т.к. мы будет использовать бсдешные сокеты. Также компилировать и запускать
код программы необходимо с правами root (суперпользователя). Для этого достаточно ввести команду
su root.
Начнем...
Для начала функции нужные нам для работы:
Открытие RAW сокета:
int sock;
sock=socket(PF_INET, SOCKET_RAW, протокол);
Закрытие сокета:
close (sock);
Указание порта отправителя и получателя:
htons(порт);
Указание IP адреса отправителя и получателя:
inet_addr ("IP адрес");
Теперь покажу как устроен заголовок UDP на Си т.к. мы будем писать прогрумму посылающую UDP пакет.
UDP:
uh_sport Порт отправителя
uh_dport Порт получателя
uh_ulen Длина заголовка
uh_sum Контрольная сумма
Сообщения об ошибках:
Чтобы в случае ошибки программа нам выдала сообщение о ней
необходимо написать такую конструкцию:
int sock;
socket(PF_INET, SOCK_RAW, IPPROTO_UDP); //Создаем сокет
if ((sock)<0) //Если sock<0 тогда
{
perror ("socket"); //выдать сообщение об ошибке
} else { //Если нет то
printf ("socket ok"); //Выдать сообщение socket ok
}
А вот код программы посылающий UDP пакет:
#include
#include
#include
main()
{
int sock;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); //Открываем сокет
if ((sock)<0){
perror ("socket");
} else {
printf ("socket ok\n");
}
char buf[9999];
/* Структуры*/
struct sockaddr_in sin;
struct udphdr *udph=(struct udphdr*)buf;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP адрес получателя
/***********/
/*UDP заголовок */
udph->uh_sport=htons(21); //Порт отправителя
udph->uh_dport=htons(22); //Порт получателя
udph->uh_ulen=0; //Длина заголовка
udph->uh_sum=0; //Контрольная сумма
/***************/
/*Посылаем пакет*/
if((sendto(sock, &udph, sizeof(udph), 0, (struct sockaddr*)&sin, sizeof(sin)))<0){
perror ("sendto");
} else {
printf ("sendto ok\n");
}
close (sock); //Закрываем сокет
}
Теперь компилируем и запускаем код с правами рута. Чтобы вполне убедиться, что программ работает
можете запустить tcpdump и посмотреть отослался пакет или нет.
[t0x1n@t0x1n~]$ su root
[root@t0x1n~]$ gcc -D_BSD_SOURCE udp.c -udp
[root@t0x1n~]$ ./udp
socket ok
sendto ok
[root@t0x1n~]$
Ну вот думаю и все! Желаю удач в сетевом кодинге
http://www.security.e-gloryon.com
security@shamkir.net
Сокеты бывают трех типов:
SOCK_DGRAM датаграмные сокеты - сокеты которые отсылаются в сеть без запроса на соединение (к ним относятся UDP сокеты)
SOCK_STREAM потоковые сокеты - сокеты требующие соединение (TCP сокеты)
SOCK_RAW сырые сокеты - то что хотим, т.е. пишем сокеты с нуля.
В этой статье нас будут интересовать RAW (сырые) сокеты.
В качестве примера я напишу программу которая посылает обычный UDP пакет.
Если вы пользуетесь операционной системой Linux то код программы нужно компилировать с параметром
-D_BSD_SOURCE т.к. мы будет использовать бсдешные сокеты. Также компилировать и запускать
код программы необходимо с правами root (суперпользователя). Для этого достаточно ввести команду
su root.
Начнем...
Для начала функции нужные нам для работы:
Открытие RAW сокета:
int sock;
sock=socket(PF_INET, SOCKET_RAW, протокол);
Закрытие сокета:
close (sock);
Указание порта отправителя и получателя:
htons(порт);
Указание IP адреса отправителя и получателя:
inet_addr ("IP адрес");
Теперь покажу как устроен заголовок UDP на Си т.к. мы будем писать прогрумму посылающую UDP пакет.
UDP:
uh_sport Порт отправителя
uh_dport Порт получателя
uh_ulen Длина заголовка
uh_sum Контрольная сумма
Сообщения об ошибках:
Чтобы в случае ошибки программа нам выдала сообщение о ней
необходимо написать такую конструкцию:
int sock;
socket(PF_INET, SOCK_RAW, IPPROTO_UDP); //Создаем сокет
if ((sock)<0) //Если sock<0 тогда
{
perror ("socket"); //выдать сообщение об ошибке
} else { //Если нет то
printf ("socket ok"); //Выдать сообщение socket ok
}
А вот код программы посылающий UDP пакет:
#include
#include
#include
main()
{
int sock;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); //Открываем сокет
if ((sock)<0){
perror ("socket");
} else {
printf ("socket ok\n");
}
char buf[9999];
/* Структуры*/
struct sockaddr_in sin;
struct udphdr *udph=(struct udphdr*)buf;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP адрес получателя
/***********/
/*UDP заголовок */
udph->uh_sport=htons(21); //Порт отправителя
udph->uh_dport=htons(22); //Порт получателя
udph->uh_ulen=0; //Длина заголовка
udph->uh_sum=0; //Контрольная сумма
/***************/
/*Посылаем пакет*/
if((sendto(sock, &udph, sizeof(udph), 0, (struct sockaddr*)&sin, sizeof(sin)))<0){
perror ("sendto");
} else {
printf ("sendto ok\n");
}
close (sock); //Закрываем сокет
}
Теперь компилируем и запускаем код с правами рута. Чтобы вполне убедиться, что программ работает
можете запустить tcpdump и посмотреть отослался пакет или нет.
[t0x1n@t0x1n~]$ su root
[root@t0x1n~]$ gcc -D_BSD_SOURCE udp.c -udp
[root@t0x1n~]$ ./udp
socket ok
sendto ok
[root@t0x1n~]$
Ну вот думаю и все! Желаю удач в сетевом кодинге