Anda di halaman 1dari 9

STRUKTUR ALAMAT SOKET

Struktur ini dapat dilalui dalam 2 arah :


 Dari proses ke kernel
 Dari kernel ke proses

Sebagian besar fungsi soket membutuhkan sebuah pointer ke sebuah


struktur alamat soket sebagai sebuah argumen.
Setiap suita protokol yang didukung mendefinisikan struktur alamat
soketnya. Nama dari struktur ini dimulai dengan sock_addr dan
diakhiri dengan sebuah akhiran unik untuk setiap suita protokol.

STRUKTUR ALAMAT SOKET IPv4


Sebuah struktur alamat soket IPv4 umumnya disebut sebuah
“struktur alamat soket internet” dinamakan sock_addr_in dan
didefinisikan dgn menyertakan header <netinet/in.h>.

Struct in_addr {
In_addr_t s_addr; /* 32-bit IPv4 address */
};

struct sockaddr_in {
uint8_t sin_len; /* length of structure(16) */
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* 16-bit TCP or UDP port
number */
/* network byte ordered */
struct in_addr sin_addr; /* 32-bit IPv4 address*/
/* network byte ordered */
char sin_zero[8]; /*unused */
};

Struktur Alamat Soket (IPv4) Internet : sockaddr_in

 Anggota dari panjang ; sin_len; ditambahkan dgn 4.3 BSD-Reno;


jika dukungan untuk protokol-protokol OSI ditambahkan.
Sebelum release ini, anggota pertama adalah sin_family yang
secara historis adalah sebuah unsigned short.
Tidak semua vendor mendukung field panjang untuk struktur
alamat soket & Posix.1g tidak membutuhkan anggota ini.
Dengan memiliki sebuah field panjang akan menyederhanakan
penanganan dari struktur alamat soket yang panjang-variabel.

 Jika field panjang diadakan, kita tidak pernah perlu mengaturnya,


dan tidak pernah perlu mengujinya, kecuali jika kita berurusan
dengan soket-soket routing.
Field panjang ini digunakan di dalam kernel oleh perute yang
berurusan dengan struktur alamat soket dari bermacam-macam
keluarga protokol (misal : kode tabel routing)

Catatan :
Ke-4 fungsi soket ; bind, connect, send to, dan
sendmsg; berfungsi untuk melewatkan sebuah struktur alamat
soket dari proses ke kernel.
Lima fungsi soket yang berfungsi melewatkan sebuah struktur
alamat soket dari kernel ke proses; accept, recvfrom,
recvmsg, getpeername, dan getsockname.

 Posix.1g hanya meminta 3 anggota dalam struktur :


sin_family, sin_addr, dan sin_port.
Bagi implementasi Posix-compliant, mendefinisikan anggota
struktur tambahan adalah bisa diterima, sedangkan bagi sebuah
struktur alamat soket Internet, hal ini adalah normal.
Hampir seluruh implementasi menambahkan anggota sin_zero
sehingga seluruh struktur alamat adalah paling tidak berukuran 16
byte.

 Di sini ditampilkan tipe data Posix.1g untuk anggota-anggota


s_addr, sin_family, dan sin_port.
Tipe data in_addr_t harus sebuah tipe unsigned integer dari
paling tidak 32 bit.
In_port_t harus sebuah tipe unsigned integer dari paling tidak
16 bit.
Sa_family_t dapat menjadi sembarang tipe unsigned integer,
normalnya sebuah 8-bit unsigned integer bila implementasi
mendukung field panjang, atau sebuah 16-bit unsigned integer
bila tidak mendukung field panjang.

Tipe data Deskripsi Header


Int8_t signed 8-bit integer <sys/types.h>
Uint8_t Unsigned 8-bit integer <sys/types.h>
Int_16_t Signed 16-bit integer <sys/types.h>
Uint16_t Unsigned 16-bit integer <sys/types.h>
Int32_t Signed 32-bit integer <sys/types.h>
Unit32_t Unsigned 32-bit integer <sys/types.h>
Sa_family_t Address family of socket address <sys/socket.h>
structure
Socklen_t Length of socket address <sys/socket.h>
structure, normalnya uint32_t
In_addr_t IPv4 address, normalnya <netinet/in.h>
uint32_t
In_port_t TCP atau UDP port, normalnya <netinet/in.h>
uint16_t
 Ke-2 alamat IPv4 dan TCP atau UDP port number selalu disimpan
dalam sebuah struktur dalam network byte order. Kita harus
menyadarinya ketika menggunakan anggota-anggota ini.

 Alamat IPv4 32-bit dapat diakses dalam 2 cara berbeda. Contoh :


jika serv ditentukan sebagai struktur alamat soket Internet, lalu
serv.sin_addr merekomendasikan alamat IPv4 32-bit sebagai
sebuah struktur in_addr, sementara serv.sin_addr.s_addr
merekomendasikan alamat IPv4 32-bit yang sama sebagai sebuah
in_addr_t (khususnya sebuah integer 32-bit unsigned) kita
harus pastikan bahwa kita mereferensi alamat IPv4 dengan
benar, khususnya ketika ia digunakan sebagai sebuah argumen
untuk suatu fungsi, karena kompilator seringkali menyuguhkan
struktur dengan cara berbeda dari integer.

 Anggota sin_zero tidak digunakan tapi kita selalu mengaturnya


ke nol ketika mengisi satu dari struktur-struktur ini. Berdasarkan
konvensi, kita selalu mengatur keseluruhan struktur ke nol
sebelum mengisinya, bukan hanya anggota sin_zero.

 Struktur alamat soket digunakan hanya pada host yang diberikan :


struktur itu sendiri tidak mengkomunikasikan antara host-host
berbeda meskipun field-field tertentu (misalnya alamat IP dan
port) digunakan untuk komunikasi.

STRUKTUR ALAMAT SOKET UMUM


Struktur alamat soket selalu dilintasi secara referensi ketika
disuguhkan sebagai sebuah argumen ke sembarang fungsi soket
manapun. Tetapi, fungsi-fungsi soket yang mengambil satu dari
pointer-pointer ini sebagai sebuah argumen harus berurusan dengan
struktur alamat soket dari keluarga protokol yang didukung.
Sebuah masalah adalah bagaimana mendeklarasikan tipe dari pointer
yang dilewati. Dengan ANSI C, solusinya sederhana : void * adalah
tipe pointer umum. Tetapi fungsi-fungsi soket lebih tua dari ANSI C
dan solusi yang dipilih adalah dengan mendefinisikan sebuah struktur
alamat soket umum dalam <sys/socket.h> sbb :

Struct sockaddr {
Uint8_t sa_len;

Sa_family_t sa_family; /*address family :


AF_xxx value */
Char sa_data[14]; /* protocol-
specific address */

Struktur Alamat Soket Umum : sockaddr


Fungsi-fungsi soket lalu didefinisikan sebagai mengambil sebuah
pointer ke struktur alamat soket umum, sebagaimana diperlihatkan di
sini dalam prototype fungsi C ANSI untuk fungsi bind :

int bind(int, struct sockaddr *, socklen_t)

Ini membutuhkan bahwa panggilan manapun ke fungsi-fungsi ini


yang harus mengkastakan pointer ke struktur alamat soket protokol-
tertentu menjadi sebuah pointer ke sebuah struktur alamat soket
umum. Contoh :

Struct sockaddr_in serv; /* IPv4 socket address


structure */
/*fill in serv{} */
bind (sockfd, (struct sockaddr *) &serv,
sizeof(serv));

Jika kita menghilangkan kasta “(struct sockaddr *)”,


kompilator C menghasilkan sebuah peringatan dalam bentuk
“warning : passing arg 2 of ‘bind’ from incompatible pointer type”
yang mengasumsikan header-header sistem memiliki sebuah
prototype ANSI C untuk fungsi bind.

Dari sudut pandang seorang pemrogram aplikasi, satu-satunya


penggunaan dari struktur alamat soket ini adalah mengkastakan
pointer ke struktur-struktur protokol-tertentu.

Catatan :
Dari perspektif kernel, alasan lain untuk menggunakan pointer
ke struktur alamat soket umum sebagai argumen-argumen
adalah bahwa kernel harus mengambil pointer pemanggil,
mengkastakannya ke sockaddr * dan lalu melihat nilai dari
sa_family untuk menentukan tipe struktur. Tapi dari
perspektif pemrogram aplikasi, akan lebih sederhana jika jenis
pointer adalah void *, mengabaikan kebutuhan akan kasta
esplisit.

STRUKTUR ALAMAT SOKET IPv6


Alamat soket IPv6 ditentukan dengan memasukkan header
<netinet/in.h>.

Struct in6_addr {
uint8_t s6_addr[16]; /* 128-bit IPv4 address*/
/* network byte order */
};
#define SIN6_LEN /* required for compile-time
test */

struct sockaddr_in6 {
uint8_t sin6_len; /* length of this struct
(24) */
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* transport layer
port# */
/* network byte ordered */
uint32_t sin6_flowinfo; /* priority & flow
label */
/* network byte ordered */
struct in6_addr sin_addr;
/* 32-bit IPv4 address*/
/* network byte ordered */
};

Struktur Alamat Soket IPv6 : sockaddr_in6

 Konstanta sin6_len harus ditentukan jika sistem mendukung


anggota panjang untuk struktur alamat soket.
 Keluarga IPv6 adalah AF_INET6, sedangkan keluarga IPv4 adalah
AF_INET.
 Anggota-anggota dalam struktur ini diurutkan sedemikian rupa jika
struktur sockaddr_in6 adalah 64-bit bersekutu, demikian juga
anggota 128-bit sin6_addr. Pada beberapa prosesor 64 bit, data
yang mengakses nilai-nilai 64 bit adalah optimal jika disimpan
pada suatu batas 64 bit.
 Anggota sin6_flowinfo dibagi ke dalam 3 field :
 Low-order 24 bit adalah flow label
 4 bit berikutnya adalah prioritas
 4 bit berikutnya adalah dicadangkan.
Penggunaan field prioritas masih sebuah topik penelitian.
Flow label 24-bit dapat dipilih secara acak oleh aplikasi bagi
sebuah soket yang diberikan (pengggunaan field ini masih
eksperiental). Sebuah flow adalah sebuah urutan dari paket-paket
yang berasal dari sebuah sumber tertentu ke sebuah tujuan
tertentu dimana sumber menginginkan penanganan khusus oleh
router-router . Untuk sebuah flow yang diberikan, sekali flow label
dipilih oleh sumber, ia tidak akan berubah. Sebuah 0 flow label
(default) mengidentifikasi paket-paket yang tidak memiliki sebuah
flow.

FUNGSI-FUNGSI PENGURUTAN BYTE


Misal terdapat sebuah integer 16-bit yang tersusun atas 2 byte.
Terdapat 2 cara untuk menyimpan 2 byte memori :
 Dengan low-order byte pada permulaan alamat, dikenal sbg little-
endian byte order. Atau
 Dengan high-order byte pada permulaan alamat dikenal sbg big-
endian byte order.
Little-endian byte order and big-endian byte order for a 16-bit integer

increasing memory
address

address A + 1 address A
Little-endian byte order : High-order byte Low-order byte

MSB 16-bit value LSB

Big-endian byte order : High-order byte Low-order byte


address A address A + 1

increasing memory
address

 Tidak terdapat standard antara ke-2 pengurutan byte ini. Kita


mungkin saja menjumpai sistem yang menggunakan ke-2 format
ini.
Contoh :
 Pengurutan byte yang digunakan oleh power CPU dari pc-
ibm dengan sistem operasi aix4.2.0.0 adalah big-
endian
 Pengurutan byte yang digunakan oleh alpha CPU dari dec
dengan sistem operasi osf4.0 adalah little-endian
 Pengurutan byte yang digunakan oleh sparc CPU dari sun
dengan sistem operasi sunos1.4 adalah big-endian

 Pengurutan byte yang digunakan oleh sebuah sistem yang


diberikan kita acu sebagai host byte order.

 Terdapat sistem yang dapat berubah antara little-endian dengan


big-endian byte order, baik ketika sistem di-reset (MIPS 2000)
ataupun pada 1 titik saat program sedang berjalan (Intel i860).

 Sebagai pemrogram jaringan, kita harus berurusan dengan


pengurutan byte karena protokol-protokol jaringan harus
menspesifikasikan sebuah network byte order. Contoh : dalam
sebuah segmen TCP terdapat sebuag 16-bit port number dan
sebuah 32-bit alamat IP. Tumpukan protokol pengirim dan
penerima harus menyetujui pada urutan apa byte-byte dari field-
field byte-jamak ditransmisikan. Protokol-protokol Internet
menggunakan urutan byte big-endian untuk integer byte-jamak
ini.
 Field-field ke dan dari header-header protokol menyelamatkan kita
dari kekhawatiran tentang detail ini. Tetapi baik sejarah maupun
Posix 1g menspesifikasikan bahwa field-field tertentu dalam
struktur-struktur alamat soket dipelihara dalam network byte
order.

 Letak keperdulian kita adalah mengkonversi antara host byte


order dengan network byte order. Kita gunakan 4 fungsi berikut
untuk mengkonversi antara 2 urutan byte ini.

 Pada nama dalam fungsi ini h berarti host, n berarti network, s


berarti short dan l berarti long.

#include <netinet/in.h>

uint16_t htons (uint16_t host16bitvalue) ;

uint32_t hton1 (uint32_t host32bitvalue) ;

Both return: value in network byte order

uint16_t ntohs (uint16_t net16bitvalue) ;

uint32_t ntoh1 (uint32_t net32bitvalue) ;

Both return: value in host byte order

 Saat menggunakan fungsi-fungsi ini, kita tidak perduli tentang


nilai-nilai aktual (big endian atau little endian) untuk host byte
order dan network byte order. Apa yang harus kita lakukan adalah
meyakini untuk memanggil fungsi-fungsi yang layak untuk
mengkonversi sebuah nilai yang diberikan antara host dan
network byte order.

 Pada sistem-sistem yang memiliki pengurutan byte yang sama


dengan protokol-protokol Internet (big-endian), ke-4 fungsi ini
biasanya didefinisikan sebagai makro null.

FUNGSI-FUNGSI MANIPULASI BYTE


Terdapat 2 kelompok fungsi yang beroperasi pada field-field
multibyte, tanpa menerjemahkan data, dan tidak mengasumsikan
bahwa data adalah sebuah string C null-terminated.
Kita membutuhkan tipe-tipe fungsi ini saat berurusan dengan struktur
alamat soket, karena kita butuh memanipulasi byte-byte nol tapi
field-field ini bukanlah string karakter C.
 Kelompok pertama fungsi memiliki nama dimulai dengan b (untuk
byte). Berasal dari 4.2 BSD dan masih disediakan oleh hampir
sistem manapun yang mendukung fungsi-fungsi soket.
 Kelompok kedua fungsi memiliki nama dimulai dengan mem
(untuk memori), adalah standard C ANSI dan disediakan oleh
sembarang sistem yang mendukung sebuah pustaka C ANSI.

#include <strings.h>

void bzero (void *dest, size_t nbytes);

void bcopy (const void *src, void *dest, size_t


nbyyes);

int bcmp (const void *ptrl, const void *ptr2,


size_t nbytes);

Returns: 0 if equel, nonzero if unequal

Catatan :
Tiga penggunaan qualifier const C ANSI di sini menunjukkan
bahwa apa yang ditunjuk dengan kualifikasi ini, src, ptr1,
dan ptr2, adalah tidak dimodifikasi oleh fungsi. Dengan kata
lain : memori yang ditunjuk oleh konstanta pointer dibaca tapi
tidak dimodifikasi oleh fungsi.

 bzero mengatur sejumlah byte ke nol di dalam tujuan. Kita


sering menggunakan fungsi ini untuk menginisialisasi sebuah
struktur alamat soket ke nol.
 bcopy memindahkan sejumlah byte dari sumber ke tujuan.
 bcmp membandingkan 2 string byte yang berubah-ubah. Nilai
yang dikembalikan adalah nol jika 2 string byte adalah identik,
selain itu adalah nonzero.

Fungsi-fungsi berikut adalah fungsi-fungsi C ANSI.


 memset mengatur sejumlah byte ke nilai c di dalam tujuan.
 memcpy adalah serupa dengan bcopy tapi urutan dari 2 argumen
pointer di-swap.
bcopy menangani dengan tepat field-field overlapping, sementara
prilaku memcpy tidak ditentukan bila sumber dan tujuan overlap.
Fungsi C ANSI memmove harus digunakan saat field-field overlap.
 memcp membandingkan 2 string byte yang berubah-ubah dan
mengembalikan nol jika mereka identik. Jika tidak identik, nilai
yang dikembalikan adalah baik lebih besar dari nol ataupun kurang
dari nol bergantung pada apakah byte tak sebanding yang
pertama yang ditunjuk oleh ptr1 adalah lebih besar dari ataukah
kurang dari byte berkorespondensi yang ditunjuk oleh ptr2.
Pembandingan dikerjakan dengan mengasumsikan bahwa 2 byte
tak sebanding tsb adalah unsigned char.

#include <strings.h>

void *memset (void *dest, int c, size_t len);

void *memcpy (void *dest, const void *src, size_t


nbyyes);

int memcmp (const void *ptrl, const void *ptr2,


size_t nbytes);

Returns: 0 if equal,<0 or >0 if unequal

Anda mungkin juga menyukai