Skip to content

Commit 9c21019

Browse files
authored
New Blog Post + Chore (#34)
* package bump, readme adjustment Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com> * update creds, update BlogLayout to conditionally render images Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com> * fix typo and nullchecks Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com> --------- Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
1 parent c56d999 commit 9c21019

File tree

6 files changed

+158
-16
lines changed

6 files changed

+158
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
## 🚀 Project Overview
1111

12-
A revised portofolio web built using Astro.js and TailwindCSS. Design by [David Cojocaru](https://github.com/cojocaru-david/cojocarudavid.me). Migrated to Astro.js 5, Vite 6 and TailwindCSS 4
12+
A revised portfolio web built using Astro.js and TailwindCSS. Original design by [David Cojocaru](https://github.com/cojocaru-david/cojocarudavid.me). Migrated to Astro.js 5, Vite 6 and TailwindCSS 4
1313

1414
## 🛠️ Technologies Used
1515

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"test:watch": "astro check --watch"
1313
},
1414
"devDependencies": {
15-
"@astrojs/check": "^0.9.5",
15+
"@astrojs/check": "^0.9.6",
1616
"@astrojs/sitemap": "^3.6.0",
1717
"@fontsource-variable/inter": "^5.2.5",
1818
"@fontsource/inter": "^5.2.5",
@@ -27,16 +27,16 @@
2727
"satori-html": "^0.3.2"
2828
},
2929
"dependencies": {
30-
"@astrojs/mdx": "^4.3.9",
31-
"@astrojs/react": "4.4.1",
30+
"@astrojs/mdx": "^4.3.13",
31+
"@astrojs/react": "4.4.2",
3232
"@iconify-json/cib": "^1.2.2",
3333
"@iconify-json/mdi": "^1.2.3",
3434
"@iconify-json/simple-icons": "^1.2.32",
3535
"@tailwindcss/postcss": "^4.1.7",
3636
"@tailwindcss/vite": "^4.1.4",
3737
"@types/react": "^19.1.4",
3838
"@types/react-dom": "^19.1.5",
39-
"astro": "^5.15.3",
39+
"astro": "^5.16.5",
4040
"astro-compressor": "^1.0.0",
4141
"astro-expressive-code": "^0.40.2",
4242
"astro-icon": "^1.1.5",
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
title: IP Address is Literally Just a Number
3+
description: An accidental encounter that made me question the concept of IP addresses.
4+
pubDate: 2025-12-11
5+
hero: ""
6+
heroAlt: ""
7+
tags: ["ip", "network", "computer", "technology"]
8+
---
9+
10+
I always consider myself a very curious person, especially when it comes to technology. I will try just about anything that is remotely interesting. However, I have to admit that while I grew up witnessing insane technological advancements, I never really got the opportunity to play with low-level stuff. Things like assembly, machine codes, low-level networking, etc.
11+
12+
## The Concept of IP Address (Specifically, IPv4)
13+
14+
Every single IT and IT-adjacent person knew about IPv4: 4 octets of decimal numbers, separated by dots. I always knew that it is a 32-bit integer value, separated into 4 octets. I can probably guess it is somewhat related to how a byte is 8 bits, and just took it for granted for years.
15+
16+
However, I came across a comment that made me question something. It is an absurdly simple statement, and goes something like:
17+
> Try pinging 1.1 from inside the box (VM).
18+
19+
Something doesn't look right. `1.1` lacks <b>TWO</b> extra dots. It looks like an IP address that is chopped into half. There is just no way `1.1` is a valid IP address
20+
21+
However, I decided to just go ahead and try pinging it. Unsurprisingly, it resolves to `1.0.0.1`, the Cloudflare DNS server:
22+
23+
```bash
24+
[root@localhost ~]# ping -c1 1.1
25+
PING 1.1 (1.0.0.1) 56(84) bytes of data.
26+
64 bytes from 1.0.0.1: icmp_seq=1 ttl=51 time=1.12 ms
27+
28+
--- 1.1 ping statistics ---
29+
1 packets transmitted, 1 received, 0% packet loss, time 0ms
30+
rtt min/avg/max/mdev = 1.119/1.119/1.119/0.000 ms
31+
```
32+
33+
This leads to my first question:
34+
35+
> <b>But, how?</b>
36+
37+
How does it assume and pad 2 zeroes in the middle segment?
38+
39+
## In Search of Explanation
40+
41+
Of course, as any good engineer would do, I embarked on a journey in search of explanations. My initial thought was:
42+
43+
> It must be some kind of weird, non-standard IP format.
44+
45+
Logically, I assume that the `ping` utility must have assumed that missing octets are merged. What if we tried to omit the dot notation altogether?
46+
47+
Assuming that `1.0.0.1` is a typical 32-bit integer, the decimal equivalent would be `16,777,217`:
48+
49+
```bash
50+
[root@localhost ~]# ping -c1 16777217
51+
PING 16777217 (1.0.0.1) 56(84) bytes of data.
52+
64 bytes from 1.0.0.1: icmp_seq=1 ttl=51 time=1.07 ms
53+
54+
--- 16777217 ping statistics ---
55+
1 packets transmitted, 1 received, 0% packet loss, time 0ms
56+
rtt min/avg/max/mdev = 1.065/1.065/1.065/0.000 ms
57+
```
58+
59+
Unsurprisingly, it worked. I tried several other formats, and the usual suspect worked: octal and hexadecimal:
60+
61+
```bash
62+
# for Octal, 0 prefix is used
63+
[root@localhost ~]# ping -c1 0100000001
64+
PING 0100000001 (1.0.0.1) 56(84) bytes of data.
65+
64 bytes from 1.0.0.1: icmp_seq=1 ttl=51 time=1.09 ms
66+
67+
--- 0100000001 ping statistics ---
68+
1 packets transmitted, 1 received, 0% packet loss, time 0ms
69+
rtt min/avg/max/mdev = 1.090/1.090/1.090/0.000 ms
70+
71+
# For hex, 0x prefix
72+
[root@localhost ~]# ping -c1 0x1000001
73+
PING 0x1000001 (1.0.0.1) 56(84) bytes of data.
74+
64 bytes from 1.0.0.1: icmp_seq=1 ttl=51 time=1.07 ms
75+
76+
--- 0x1000001 ping statistics ---
77+
1 packets transmitted, 1 received, 0% packet loss, time 0ms
78+
rtt min/avg/max/mdev = 1.073/1.073/1.073/0.000 ms
79+
```
80+
81+
We can even do some chaotic madness, such as mixed-dot notation. For example, we can do something like `0x8.010.1028` to ping google's `8.8.4.4`:
82+
- First Octet: 8 dec -> 0x8 hex
83+
- Second Octet: 8 dec -> 010 octal
84+
- Third + Fourth Octet combined: 4 * 256 + 4 = 1028 dec
85+
86+
```bash
87+
[root@localhost ~]# ping -c1 0x8.010.1028
88+
PING 0x8.010.1028 (8.8.4.4) 56(84) bytes of data.
89+
64 bytes from 8.8.4.4: icmp_seq=1 ttl=112 time=0.882 ms
90+
91+
--- 0x8.010.1028 ping statistics ---
92+
1 packets transmitted, 1 received, 0% packet loss, time 0ms
93+
rtt min/avg/max/mdev = 0.882/0.882/0.882/0.000 ms
94+
```
95+
96+
This experiment leads me to my second question:
97+
98+
> <b>But why?</b>
99+
100+
Who the hell in the 21st century needs to ping something in a hexadecimal or octal format? Or that chaotic mess of a mixed-dot notation?
101+
102+
I scoured through the internet, asking every single LLM, dug to any kind of public documents. However, not even the great Wikipedia has information about this.
103+
There are several discussions here and there, but nothing meaningful.
104+
105+
## It Is Not a Coincidence
106+
107+
My first assumption was that it must be some kind of legacy compatibility, considering the `ping` utility's age. However, it is actually more common than I thought:
108+
- It works on every single browser I tried
109+
- It works on every single OS I tried (Linux, Windows), across multiple versions
110+
- It works on every single programming language I tried
111+
112+
Go ahead and try typing `https://0x8.010.1028` into your browser's address bar. Both Chrome and Firefox will happily resolve it to `https://dns.google/`
113+
114+
Unsatisfied, I went ahead and dug even deeper.
115+
116+
## The Revelation
117+
118+
I found a bit of hint on [inet_addr's man page](https://linux.die.net/man/3/inet_addr). Utilities that parse IP addresses, such as `inet_addr()` and `inet_aton()` generally interpret the IP address in its binary form. This means that it does not care what is the input format, as long as the binary value stays the same. Under the hood, pretty much all modern OSes and network-facing tools use some kind of these implementations.
119+
120+
After further digging, The RFC for Internet Protocol, [RFC 791](https://datatracker.ietf.org/doc/html/rfc791#section-2.3), writes this in `Section 2.3`, Subsection `Addressing`:
121+
122+
> Addresses are fixed length of four octets (32 bits). An address begins with a network number, followed by local address (called the "rest" field). There are three formats or classes of internet addresses: in class a, the high order bit is zero, the next 7 bits are the network, and the last 24 bits are the local address; in class b, the high order two bits are one-zero, the next 14 bits are the network and the last 16 bits are the local address; in class c, the high order three bits are one-one-zero, the next 21 bits are the network and the last 8 bits are the local address.
123+
124+
After reading that, it clicked a bit for me. It doesn't specifically say that an IP address must use the 4-octet notation. Only how many bits are network and host segment in each class. Back then, when classful network architecture was still a thing, it made sense to have flexible ways to represent IP addresses. For example:
125+
126+
1. <b>Class C network has a local address size of 8 bits, or exactly 1 octet.</b>
127+
This aligns perfectly with modern day's `/24` subnet. Therefore, an address such as `192.168.1.1` is perfectly fine, since the host segment is perfectly represented by the last octet. You can instantly tell that `192.168.1.1` and `192.168.1.250` belongs to the same network.
128+
2. <b>Class B network has a local address size of 16 bits, or exactly 2 octets.</b>
129+
With 4 octet dot-decimal notation, the last 2 octets are kinda useless, since they belong to the same network segment. For example, `172.16.16.1` and `172.16.20.1` will always belong to the same network. A notation of `172.16.4097` and `172.16.5121` made more sense. You can read it as "host no. 4097 and 5121 on `172.16.x` network"
130+
3. <b>Class A network has a local address size of 24 bits, or exactly 3 octets.</b>
131+
In this case, the last 3 octets are host segment. A `1.1` IP of a Class A network can be read as "host no. 1 on `1.x` network".
132+
133+
Somehow, as we shifted into classless and CIDR-based networking, this notation just somewhat stuck around. Knowing about this in 2025 probably will not help in anything, but the chase itself was a fun journey for me. After all, there is no such thing as useless knowledge.

src/data/contributions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
{
7070
"name": "ItsHarta/ItsHarta",
7171
"url": "-",
72-
"description": "My Personal Website & Portofolio page, overhauled & built with Astro.js and Tailwind CSS.",
72+
"description": "My Personal Website & Portfolio page, overhauled & built with Astro.js and Tailwind CSS.",
7373
"languages": [
7474
"NodeJS",
7575
"JSON",

src/data/credentials.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
"title": "Microsoft Certified",
2020
"text": "Azure Fundamentals AZ-900",
2121
"logo": "mdi:microsoft"
22+
},
23+
{
24+
"title": "Microsoft Certified",
25+
"text": "Security Operations Analyst SC-200",
26+
"logo": "mdi:microsoft"
2227
},
2328
{
2429
"title": "The SecOps Group",

src/layouts/BlogLayout.astro

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { author, tag } from "@data/socials";
99
interface Props {
1010
title: string;
1111
description: string;
12-
image: ImageMetadata;
13-
imageAlt: string;
12+
image?: ImageMetadata;
13+
imageAlt?: string;
1414
pubDate: Date;
1515
url: string;
1616
updatedDate: Date | undefined;
@@ -83,14 +83,18 @@ const fullPubDate = pubDate.toLocaleDateString("en", {
8383
</p>
8484
</div>
8585
</div>
86-
<Image
87-
src={image}
88-
alt={imageAlt}
89-
loading="eager"
90-
class="rounded-lg"
91-
width={1200}
92-
height={630}
93-
/>
86+
{
87+
(image && imageAlt)
88+
&& <Image
89+
src={image}
90+
alt={imageAlt}
91+
loading="eager"
92+
class="rounded-lg"
93+
width={1200}
94+
height={630}
95+
/>
96+
}
97+
9498
</header>
9599
<article
96100
class="prose prose-code:before:hidden prose-code:after:hidden dark:prose-invert lg:prose-lg dark:prose-code:text-zinc-300 dark:prose-a:text-blue-400 prose-a:text-blue-600 max-w-none hover:prose-a:underline focus:prose-a:underline prose-a:no-underline dark:prose-headings:text-teal-500 prose-img:rounded-lg"

0 commit comments

Comments
 (0)