Xreferat.com » Рефераты по информатике и программированию » Реализация сети в операционной системе Linux

Реализация сети в операционной системе Linux

ip опций фрагменторование если необходимо отправка пакета на нужный девайс

DEVICE_rx() девайсно зависимая функция,

пример drivers/net/de600.c

здесь я попытаюсь перевести замечательные комментарии автора

Linux driver for the D-Link DE-600 Ethernet pocket adapter.

*

* Portions (C) Copyright 1993, 1994 by Bjorn Ekwall

* The Author may be reached as [email protected]

/*

* Если у нас хороший пакет то забираем его из адаптера

*/

static void

de600_rx_intr(struct net_device *dev)

{

struct sk_buff *skb;

unsigned long flags;

int i;

int read_from;

int size;

register unsigned char *buffer;

save_flags(flags);

cli();

/* Определяем размер пакета */

size = de600_read_byte(RX_LEN, dev); /* нижния байт */

size += (de600_read_byte(RX_LEN, dev) 1535)) {

printk("%s: Bogus packet size %d.n", dev->name, size);

if (size > 10000)

adapter_init(dev);

return;

}

skb = dev_alloc_skb(size+2);

if (skb == NULL) {

printk("%s: Couldn't allocate a sk_buff of size %d.n",

dev->name, size);

return;

}

/* Иначе*/

skb->dev = dev;

skb_reserve(skb,2); /* Align */

/* 'skb->data' указывет на начало буфера данных. */

buffer = skb_put(skb,size);

/* копируем пакет в буфер */

de600_setup_address(read_from, RW_ADDR);

for (i = size; i > 0; --i, ++buffer)

*buffer = de600_read_byte(READ_DATA, dev);

/* Определяем тип протокола

skb->protocol=eth_type_trans(skb,dev);

/*Передаем на верхний уровень см net/core/dev.c

netif_rx(skb);

/* обновляем статистику */

dev->last_rx = jiffies;

((struct net_device_stats *)(dev->priv))->rx_packets++; /* количество получений */

((struct net_device_stats *)(dev->priv))->rx_bytes += size; /* количество полученных байт */

/*

* Если случится что-то плохое во время доставки, netif_rx()

* сделало a mark_bh(INET_BH) для нас и будет работать

* когда мы войдем в bottom-halv.

*/

}

ip_finish_output() net/ipv4/ip_output

определяет девайс для данного маршрута

вызывает функцию девайса[=dev_queue_xmit]

ip_forward -net/ipv4/ip_forward

в этом файле хорошие комментарии

проверяем роутер

если пакет никому не предназначен то дропаем

если плохой TTL аналогично

если неможет пакет отфорвардится то отправляем icmp пакет ICMP_DEST_UNREACH

если необходимо шлем пакет ICMP HOST REDIRECT

копируем и уничтожаем старый пакет

уменьшаем TTL

если необходимо устанавливаем нужные опции ip_forward_options в

ip_forward_finish

ip_rcv net/ipv4/ip_input.c главная функция получения ip пакета

проверяем ошибки

плохая длина

версия

чексумма

вызываем pskb_trim

вызываем ip_route_input

Процесс маршрутизации

Как уже говорилось есть тоюлица соседей, FIB,routing cache Таблица соседей содержит адреса(mac) компьютеров которые физически соединены с нами. Linux использует АRP для определения адресов ета таблица динамическая хотя администраторы могут задать статические записи. Стуктуры связанные с етой таблицей описаны в include/net/neighbour.h основные структуры. struct neigh_table -их целый связаный список struct neigh_parms -список содержит разнообразную статистику struct neighbour -hash таблица соседей ассоциированных с данной таблицей struct pneig_entry -hash всех девайсов

поля struct neighbour

struct net_device -девайс

hh_cache -указатель на аппаратный кэш

sk_buff_head arp_queuq -очередь arp пакетов

есть local -в ней находятся свои интерфейсы

и main в ней наверное всё остальное

Forwarding Information Database

struct fib_table в include/net/ip_fib.h

содержит указатели на различные функции

tb_stamp

tb_id -255 для local и 254 для main

td_data -hash fib таблица

struct fn_hash -net/ipv4/fib_hash.c

struct fn_zone *fn_zones[33] -указатели на зоны

struct fn_zone *fn_zone_list указатель на первую не пустую зону

struct fn_zone содержит информацию про зону и маршруты для неё

struct fib_node ** fz_hash -указывает на кэш записей этой зоны

int fz_nent количество записей

int fx_divisor числу бакетов для зоны (в основном 16 кроме зоны 0000

loopback девайса)

int fz_order индекс зоны в родительской fn_hash

struct fib_node -содержит информацию по девайсу в fib_info(include/net/ip_fib.h)

метрику ,протокол и т.д

Routing Cache

Это наиболее быстрый способ нахождения маршрута Когда ip нужен маршрут ,то он определяет ячейку в хэше,которая указывает на цепочку маршрутов и идёт по этой цепочке пока не найдет нужный маршруты имеют таймеры и частоту использования ,наиболее частые перемещаются в начало.

struct rtable -звено в цепочке

содержит адреса отправителя и получателя

входящий интерфейс

адрес соседа или шлюза

struct dst_entry

содержит спецефические для данного маршрута данные и функции

struct dev -понятно

pmtu максимальная длина пакета для данного маршрута

int (*input)(struct sk_buff) -указатель на функцию приема для данного маршрута

часто ето tcp_rcv

int (*output)(struct sk_buff) указатель на функцию отсылки (dev_queue_xmit)

также разнообразные статистические данные и опции

Таким образом нами было проведено исследование сетевой архитектуры операционной системы Линух на примере реализации стека протоколов tcp-ip версии 4 в ядре 2.4.7

Приложение

После длительных теоретических изысканий применим их на практике

Нашей целью будет создание удобного пользовательского интерфейса для указания в пакете подставного ip адреса(адреса которого нет у никакого нашего интерфейса) Я не буду показывать ,то как адреса выставляются в ядре. Замечу только то что, из сокета семейства AF_INET и типа SOCK_RAW пакет с не своим адресом отправить вроде бы можно (в ядре 2.2 ,насчет 2.4 неуверен -может там есть какие-то проверки). страницы мана говорят про опцию IP_HDRINCL .Их можно отправлять также через тип SOCK_PACKET. Но для всего этого знать код ядра не очень необходимо. Поэтому мы пойдём други путём.

Наиболее легкий путь(?) сделать это через интерфейс setsockopt. После внимательного изучения кода функции sys_setsockopt -net/socket.c находим строки if ((sock = sockfd_lookup(fd, &err))!=NULL)

{

if (level == SOL_SOCKET)

err=sock_setsockopt(sock,level,optname,optval,optlen);

else

err=sock->ops->setsockopt(sock, level, optname, optval,optlen);

sockfd_put(sock);

}

return err;

}

значит нам надо искать функцию setsockopt в коде для реализации для типа sock_raw это файл net/ipv4/raw.c смотрим static int raw_setsockopt(struct sock *sk, int level, int optname,

char *optval, int optlen)

{

if (level != SOL_RAW)

return ip_setsockopt(sk, level, optname, optval, optlen);

...................................

}

функция ip_setsockopt лежит в net/ipv4/ip_sockglue.c в ней идет длинный перебор опций мы остановим свой выбор на уровне SOL_IP и добавим в перебор свои строки /*HACK:>>>>>>>>>>>>>>>*/

#ifdef CONFIG_HACKIP

case IP_HACKIP:

printk("HACKIP:setsockopt flag %dn",sk->hackflag);

sk->hackflag=1;

get_user(val,(int *) optval);

printk("HACKIP:setsockopt val %dn",val);

sk->hackf.src_addr=val;

break;

#endif

case IP_HDRINCL:

подробнее опишем происходящие действия

printk -выводим отлабочные сообщения

Я не уверен ,но судя по всему при создании сокета вся структура обнуляется поэтому мы можем не смотреть флаг .Я добавил эту строку ,чтоб посмотреть всегда ли он равен 0 при не установленной опции а после установки при повторе он равен 1. get_user забираем значение ,подробности include/asm/uaccess.h но для всего этого нам надо добавить соответствующие поля в struct sock =======sock.h=============

.........................

#ifdef CONFIG_HACKIP

/*HACK:>>>>>>>>>>>>>>>>>>*/

struct ip_hack {

__u32 src_addr;

};

#endif

struct sock {

/* Socket demultiplex comparisons on incoming packets. */

.................................

#ifdef CONFIG_HACKIP

/*HACK:>>>>>>>>>>>>>>>>>*/

struct ip_hack hackf;

int hackflag;

#endif

........................................

===========end======================

теперь нам надо перехватить отправку пакета

идем в файл net/ipv4/ip_output.c и после всех строк где есть 'iph->saddr=' вставляем наш код #ifdef CONFIG_HACKIP

if((sk->hackf.src_addr!=0)&&(sk->hackflag==1))

{

iph->saddr=sk->hackf.src_addr;

printk("HACKIP:ip_build_and_send.. %dn",iph->saddr);

}

#endif

Осталось малое: в файл include/linux/in.h добавляем строку #define IP_HACKIP 16

в файл net/Config.in

bool 'HACKIP facilities' CONFIG_HACKIP делаем

cd /usr/src/linux

make menuconfig

make dep

make bzImage

cp arh/i386/boot/bzImage /boot/kursach

правим lilo.conf или /boot/grub/menu.lst

соответствуюшая команда

reboot....

теперь протестируем нашу программу извиняюсь за возможное наличие лишних include просто я переделал файл из друго-го проекта

============rel.c========================

/* Written by Gleb Paharenko 2003 */

/*Посвящяется Кевину Митнику */

/*и прекрасной весне в мае 2003-го*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define IP_HACKIP 16

int main()

{

int sd,res;

int value=1;

int sval=0;

int oval=1;

char buffer[100];

struct sockaddr_in addr,raddr;

bzero(buffer,sizeof(buffer));

if((sd=socket(PF_INET,SOCK_RAW,6))

Если Вам нужна помощь с академической работой (курсовая, контрольная, диплом, реферат и т.д.), обратитесь к нашим специалистам. Более 90000 специалистов готовы Вам помочь.
Бесплатные корректировки и доработки. Бесплатная оценка стоимости работы.

Поможем написать работу на аналогичную тему

Получить выполненную работу или консультацию специалиста по вашему учебному проекту
Нужна помощь в написании работы?
Мы - биржа профессиональных авторов (преподавателей и доцентов вузов). Пишем статьи РИНЦ, ВАК, Scopus. Помогаем в публикации. Правки вносим бесплатно.

Похожие рефераты: