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

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




👉🏻👉🏻👉🏻 ВСЯ ИНФОРМАЦИЯ ДОСТУПНА ЗДЕСЬ ЖМИТЕ 👈🏻👈🏻👈🏻




























































Рассмотрим подробнее что происходит с пакетом при попадании в нашу машину. Сначала он обрабатывается драйвером аппаратуры(сетевой карты и т.д) если пакет предназначен нам то он посылается на выше лежащий уровень - сетевой там определяется для кого он предназначен: нам или кому-то другому, для этого просматривается кэш маршрутизации, если там нет маршрута то Forwarding Information Base (FIB), если пакет предназначен другому компьютеру то ядро шлёт его на соответствующее устройство (сетевую карту) ,если нам ,то через транспортный и вышележащие уровни приложению. Обмен данными между приложением и ядром осуществляется через абстракцию сокета. В Линухе используется BSD сокеты.
Рассмотрим поподробнее структуру пакета
Ключ к быстрому обмену данными в использовании структуры sk_buf и передачи на вышестоящие уровни только указателя на неё
описание структуры лежит в linux/skbuff.h
/* These two members must be first. */
struct sk_buff * next; /* Next buffer in list */
struct sk_buff * prev; /* Previous buffer in list */
struct sk_buff_head * list; /* List we are on */
struct sock *sk; /* Socket we are owned by */
struct timeval stamp; /* Time we arrived */
struct net_device *dev; /* Device we arrived on/are leaving by */
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
unsigned int len; /* Length of actual data */
unsigned char __unused, /* Dead field, may be reused */
cloned, /* head may be cloned (check refcnt to be sure). */
ip_summed; /* Driver fed us an IP checksum */
__u32 priority; /* Packet queueing priority */
atomic_t users; /* User count - see datagram.c,tcp.c */
unsigned short protocol; /* Packet protocol from driver. */
unsigned short security; /* Security level of packet */
unsigned int truesize; /* Buffer size */
unsigned char *head; /* Head of buffer */
unsigned char *data; /* Data head pointer */
unsigned char *tail; /* Tail pointer */
unsigned char *end; /* End pointer */
void (*destructor)(struct sk_buff *); /* Destruct function */
/* Can be used for communication between hooks. */
/* Associated connection, if any */
__u32 tc_index; /* traffic control index */
там же содержится масса полезных функций для работы с sk_buff. все протоколы используют ету структуру добавляя заголовки своего уровня
Уровень IPиспользует 3 структуры для маршрутизации FIBгде хранятся все маршруты routingcacheгде находятся наиболее часто используемые neibourtableсписок компьютеров физически соединенных с данным
FIBсодержит 32 зоны по одной на каждый бит ipадреса каждая зона содержит точки входа для хостов и сетей которые задайтся данной маской подсети 255.0.0.0 имеет 8 значащих бит и поэтому в восьмой зоне 255.255.255.0 в 24 зоне
routingcacheхэш-таблица которая содержит до 256 цепочек маршрутов если подходящий маршрут не найден в кэше то он добавляется туда из FIBустаревшие записи по истечении некоторого времени удаляются содержимое кэша можно увидеть в /proc/net/rt_cache
главные настройки сети в дистрибутиве RedHat (Mandrake) лежат в /etc/sysconfig/network ,/etc/sysconfig/network-scripts/ifcfg-eth0 и тд...
содержимое моих файлов (не в virtualmashineредхате а на нормальной машине Mandrake-8.2 где соответственно нет никаких сетевых карт)
/etc/sysconfig/network-scripts/ifcfg-lo
# If you're having problems with gated making 127.0.0.0/8 a martian,
# you can change this to something else (255.255.255.255, for example)
Очень полезной программой является ifconfigсинтаксис которой подробно рассмотрен в мануале
[20:16][pts1]/etc/sysconfig/network-scripts [root]
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:3242 errors:0 dropped:0 overruns:0 frame:0
TX packets:3242 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:227644 (222.3 Kb) TX bytes:227644 (222.3 Kb)
Destination Gateway Genmask Flags Metric Ref Use Iface
её назначение ,а также многих других описано в LinuxNetworkAdministratorGuide
В этой части мы подробно рассмотрим сокеты и всё что с ними связано
Когда процесс создаёт сокет то он пустой потом система определяет маршрут к удалённому хосту и вносит эту информацию в сокет. После этого пакеты направляются на нужное устройство
Есть два типа сокетов BSDсокеты которые включают как член INETcокеты BSDсокеты описываются структурой structsocketв linux/net.h
struct fasync_struct *fasync_list; /* Asynchronous wake up list */
struct file *file; /* File back pointer for gc */
int (*release) (struct socket *sock);
int (*bind) (struct socket *sock, struct sockaddr *umyaddr,
int (*connect) (struct socket *sock, struct sockaddr *uservaddr,
int (*socketpair) (struct socket *sock1, struct socket *sock2);
int (*accept) (struct socket *sock, struct socket *newsock,
int (*getname) (struct socket *sock, struct sockaddr *uaddr,
unsigned int (*poll) (struct file *file, struct socket *sock, struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt) (struct socket *sock, int level, int optname,
int (*getsockopt) (struct socket *sock, int level, int optname,
int (*sendmsg) (struct socket *sock, struct msghdr *m, int total_len, struct scm_cookie *scm);
int (*recvmsg) (struct socket *sock, struct msghdr *m, int total_len, int flags, struct scm_cookie *scm);
int (*mmap) (struct file *file, struct socket *sock, struct vm_area_struct * vma);
ssize_t (*sendpage) (struct socket *sock, struct page *page, int offset, size_t size, int flags);
* structproto_ops *opsуказывает на протокольно зависимые функции
/* Socket demultiplex comparisons on incoming packets. */
__u32 daddr; /* Foreign IPv4 addr */
__u32 rcv_saddr; /* Bound local IPv4 addr */
__u16 dport; /* Destination port */
unsigned short num; /* Local port */
int bound_dev_if; /* Bound device index if != 0 */
/* Main hash linkage for various protocol lookup tables. */
volatile unsigned char state, /* Connection state */
zapped; /* In ax25 & ipx means not linked */
unsigned short family; /* Address family */
unsigned char reuse; /* SO_REUSEADDR setting */
atomic_t refcnt; /* Reference count */
socket_lock_t lock; /* Synchronizer... */
int rcvbuf; /* Size of receive buffer in bytes */
wait_queue_head_t *sleep; /* Sock wait queue */
struct dst_entry *dst_cache; /* Destination cache */
atomic_t rmem_alloc; /* Receive queue bytes committed */
struct sk_buff_head receive_queue; /* Incoming packets */
atomic_t wmem_alloc; /* Transmit queue bytes committed */
struct sk_buff_head write_queue; /* Packet sending queue */
atomic_t omem_alloc; /* "o" is "option" or "other" */
int wmem_queued; /* Persistent queue size */
int forward_alloc; /* Space allocated forward. */
unsigned int allocation; /* Allocation mode */
int sndbuf; /* Size of send buffer in bytes */
/* Not all are volatile, but some are, so we might as well say they all are.
/* Hole of 3 bytes. Try to pack. */
/* The backlog queue is special, it is always used with
* the per-socket spinlock held and requires low latency
* access. Therefore we special case it's implementation.
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#if defined(CONFIG_INET) || defined (CONFIG_INET_MODULE)
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
int err, err_soft; /* Soft holds errors that don't
unsigned char localroute; /* Route locally only */
/* Socket Filtering Instructions */
/* This is where all the private (optional) areas that don't
#if defined(CONFIG_INET) || defined (CONFIG_INET_MODULE)
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
#if defined (CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE)
#if defined (CONFIG_PACKET) || defined(CONFIG_PACKET_MODULE)
#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE)
#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE)
#if defined(CONFIG_ECONET) || defined(CONFIG_ECONET_MODULE)
#if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE)
#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
#if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE)
/* This part is used for the timeout functions. */
struct timer_list timer; /* This is the sock cleanup timer. */
/* Identd and reporting IO signals */
/* RPC and TUX layer private data */
void (*state_change)(struct sock *sk);
void (*data_ready)(struct sock *sk,int bytes);
void (*write_space)(struct sock *sk);
void (*error_report)(struct sock *sk);
int (*backlog_rcv) (struct sock *sk,
Эта структура очень широко используется и имеет много hacksзависящих от конфигурации как видим для каждого протокола здесь найдется местечко
Сокеты проходят через процесс маршрутизации только один раз для каждого маршрута. Они содержат указатель на маршрут structsock- >dst_cache* и вызывают ip_route_connect (net/route.h) для нахождения маршрута информация записывается в dst_cacheи сокет дальше использует её не повторяя операции поиска маршрута пока не случится что-то необычное в этом и есть смысл connect
server = gethostbyname(SERVER_NAME);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_port = htons(PORT_NUM);
memcpy(&address.sin_addr,server->h_addr,server->h_length);
connect(sockfd, &address, sizeof(address));
socketсоздаёт обект сокета определенного типа и инициализирует его также делает дефолтовские очереди (incoming,outgoing,error,backlog) и заголовок TCP
connectопределяет маршруты вызывая протокольно зависимые функции (tcp_v4_connect(),udp_connect()) net/socket.c
asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, int addrlen)
err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
int sock_create(int family, int type, int protocol, struct socket **res)
.....................................
//cоздаемпротокольнозависимыйсокет!
//--------------------------------------
if ((i = net_families[family]->create(sock, protocol)) < 0)
Устанавливаем указатели на протокольно зависимые части
Сохраняем данные про тип и параметры сокета
Устанавливаем сокет в положение закрыт
Создаем новую запись в таблице маршрутизации
Сохраняем указатель на запись маршрутизации в сокете
Вызываем протокольно зависимую функцию connect
Close вызывает sock_close in socket.c
void sock_release(struct socket *sock)
а та через цепочку вызовов протокольнозависимую функцию
void inet_sock_release(struct sock *sk) -net/ipv4/af_inet.c
назвние говорит за себя + хороший комментарий Алана Коха
fib_lookup() - include/net/ip_fib.h
возвращает маршрут .Написана русским -Кузнецов!
вызывает ip_route_output для определении адреса назначения
rt_intern_hash полезные для маршрутизации функции
sock_init_data net/core/sock.c инициализируетосновныеполясокета
сохдает пакеты для соединения с установленным размером окна
и соответствующими битами, ложит пакет в очередь и выpывает
tcp_transmit_skb чтоб послать пакет
tcp_transmit_skb -заполняет заголовок пакета и передает его
создает соединительный пакет и вызывает tcp_connect
Эта часть описывает процесс обмена данными между различными уровнями ядра и сети Когда приложение отправляет данные то оно пишет в сокет тот в своб очередь определяет свой тип и вызывает соответствующую функцию,та передает данные протоколу транспортного уровня(tcp,udp) функции етого уровня создают структуру sk_buff,копируют в неё данные заполняют заголовок своего уровня,считают контрольную сумму и шлют на уровень IP.Там дописывается заголовок ip,checksum,возможно пакет фраг менторуется и шлётся на xmit очередь сетевого девайса ,тот посылает пакет в сеть.
calls spin_unlock_bh() освобождаемдевайс
DEVICE->hard_start_xmit() - зависитотдевайса, drivers/net/DEVICE.c
в общем проверяет открыто ли устройство
говорит системной шине послать пакет
inet_sendmsg() - net/ipv4/af_inet.c
int inet_sendmsg(struct socket *sock, struct msghdr *msg, int size,
if (sk->num==0 && inet_autobind(sk) != 0)
вызываем функцию протокола чтоб послать данные
return sk->prot->sendmsg(sk, msg, size);
ip_build_xmit - net/ipv4/ip_output.c (604)
calls sock_alloc_send_skb() выделяемпамять
if(!sk->protinfo.af_inet.hdrincl) {
iph->ttl=sk->protinfo.af_inet.mc_ttl;
ip_select_ident(iph, &rt->u.dst, sk);
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
err = getfrag(frag, ((char *)iph)+iph->ihl*4,0, length-iph->ihl*4);
calls getfrag() копируем данные у юзера
returns rt->u.dst.output() [= dev_queue_xmit()]
ip_queue_xmit() - net/ipv4/ip_output.c (234)
calls skb->dst->output() [= dev_queue_xmit()]
qdisc_restart() - net/sched/sch_generic.c (50)
if если ошибка опять стввим пакет в очередь
sock_sendmsg() - net/socket.c (325)
calls scm_sendmsg() [socket control message]
calls sock->ops[inet]->sendmsg() and destroys scm
>>> sock_write() - net/socket.c (399)
calls socki_lookup() accоциируемсокетс inode
tcp_sendmsg() - net/ipv4/tcp.c (755)
calls csum_and_copy_from_user() делаем checksum & копируем
tcp_send_skb() - net/ipv4/tcp_output.c (160)
мы ставим буфер в очередь и решаем оставить его там или послать
calls __skb_queue_tail() добавляем в очередь
tcp_transmit_skb() - net/ipv4/tcp_output.c (77)
calls tcp_build_and_update_options()
calls tp->af_specific[ip]->queue_xmit()
копируем из адресного пространства пользователя и добавляем checksum
Получение данных начинается с прерывания от сетевой карты. Драйвер девайса выделяет память и пересылает данные в то пространство. Потом передает пакет в связующий уровень который вызывает bottom-halv,которое обрабатывает событие вне прерывания пересылая данные на уровень выше -ip.Тот проверяет ошибки фрагменты, маршрутизирует пакет или отсылает на уровень выше(tcp || udp) Этот уровень снова проверяет ошибки определяет сокет которому предназначен пакет и ложит его в очередь сокета. Тот в свою очередь будит пользовательский процесс и копирует данные в его буфер.
Пытаемся что-то прочитать(и засыпаем)
Заполняем заголовок сообщения указателем на буфер(сокет)
ложим пакет в то место судя по всему используя DMA
выставляем флаг запуска bottom-halv
Пересылка пакетов из девайса чтоб не было прерываний
Определение маршрута(форвардить или нет)
Отсылка пакета по назначению(TCP||UDP||forwarding)
Проверка флагов и ошибок а также не был ли получен пакет ранее
Вызов соответствуюшей функции доставки(udp ||tcp) в буфер пользователя
Рассмотрим подробнее процесс форвардинга пакетов
Сначала идет проверка TTL и уменьшение его на 1 Проверка пакета на наличие действительного маршрута если такого нет то отсылается соответствующее icmp сообщение копирование пакета в новый буфер и освобождение старого Установка нужных ip опций фрагменторование если необходимо отправка пакета на нужный девайс
DEVICE_rx() девайсно зависимая функция,
здесь я попытаюсь перевести замечательные комментарии автора
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 bj0rn@blox.se
* Если у нас хороший пакет то забираем его из адаптера
de600_rx_intr(struct net_device *dev)
size = de600_read_byte(RX_LEN, dev); /* нижниябайт */
size += (de600_read_byte(RX_LEN, dev) << 8); /* верхнийбайт */
size -= 4; /* Ignore trailing 4 CRC-bytes */
/* Сообщаем адаптеру куда ложить следующий пакет и получаем */
if ((size < 32) || (size > 1535)) {
printk("%s: Bogus packet size %d.\n", dev->name, size);
printk("%s: Couldn't allocate a sk_buff of size %d.\n",
/* 'skb->data' указывет на начало буфера данных. */
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
((struct net_device_stats *)(dev->priv))->rx_packets++; /* количествополучений */
((struct net_device_stats *)(dev->priv))->rx_bytes += size; /* количествополученныхбайт */
* Если случится что-то плохое во время доставки, netif_rx()
* сделало amark_bh(INET_BH) для нас и будет работать
ip_finish_output() net/ipv4/ip_output
определяет девайс для данного маршрута
вызывает функцию девайса[=dev_queue_xmit]
если пакет никому не предназначен то дропаем
если неможет пакет отфорвардится то отправляем icmpпакет ICMP_DEST_UNREACH
если необходимо шлем пакет ICMPHOSTREDIRECT
если необходимо устанавливаем нужные опции ip_forward_optionsв
ip_rcvnet/ipv4/ip_input.cглавная функция получения ipпакета
Как уже говорилось есть тоюлица соседей, FIB,routingcacheТаблица соседей содержит адреса(mac) компьютеров которые физически соединены с нами. Linux использует АRP для определения адресов ета таблица динамическая хотя администраторы могут задать статические записи. Стуктуры связанные с етой таблицей описаны в include/net/neighbour.h основные структуры. struct neigh_table -их целый связаный список struct neigh_parms -список содержит разнообразную статистику struct neighbour -hash таблица соседей ассоциированных с данной таблицей struct pneig_entry -hash всех девайсов
hh_cache -указатель на аппаратный кэш
sk_buff_head arp_queuq -очередь arp пакетов
есть local -в ней находятся свои интерфейсы
и main в ней наверное всё остальное
struct fib_table в include/net/ip_fib.h
содержит указатели на различные функции
tb_id -255 для local и 254 для main
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 fx_divisor числу бакетов для зоны (в основном 16 кроме зоны 0000
int fz_order индекс зоны в родительской fn_hash
struct fib_node -содержит информацию по девайсу в fib_info(include/net/ip_fib.h)
Это наиболее быстрый способ нахождения маршрута Когда ip нужен маршрут ,то он определяет ячейку в хэше,которая указывает на цепочку маршрутов и идёт по этой цепочке пока не найдет нужный маршруты имеют таймеры и частоту использования ,наиболее частые перемещаются в начало.
содержит адреса отправителя и получателя
содержит спецефические для данного маршрута данные и функции
pmtu максимальная длина пакета для данного маршрута
int (*input)(struct sk_buff) -указатель на функцию приема для данного маршрута
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)
err=sock_setsockopt(sock,level,optname,optval,optlen);
err=sock->ops->setsockopt(sock, level, optname, optval,optlen);
значитнамнадоискатьфункцию setsockopt вкодедляреализациидлятипа sock_raw этофайл net/ipv4/raw.c смотрим static int raw_setsockopt(struct sock *sk, int level, int optname,
return ip_setsockopt(sk, level, optname, optval, optlen);
...................................
функция ip_setsockopt лежит в net/ipv4/ip_sockglue.c в ней идет длинный перебор опций мы остановим свой выбор на уровне SOL_IP и добавим в перебор свои строки /*HACK:>>>>>>>>>>>>>>>*/
printk("HACKIP:setsockopt flag %d\n",sk->hackflag);
printk("HACKIP:setsockopt val %d\n",val);
подробнее опишем происходящие действия
printk -выводим отлабочные сообщения
Я не уверен ,но судя по всему при создании сокета вся структура обнуляется поэтому мы можем не смотреть флаг .Я добавил эту строку ,чтоб посмотреть всегда ли он равен 0 при не установленной опции а после установки при повторе он равен 1. get_user забираем значение ,подробности include/asm/uaccess.h но для всего этого нам надо добавить соответствующие поля в struct sock =======sock.h=============
/* Socket demultiplex comparisons on incoming packets. */
........................................
===========end======================
теперь нам надо перехватить отправку пакета
идем в файл net/ipv4/ip_output.c и после всех строк где есть 'iph->saddr=' вставляем наш код #ifdef CONFIG_HACKIP
if((sk->hackf.src_addr!=0)&&(sk->hackflag==1))
printk("HACKIP:ip_build_and_send.. %d\n",iph->saddr);
Осталосьмалое: вфайл include/linux/in.h добавляемстроку #define IP_HACKIP 16
bool 'HACKIP facilities' CONFIG_HACKIP делаем
cp arh/i386/boot/bzImage /boot/kursach
правим lilo.conf или /boot/grub/menu.lst
теперь протестируем нашу программу извиняюсь за возможное наличие лишних include просто я переделал файл из друго-го проекта
============rel.c========================
/* Written by Gleb Paharenko 2003 */
/*и прекрасной весне в мае 2003-го*/
if((sd=socket(PF_INET,SOCK_RAW,6))<0)
inet_aton("212.168.1.11",(struct sockaddr *)&(addr.sin_addr));
inet_aton("192.168.1.1",(struct sockaddr *)&(raddr.sin_addr));
inet_aton("192.168.1.10",(struct sockaddr *)&(addr.sin_addr));
if(bind(sd,(struct sockaddr *)&addr,sizeof(addr))<0)
if(connect(sd,(struct sockaddr *)&raddr,sizeof(raddr))!=0){
if(setsockopt(sd,SOL_IP,IP_HACKIP,&sval,4)!=0)
May 20 00:53:49 kursach -- root[863]: ROOT LOGIN ON tty1
May 20 00:53:51 kursach kernel: HACKIP:setsockopt flag 0
May 20 00:53:51 kursach kernel: HACKIP:setsockopt val 184658132
May 20 00:53:51 kursach kernel: HACKIP:ip_build_and_send.. 184658132
домауменястоит vmware :host-only networking
host machine Windows2000 Professional 192.168.1.1/24
virtual Linux Red-Hat 7.2 "Enigma" 192.168.1.10/24

Название: Реализация сети в операционной системе Linux
Раздел: Рефераты по информатике, программированию
Тип: курсовая работа
Добавлен 12:08:51 26 марта 2005 Похожие работы
Просмотров: 249
Комментариев: 14
Оценило: 4 человек
Средний балл: 5
Оценка: неизвестно   Скачать

Привет студентам) если возникают трудности с любой работой (от реферата и контрольных до диплома), можете обратиться на FAST-REFERAT.RU , я там обычно заказываю, все качественно и в срок) в любом случае попробуйте, за спрос денег не берут)
Да, но только в случае крайней необходимости.

Курсовая работа: Реализация сети в операционной системе Linux
Реферат по теме Ксенофобия в образовании
Курсовая Работа Объемы
Реферат: Арттерапевтические техники для работы с телесным образом «я» и с психосоматическими заболеваниями
Реферат: Предмет статистики финансов. Теоретические основы и метод статистики финансов
Реферат по теме Обоснование возможности реализации регулировки фаз газораспределения
Курсовая работа: Центральный банк
Реферат: Педагогические взгляды английских и французских просветителей
Сочинение Очень В Моем Городе
Реферат Иностранные Слова В Современной Речи
Реферат: Банковские карточки, их виды
Курсовая работа по теме Взаємодія школи і сім’ї у вихованні дітей
Форма Сочинения Егэ По Русскому Языку 2022
Курсовая работа: Діяльність підприємств на світовому ринку технології
Поведение Фирмы В Краткосрочном Периоде Реферат
Сочинение Описание Памятника Петра И Февронии
Доклад: Институты ООН по вопросам борьбы с преступностью
Реферат: Россия в мировом политическом процессе
Реферат: Слепоглухие дети. Реабилитация и обучение
Реферат: Распад СССР: ностальгия, преступление, подвиг
Курсовая Работа На Тему Коррупция
Реферат: Ананасы в шампанском
Доклад: Самбо
Реферат: Техника безопасности (всем морякам)

Report Page