Uživatelské nástroje

Nástroje pro tento web


c_network

Toto je starší verze dokumentu!


Programovani soketu v C

Sokety

Datové typy a struktury pro HW nebo protokoly

  • int může být někde 32 bit, někde třeba 16 bit, pokud potřebujeme určitou přesnou velikost, jsou užitečné typy
  • pokud používáme datové struktury
    • vkládají se někdy mezi jednotlivé atributy prazdné místa do paměti,
    • popřípadě se provádí nějaké optimalizace, které mohou zabrat více paměti, než ve skutečnosti chceme.
    • někdy potřebujeme, aby struktura zabírala stejné místo v paměti na všech architekturách
    • použijeme
struct my_struct {
        uint8_t  field1;
        uint16_t field2;
} __attribute__((packed));
#include <netinet/in.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

Prace s adresami

  • struct sockaddr je nejvice obecna
  • jednotlive struktury jsou mezi sebou prevoditelne, ale nemusi mit vubec stejnou delku!! Je treba si uvedomit, kam mohu kdy sahnout ve strukture.
include <netinet/in.h>

// All pointers to socket address structures are often cast to pointers
// to this type before use in various functions and system calls:

struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
};


// IPv4 AF_INET sockets:

struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
};

struct in_addr {
    unsigned long s_addr;          // load with inet_pton()
};


// IPv6 AF_INET6 sockets:

struct sockaddr_in6 {
    u_int16_t       sin6_family;   // address family, AF_INET6
    u_int16_t       sin6_port;     // port number, Network Byte Order
    u_int32_t       sin6_flowinfo; // IPv6 flow information
    struct in6_addr sin6_addr;     // IPv6 address
    u_int32_t       sin6_scope_id; // Scope ID
};

struct in6_addr {
    unsigned char   s6_addr[16];   // load with inet_pton()
};


// General socket address holding structure, big enough to hold either
// struct sockaddr_in or struct sockaddr_in6 data:

struct sockaddr_storage {
    sa_family_t  ss_family;     // address family

    // all this is padding, implementation specific, ignore it:
    char      __ss_pad1[_SS_PAD1SIZE];
    int64_t   __ss_align;
    char      __ss_pad2[_SS_PAD2SIZE];
};

Broadcast

  • pokrývá dvě vrstvy modelu ISO/OSI (spojová a síťová)
  • MAC broadcast (FF:FF:FF:FF:FF:FF)
  • rozlišujeme 2 druhy IP broadcastu
    • broadcastová adresa siťě (10.10.11.255)
    • globální broadcastová adresa (255.255.255.255)
  • zasílání broadcastu vyžaduje speciální oprávnění (flag)
    • globální nelze odeslat bez brány!
    • nelze odeslat lokální na jinou síť.. neví se, že je to bcast :)
  • příjem je podivný:
    • bcast neprojde pres router, jestliže nemá nastavený flag na přesměrovávání
    • oba typy IP bcastu dojdou na všechny zařízení, protože se to posílá MAC bcastem!!
    • ale!! aplikace která naslouchá na portu, například nc -u -l 9999, tak
    • přijímá globální bcast i síťový, ale jen pokud přijde z dostupné IP? (ze stejné sítě, existující IP adresy?)
  • TODO
    • zkusit hack.. odesílat vzdy na MAC FF:FF… a ruzne kombinace src, dst
    • z jine site poslat lokalni bcast pomoci specifikace ff:ff .. to by nemelo projit, kvuli nedostupnosti zdroje
    • kdyztak zkusit uplny fake… treba gw ip, gw mac, dst mac ff, dst ip global bcast
    • poslat jinou, ale funkční IP, FAKE SRC MAC brány a nebo kouknout, zde si to druha strana overuje existenci hosta arpeckem

Test příjmu broadcastu aplikací listen

  • OTESTOVAT ZNOVU.. NC MA TEHDENCY UZAMCIT SE JEN NA JEDNU RCVIP.. MUSIM HO PO KAZDEM POKUSU ZABIT
  • A TEN MZ VERZE 0.40 NEUMI ZMENIT MAC, MALFORMUJE PKT
  • server je 10.10.11.20/25, ntb, wifi
 
nc -l -p -u 9999
  • z klienta pharaon (10.10.11.2, 192.168.100.1) v LAN došlo:
mz eth0 -A 10.10.11.2 -B 255.255.255.255 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"
mz eth0 -A 10.10.11.2 -B 10.10.11.127 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"
  • nedošlo (protože se posílalo na MAC brány?):
mz eth0 -A 10.10.11.2 -B 10.10.11.128 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"
mz eth0 -A 10.10.11.2 -B 10.10.11.255 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"
  • došlo na stroj, ale nedošlo do soketu (použila se BCAST MAC)
mz eth0 -A 192.168.10.10 -B 10.10.11.127 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"  // z jiné sítě a neexistující
mz eth0 -A 10.10.11.8 -B 255.255.255.255 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"  // neexistujici ip
mz eth0 -A 10.10.11.3  -B 10.10.11.127 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"    // neexistujici ip
mz eth0 -A 10.10.11.1  -B 10.10.11.127 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"    // ip brany, ale moje mac
mz eth0 -A 192.168.100.1 -B 10.10.11.127 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"  // existující, ale jíná síť
mz eth0 -A 192.168.100.1 -B 255.255.255.255 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39" // existující, ale jíná síť
  • zkusil jsem si nastavit jinou sit (192.168.20.20)… vůbec neodešlo z IF
    • ta 127 .. neví se, že je to bcast .. bere se to jako host a brána není
    • globální chce asi gw = že by taky nevěděl, že je to bcast? nebo prostě obecně to chce bránu?
mz eth0 -A 192.168.20.20 -B 255.255.255.255 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39" // nebyla nastavená gw
mz eth0 -A 192.168.20.20 -B 10.10.11.127 -t udp "dp=9999,p=36:30:34:36:36:30:30:31:39"    // nevedel, ze je to bcast
  • staré informace.. zmatené :)
  • globální broadcast
    • nelze provést (v unixu), pokud není specifikovaná brána - neví se který adaptér použít?
    • přijímají jej všechny uzly v LAN (v promiscuitinim i normálním režimu)
    • přijímají jej UDP sockety, které jsou 'bindované na INADDR_ANY' a zdrojová IP bcastu odpovídá síti některé z lokálních IP?
    • nc -l -u -p 9999 skončí s hláškou network unreacheable
  • broadcast z neplatné adresy
    • nelze provést, pokud není specifikovaná brána - neví se který adaptér použít?
    • přijímají jej všechny uzly v LAN (v promiscuitinim i normálním režimu)
    • přijímají jej uzly, které jsou 'bindovány na IP z dané sítě'
    • nc -l -u -p 9999 skončí s hláškou network unrecheable
  • bind() na INADDR_ANY
    • příjmá broadcasty na všech Intf pokud jejich zdrojová adresa odpovídá nějaké z lokální podsítě
    • příjmá data adresované libovolné lokální IP adrese
    • při odesílání globálního broadcastu nebo bcastu pro nelokální subnet se použíje IP adresa zařízení s default gw
    • při odesílání unicast dat nebo bcastu pro lokální subnet se použíje odpovídající IP a Intf
      • odesílací intf lze specifikovat pomocí socketopt SO_BINDTODEVICE, ale vyžaduje práva roota a je obsolute
  • bind() na inet_addr(„aaa.bbb.ccc.ddd“)
    • nepřijímá žádné broadcasty
    • přijímá data pouze na intf odpovídající uvedené IP adrese
    • pro odesílání dat nebo broadcastu se použije uvedená IP
c_network.1365689798.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki