ابزار کاربر

ابزار سایت


c-socket-programming:inet_pton

تابع ()inet_pton

برای استفاده از آدرس IP در اکثر توابع، باید ابتدا IP از شکل رشته ای (شکل نمایشی یا presentation) به شکل Network-Byte-Order تبدیل شود. این تبدیل توسط ()inet_pton انجام می شود.

#include <arpa/inet.h>

int inet_pton(int af, const char *src, void *dst);

تعریف struct in_addr به شکل زیر است

typedef uint32_t in_addr_t;
struct in_addr {
    in_addr_t s_addr; // that's a 32-bit int (4 bytes)
};

نمونه تبدیل در IPv4 :

// inet_pton-ipv4.c
// gcc -std=c99 -o inet_pton-ipv4 inet_pton-ipv4.c
#include <stdio.h>
#include <arpa/inet.h>
 
int main()
{
    char *ipv4 = "192.168.154.239";
    struct in_addr ia;
 
    inet_pton(AF_INET, ipv4, &ia);
 
    printf("ipv4 string : %s\n", ipv4);
    printf("sizeof(struct in_addr) : %ld\n", sizeof(struct in_addr));
    printf("ia hex : %X\n", ia.s_addr);
    printf("ia hex : %X\n", ia);
    printf("ia dec : %u\n", ia.s_addr);
    printf("ia dec : %u\n", ia);
 
    return 0;
}

خروجی :

ipv4 string : 192.168.154.239
sizeof(struct in_addr) : 4
ia hex : EF9AA8C0
ia hex : EF9AA8C0
ia dec : 4019890368
ia dec : 4019890368

همانطور که در مثال فوق مشاهده می شود چون struct in_addr فقط یک عضو دارد(s_addr) پس می توان از ia و ia.s_addr به شکل یکسان استفاده کرد.

تفاوت Network-Byte-Order و Host-Byte-Order در خروجی فوق به خوبی دیده میشود چون 192 معادل 0xC0 و 168 معادل 0xA8 و 154 معادل معادل 0x9A و 239 معادل 0xEF است و ضمن ذخیره سازی در حافظه به شکل Little-Endian ذخیره شده (EF9AA8C0)

در تعریف struct in_addr می بینیم که s_addr از نوع uint32_t تعریف شده پس بجای struct in_addr می توان از unsigned int استفاده کرد که روش مناسبی نیست. ولی برای درک بهتر این روش را آزمایش میکنیم :

// inet_pton-ipv4.c
// gcc -std=c99 -Wall -Wextra -Werror -pedantic -o inet_pton-ipv4 inet_pton-ipv4.c
#include <stdio.h>
#include <arpa/inet.h>
 
int main()
{
    char *ipv4 = "192.168.154.239";
    unsigned int ui;
 
    inet_pton(AF_INET, ipv4, &ui);
 
    printf("ipv4 string : %s\n", ipv4);
    printf("sizeof(unsigned int) : %ld\n", sizeof(unsigned int));
    printf("ia hex : %X\n", ui);
    printf("ia dec : %u\n", ui);
 
    return 0;
}

خروجی

ipv4 string : 192.168.154.239
sizeof(unsigned int) : 4
ia hex : EF9AA8C0
ia dec : 4019890368

همانطور که در مثال فوق مشاهده میشود، می توان از unsigned int به راحتی به جای struct in_addr استفاده کرد. ترجیح بر این است برای یکپارچگی بین IPv4 و IPv6 از struct in_addr و struct in6_addr استفاده شود. چون IPv6 به شکل یک رشته 16Byte و‌ IPv4 به شکل یک unsigned int که 4Byte است نگهداری می شود.

به دلیل تعریف dst از نوع *void است که می توانیم برخورد چند گانه با آن داشته باشیم (Poor Man's Polymorphism)

نمونه تبدیل در IPv6 :

// inet_pton-ipv6.c
// gcc -std=c99 -Wall -Wextra -Werror -pedantic -o inet_pton-ipv6 inet_pton-ipv6.c
 
#include <stdio.h>
#include <arpa/inet.h>
 
int main()
{
    char *ipv6 = "0011:2233:4455:6677:8899:AABB:CCDD:EEFF";
    struct in6_addr i6a;
 
    inet_pton(AF_INET6, ipv6, &i6a);
 
    printf("sizeof(struct in6_addr) : %ld\n", sizeof(struct in6_addr));
    printf("ipv6 str: %s\n", ipv6);
    for(long unsigned int i=0; i < sizeof(struct in6_addr); i++)
	    printf("%02X ", i6a.s6_addr[i]);
    printf("\n");
 
    return 0;
}

خروجی :

sizeof(struct in6_addr) : 16
ipv6 str: 0011:2233:4455:6677:8899:AABB:CCDD:EEFF
00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF

در مثال فوق مشاهده می شود که در IPv6 روش Host-Byte-Oder و Network-Byte-Order یکسان است.

c-socket-programming/inet_pton.txt · آخرین ویرایش: 2024/06/18 22:49 توسط pejman

به جز مواردی که ذکر می‌شود، مابقی محتویات ویکی تحت مجوز زیر می‌باشند: Public Domain
Public Domain Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki