Files
Network-Programming-in-C/readme.md
2024-09-01 17:39:22 +05:30

238 lines
5.5 KiB
Markdown

# Network Programming in C
Quick reference to `struct`(s) and apis' used for networking applicaton in C language.
Let's first discuss about the important `struct` and then how we use apis' to establish networking functionality.
## struct(s) used are :-
* **struct** addrinfo -
```
struct addrinfo {
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
int ai_socktype; // SOCK_STREAM, SOCK_DRAM
int ai_protocol; // use 0 for "any"
size_t ai_addrlen; // size of ai_addr in bytes
struct scokaddr *addr; // struct sockaddr_in or _in6
char *ai_canonname; // full canonical hostname
struct addrinfo *ai_next; // linked list, next node
};
```
1. ai_flags :
Type : `int`
Value : `AI_PASSIVE`, `AI_CANONNAME`.
Purpose : Help determine the processing path for `getaddrinfo()`.
* For ex : `AI_PASSIVE` suggest the `getaddrinfo()` to get the address of the host machine the program is running on.
2. ai_family :
Type : `int`
Value : `AF_INET (IPv4)`, `AF_INET6 (IPv6)` or `AF_UNSPEC`.
Purpose : Specify which type of IP address (in terms of representation) does it hold.
3. ai_socktype :
Type : `int`
Value : `SOCK_STREAM`, `SOCK_DRAM`.
Purpose : Specify what kind of socket we are interested in using.
4. ai_protocol :
Type : `int`
Value : use 0 for "any".
Purpose : What kind of protocol we are intending to use.
5. ai_addrlen :
Type : `size_t`
Value : size of ai_addr in bytes.
Purpose : What is the size of struct sockaddr pointer holds.
6. addr :
Type : `struct sockaddr *`
Value : address in form of `struct sockaddr`.
Purpose : Holding the actual address.
7. ai_cannonname :
Type : `char *`
*I don't know what's it's used for.*
8. ai_next :
Type : `struct addrinfo *`
Value : address of next `struct addrinfo`.
Purpose : Intending to have a linked list.
---
* **struct** sockaddr -
```
struct sockaddr{
unsigned short sa_family; // Address family, AF_XXX
char sa_data[14]; // 14 bytes of protocol address
};
```
1. sa_family :
Type : `unsigned short`
Value : `AF_XXX`
Purpose : Specify the address family type.
2. sa_data :
Type : `char`
Value : IP address in for raw byte data.
Purpose : Buffer for storing the actual address in *Network Byte Order*.
> [!IMPORTANT]
> Using this structure and hard coding every thing on it is very tedious. Use `struct sockaddr_in` for IPv4 or `struct sockaddr_in6` for IPv6.
---
* **struct** sockaddr_in -
```
struct sockaddr_in{
short int sin_family; // Address family, AF_INET
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
```
1. sin_family :
Type : `short int`
Value : `AF_INET`.
Purpose : Specifying the IP address belongs to IPv4.
2. sin_port :
Type : `unsigned short int`
Value : Port number.
Purpose : Stores the port number which will be used by the created socket.
3. sin_addr :
Type : `struct in_addr`
Value : Internet address
Purpose : Act as a buffer to store Internet address in raw byte.
4. sin_zero :
Type : `unsigned char`
Value : All element set to zero.
Purpose : Used for padding to match the size of `struct sockaddr`.
* **struct** in_addr -
```
struct in_addr{
uint32_t s_addr;
};
```
1. s_addr :
Type : `uint32_t`
Value : IP address in raw byte in Network Byte Order.
Purpose : Act as buffer to store IP address.
---
* **struct** sockaddr_in6 -
```
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
};
```
> `sin6_family`, `sin6_port` and `sin6_addr` are similar to the corresponding fields of `struct sockaddr_in6`.
* **struct** in6_addr -
```
struct in6_addr{
unsigned char s6_addr[16]; //IPv6 address
};
```
1. s6_addr :
Type : `unsigned char array`
Value : IPv6 address in raw byte.
Purpose : Act as a buffer to store IPv6 address.
---
* **struct** sockaddr_storage -
> [!IMPORTANT]
> Because `sockaddr_in6` is larger in size than `sockaddr_in` and we may not know which to use when, we can use `sockaddr_storage` for storing any of the two and type-cast to their respective type.
```
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];
};
```
1. ss_family :
Type : `sa_family_t`
Value : `AF_INET` or `AF_INET6`.
Purpose : To distinguish address family it contains.