11/9/2024

Best kernel for audio? by Ryo

Hi! I wanted to share something that I have been looking into related to Realtime kernel. RT kernel is a kernel which aims to achieve low latency for process scheduling. One of its application is audio and I'm trying to see how it benefits from RT kernel. Below is the setup that I'm currently working on. Machine: Mac M2 (which I bought it recently, it runs on Linux😆) Audio Editor: Ardour Although I'm still trying to understand how Ardour and audio input devices work, today I went to my friend's place who plays guitar to see how it works. It was quite intersting to see his setup, especially the audio interface which converts sound signals from guitar into digital bits so that PCs can do interesting suff (please correct me if I were wrong...). I am not yet ready to do any kind of testing(benchmarking?), but my guess is that higher the frequency you try to capture, you will need a kernel with a lower latency! By the way, besides playing around with guitar, Today I made a strawberry pi for the first time. I tasted ok but yet there remained a room for improvement. Maybe I can give another try next week😋. See you on the next post!

2/29/2024

Looking into ARM by Ryo

1/6/2024

Hello, world! by Ryo

Hi, I just wanted to make a brief post (its new year). At the end of the last year, I was on travel to India, the country I always wanted to visit since college(couldn't due to covid). During the trip, I had a serious food poisoning. But I still consider it was a great trip(even though I still haven't had curry ever since I got back) and I am already looking forward to the next trip to India(喉元過ぎれば熱さ忘れる). I had a good time giving time for myself to think about this and that. Throughout the last year, I was trying to figure out this and that, and I believe now I at least have a direction. And I just feel so greatful, given the chance to pursuit what I want.

11/25/2023

Process vs Thread by Ryo

Hi, recently I have been looking into how user processes are prepared. Today's post is about the how user process and thread are being prepared in terms of allocated memory. When a new process or thread being created, it calls clone system call. If you want to create a thread, you can pass CLONE_VM flag to the system call. One of the difference between a process and thread is that wheather it shares its memory space or not. The latter does but the former does not, and today's post is about looking into this difference. In order to see the difference, I prepared a program which ① the parents process assignes a variable with 5, and ② the cloned child process rewrites the variable with 10. The difference mentioned earlier can be seen at the ② point. Let's first see how the process looks like. Below shows that the PID 1628 is the parent and the 1629 is the child. crash> ps | grep clone 1628 1601 0 ffff94fd4a271c80 IN 0.1 2628 1336 clone 1629 1628 0 ffff94fd4123b900 IN 0.1 2628 884 clone crash> Now let's take a look at the physical address correspoding to the variable's virtual address which is 0x404068. You can see the corresponding physical address is 17bfe068. As expected, the value at the address is still 5 as the child process does not share the address space. crash> vtop -c ffff94fd4a271c80 404068 VIRTUAL PHYSICAL 404068 17bfe068 ... crash> rd -p 17bfe068 10 17bfe068: 0000000000000005 00000000014b72b0 .........rK..... ... crash> However, if you take a look at the threading, you will see the varible is now changed as the child shares the same address space and rewrites the variable. crash> ps | grep clone 1714 1601 0 ffff94fd44e2d580 IN 0.1 2628 1396 clone 1715 1714 0 ffff94fd41291c80 IN 0.1 2628 964 clone crash> vtop -c ffff94fd44e2d580 404068 VIRTUAL PHYSICAL 404068 1161e068 ... crash> rd -p 1161e068 10 1161e068: 000000000000000a 00000000004c32b0 .........2L..... ... crash> That's it for the today's post. Note that I used x86 for this experiment as vtop on arm64(below) did not work. I wonder why🤔. Might be fun looking into it. crash> vtop -c 11884 aaaae706c84c VIRTUAL PHYSICAL vtop: invalid structure member offset: mm_struct_mmap FILE: memory.c LINE: 4007 FUNCTION: vm_area_dump() [/usr/bin/crash] error trace: aaaae706c84c => aaaae706456c => aaaae7101180 => aaaae71010ec vtop: invalid structure member offset: mm_struct_mmap FILE: memory.c LINE: 4007 FUNCTION: vm_area_dump() crash>

11/19/2023

The Very First Process by Ryo

Hi, I wanted make a post on how the first process gets initiated as I have been playing around with qemu recently. Specifically, I will describe how the parameters below lead to the /sbin/init, which has the pid of 1. admin@ip-10-0-16-6:~/busybox/busybox$ qemu-system-aarch64 -M virt -cpu cortex-a72 -m 1024 -kernel /boot/vmlinuz-6.1.0-13-cloud-arm64 -initrd /home/admin/busybox/busybox/rootfs -append "root=/dev/ram0 rdinit=/sbin/init nokaslr" -nographic Let's start with the source code. After the kernel finishes the initilization of this and that, it gets ready for the first process and calls rest_init. The function inits the rest and calls kernel_init, and then run_init_process gets called. Now back to the arguments and see what it's doing. If you take a look at the man page of initrd, it says that -initrd gets uncompressed onto the /dev/ram0, which then mounted as the inital root file system. Here I found little confusing is that if you specify root as /dev/ram0, the initial root file system, which is /dev/ram0, will remain as the normal root file system. Let's make sure that the first run_init_process is the one being called for initiating the first process in the case of using /dev/ram0 as the normal root file system. Here you can see that the execute_command has /sbin/init, the program specifed by rdinit from the normal root file system which now is the /dev/ram0. (gdb) print ramdisk_execute_command $1 = 0xffff00003fdf0196 "/sbin/init" (gdb) print execute_command $2 = 0x0 (gdb) By the way, don't forget to specify "nokaslr" for the boot parameter. Otherwise, break points won't work😑. That is it for this post!

11/11/2023

Studying Kprobe by Ryo

I have been trying to understand how systemtap works. And I want to share some of the things I studied about systemtap, or kprobe which systemtap uses internally. When you register a handler through kprobe, it inserts brk instruction at the specified offset from the chosen symbol as shown below. You can find the sample program I used for testing kprobe here. ┌──(kali㉿kali-raspberry-pi)-[~/proper-version-name/dumpable-kernel] └─$ sudo crash ./vmlinux crash> dis cpus_are_stuck_in_kernel 0xffffffe9258290a4 : mov x9, x30 0xffffffe9258290a8 : nop 0xffffffe9258290ac : brk #0x4 0xffffffe9258290b0 : stp x29, x30, [sp, #-32]!0xffffffe9258290b4 : mov x29, sp Once it reaches the brk instruction, it triggers an el1 synchronous exception. In the case of brk instruction, EC will set to 0x3C and will call el1_dbg. Where I found interesting is how brk_handler gets called. When I was first reading the source code, I thought brk_early64 is the one which gets called. However, tracing the functions showed that brk_handler is the one which was actually being called. Note that some of the functions doesn't appear because they are inlined... ┌──(kali㉿kali-raspberry-pi)-[~/systemtap/kprobe_observation] └─$ sudo trace-cmd report -i trace.dat | grep "kexec_\|kimage_\|cpus_are_stuck_in_kernel\|do_debug_exception\|early_brk64\|do_bad\|brk_handler\|debug_exception_enter\|debug_exception_exit" ... kexec-1060 [000] 246.092881: function: do_debug_exception kexec-1060 [000] 246.092884: function: brk_handler In addition, I found that the entry for the early_brk64 is replaced with brk_handler🤨. crash> rd debug_fault_info ffffffe926d6a168: ffffffe925831fe4 ...%.... crash> struct fault_info ffffffe926d6a168 10 fn = 0xffffffe925831fe4 , fn = 0xffffffe925815c50 , fn = 0xffffffe925831b04 , fn = 0xffffffe925837510 , fn = 0xffffffe925837510 , fn = 0xffffffe925837510 , struct fault_info { fn = 0xffffffe925815b04 , sig = 5, code = 1, name = 0xffffffe926635b28 "BRK handler" } fn = 0xffffffe925837510 , fn = 0xffffffe9263ec6d0 , fn = 0xffffffe9259d5df0 , If you trace back the brk_handler, you will find how this replacement happens. During the initialization, trap_init replaces the early_brk64 with brk_handler for the reason which I haven't found yet... That is it for today's post!

11/5/2023

Tracing and Tapping Kernel by Ryo

When I was trying to kexec on my RPI4, I had trouble loading the image. I remember that in order to diagnose the problem, I inserted bunch of printks to understand what was going on. Today I am writing about these 2 tools I recently started looking into which are used for debugging, maybe not just for debugging, called trace-cmd and systemtap. Recalling back when I was tackling the problem of kexec not loading the image, my first approach was to strace kexec and trace the associated system calls. It looked something like below. ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo strace kexec -l /boot/kdumpv07222023.img --reuse-cmdline ... kexec_load(0x2c9e6a0, 3, [{buf=0x7ff3c37010, bufsz=22475264, mem=0x1600000, memsz=23658496}, {buf=0x55555b7850, bufsz=55722, mem=0x2c90000, memsz=57344}, {buf=0x55555c57b0, bufsz=13656, mem=0x2c9e000, memsz=16384}], KEXEC_ARCH_AARCH64) = -1 EBUSY (Device or resource busy) From what the strace above gave me, I started looking into the source code and inserted pritnks to see which functions are being called and what they are returning. Very clever haha🙃. But now equipped with trace-cmd and systemtap, I think I'm released from this flooding of prinks, Phew... Let's say that I want to know which functions are being called. Considering the above case, I can use trace-cmd to trace all the functions being called and decide which of them might be the one that I am interested in. ┌──(kali㉿kali-raspberry-pi)-[~/systemtap] └─$ trace-cmd report -i ebusy.dat | grep "kexec_\|kimage_\|cpus_are_stuck_in_kernel" kexec-945 [000] 100.885692: function: kexec_image_load_default ... kexec-945 [000] 100.886629: function: machine_kexec_prepare kexec-945 [000] 100.886631: function: cpus_are_stuck_in_kernel kexec-945 [000] 100.887281: function: kimage_free ... When the system call for loading the kexec image is called, it calles either of kexec_load or kexec_file_load. The EBUSY error is returned by its sanity check which is handle by the cpus_are_stuck_in_kernel show above. You can guess that the cpus_are_stuck_in_kernel is the one that we are interested by reading the source code as the subsequent function are not being called. https://github.com/raspberrypi/linux/blob/rpi-6.1.y/kernel/kexec_file.c#L368 https://github.com/raspberrypi/linux/blob/rpi-6.1.y/arch/arm64/kernel/machine_kexec.c#L70 https://github.com/raspberrypi/linux/blob/rpi-6.1.y/arch/arm64/kernel/smp.c#L1093
In order to make sure that cpus_are_stuck_in_kernel is the one preventing from loading the image, let's take a look at what its return value is. Here we can use systemtap, and below indeed shows the return value is EBUSY(-16). ┌──(kali㉿kali-raspberry-pi)-[~/systemtap] └─$ sudo stap -v kexec.stp Pass 1: parsed user script and 471 library scripts using 115208virt/100712res/6596shr/94160data kb, in 1860usr/360sys/2232real ms. Pass 2: analyzed script: 1 probe, 2 functions, 0 embeds, 0 globals using 174920virt/161736res/7860shr/153872data kb, in 6930usr/700sys/7637real ms. Pass 3: using cached /root/.systemtap/cache/07/stap_0744f24e121f251cab8e1f8c2089a20b_1355.c Pass 4: using cached /root/.systemtap/cache/07/stap_0744f24e121f251cab8e1f8c2089a20b_1355.ko Pass 5: starting run. machine_kexec_prepare returned -16 Pass 5: run completed in 70usr/670sys/49763real ms. I feel that what systemtap does is soo magical. And I'm not really comfortable using magic... Next I might look into how systemtap does its magic💡.

10/29/2023

perf and Interrupts by Ryo

Hi! Today's post is about perf which is a tool I recently started looking into. perf monitors hardware/software events and is used for performace analysis. I have only started looking into the tool and haven't yet explored what its capable of but I will share something I found interesting about the tool for this post. If you take a look at how perf collects hardware/software events, you will find that there is a hardware(Performance Monitoring Unit) dedicated for monitoring the system. PMU sends interrupts to check in the time(?) spent on CPU at function level. Here I will share the result of "perf top" on RPI4(arm64). Samples: 10K of event 'cycles', 4000 Hz, Event count (approx.): 291421676 lost: 0/0 drop: 0/0 Overhead Shared Object Symbol 16.40% [kernel] [k] _raw_spin_unlock_irqrestore 7.16% [kernel] [k] finish_task_switch.isra.0 7.14% [kernel] [k] arch_counter_get_cntpct 4.03% [kernel] [k] _raw_spin_unlock_irq 3.60% [kernel] [k] _raw_read_unlock_irqr And here is the result of "perf top" on Optiplex(x86). Samples: 10K of event 'cycles', 4000 Hz, Event count (approx.): 297333264 lost: 0/0 drop: 0/0 Overhead Shared Object Symbol 4.45% [kernel] [k] native_sched_clock 1.88% perf [.] dso__find_symbol 1.64% perf [.] io__get_char 1.61% perf [.] rb_next 1.59% [kernel] [k] menu_select ... One thing to note here is that you can see _raw_spin_unlock_irqrestore is spending a lot time on RPI4(arm64) unlike Optiplex(x86). If you recall that currently arm64 does not support NMI-like inturrupt, it's clear that why perf is showing such high overhead for _raw_spin_unlock_irqrestore. Below shows the RPI4(arm64) and Optiplex(x86)'s interrupts triggered by PMU which is used for collecting data shown on "perf top". As Optiplex(x86)'s PMU uses NMI unlike RPI4(arm64), whenever it interrupts, its the exact function that is currently running at the moment. However, in the case of RPI4(arm64), the interrupts generated by PMU has the same priority as the currently runnning interrupt and needs to wait until it releases by calling _raw_spin_unlock_irqrestore. ┌──(kali㉿kali-raspberry-pi)-[~] └─$ cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 ... 29: 4111 0 0 0 GICv2 48 Level arm-pmu 30: 0 6871 0 0 GICv2 49 Level arm-pmu 31: 0 0 3374 0 GICv2 50 Level arm-pmu 32: 0 0 0 533 GICv2 51 Level arm-pmu ryo@ryo-OptiPlex-3020:~$ cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 ... NMI: 7723 9494 7256 6888 Non-maskable interrupts ... PMI: 7723 9494 7256 6888 Performance monitoring interrupts That's it for this post. It's fun to take a look at different architecture other than arm64. It helps to deepen your understanding of cantain features(like interrupts) by making a comparison🧐. I also wanted to share that I decided to make the memos private. Instead, my plan is to make posts more often here on this blog, See you on the next post!

9/18/2023

Exception, by NULLポインタ dereference by Ryo

Hi, today I will be posting about exceptions which is the subject I found very fun and interesting as it requires a good understanding of hardware along with the linux source code. I've yet only started exploring the subject but I'll share some of the stuff I've learned so far. There are many situations that can trigger an exception such as system call, packet reception, etc... But for this post, I will specifically focus in the case of null pointer dereference😏. As the MMU translation fault is an synchronous exception, it referes to the table and calls el1h_64_sync. Whenever an exception is triggered, it saves the state of registers by storing them on the stack and passes the sp to the subsequent functions. You can see how el1h_64_sync stores the registers on the stack here. crash> disas el1h_64_sync Dump of assembler code for function el1h_64_sync: 0xffffffe8e681121c <+0>: stp x0, x1, [sp] 0xffffffe8e6811220 <+4>: stp x2, x3, [sp, #16] ... 0xffffffe8e6811278 <+92>: mov x0, sp 0xffffffe8e681127c <+96>: bl 0xffffffe8e739f080 After el1h_64_sync has done its job, in the case of null pointer dereference, it calles el1_abort by refereing to the ESR reigster which is 0x25. Then el1_abort refers to this table defined as fault_info which is used to trigger the appropriate handlers based on ESR register. The handler will be called based on the offset from the fault_info. In the case of Null pointer dereference, do_translation_fault will be triggered. crash> sym fault_info ffffffe833bcb000 (d) fault_info crash> sym do_translation_fault ffffffe833bae0b4 (t) do_translation_fault crash> rd ffffffe833bcb000 0x20 ffffffe833bcb000: ffffffe8330377a0 0000008000000009 .w.3............ ffffffe833bcb010: ffffffe833e18a80 ffffffe8330377a0 ...3.....w.3.... ffffffe833bcb020: 0000008000000009 ffffffe833e18a98 ...........3.... ffffffe833bcb030: ffffffe8330377a0 0000008000000009 .w.3............ ffffffe833bcb040: ffffffe833e18ab8 ffffffe8330377a0 ...3.....w.3.... ffffffe833bcb050: 0000008000000009 ffffffe833e18ad8 ...........3.... ffffffe833bcb060: ffffffe833bae0b4 000000010000000b ...3............ ffffffe833bcb070: ffffffe833e18af8 ... After the call of do_translation_fault, it simply calls functions accordingly. One thing to note is that once it gets to die, you can see that it won't panic unless you enable CONFIG_PANIC_ON_OOPS. That's it for this post! I will be digging deeper into this subject and might be sharing them here as well✍️.

9/17/2023

Backtracing 101 by Ryo

Hi, last post I made was about "task_struct" which is used to manage tasks and I wrote little bit about how stacks are associated. In this post, I will share how to read a stack to trace the functions being called from a register being dumped at the moment of panic. Here is an example of a dumped register that you will see in the event of panic. The registers of interest are frame pointer(x29) and program counter(x30). [ 340.163740] pc : machine_kexec+0x44/0x200 [ 340.163757] lr : machine_kexec+0x44/0x200 [ 340.163773] sp : ffffffc00a963b50 [ 340.163782] x29: ffffffc00a963b50 x28: ffffff80bc6f3e00 x27: 0000000000000000 ... [ 340.163982] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff80bc6f3e00 In ARM64, whenever you branch(bl) to a new function, the instruction below gets called. It stores the fp and pc at the address where sp plus offset points to. As a result, fp is pointing at the address of the previous frame and it enables to track frames in a linked list fashion. stp x29, x30, [sp, offset]! Now let's take a look at the actual stack. I won't dump the entire stack👾, but take a look here if interested. If you start from ffffffc00a963b50(X29), you will get a list of fps shown below. ffffffc00a963b50 ffffffc00a963b80 ffffffc00a963d10 ffffffc00a963df0 ffffffc00a963e00 ffffffc00a963e30 ffffffc00a963e70 ffffffc00a963e80 ffffffc00a963ea0 ffffffc00a963fe0 0000000000000000 And as you can see from the stp instruction, the return addresses which points to the functions that we are intrested in, are on the stack right next to the fps. If we trace the addresses on the stack next to the fps and look up the associated functions, we get the backtrace. crash> sym ffffffdefb15fa74 ffffffdefb15fa74 (T) __crash_kexec+164 ffffffdefbb8dd14 (T) panic+444 ffffffdefb0aaef0 (T) __arm64_sys_p4ni9+64 ffffffdefb029a60 (t) invoke_syscall+80 ffffffdefb029b9c (t) el0_svc_common+108 ffffffdefb029c98 (T) do_el0_svc+56 ffffffdefbb9b9d4 (t) el0_svc+48 ffffffdefbb9be28 (T) el0t_64_sync_handler+244 ffffffdefb011548 (t) el0t_64_sync+396 As you can see, this trace show that the panic was triggered by an user space exception. For the next post, I will write about how excpetions are triggered and how they work😉.

9/16/2023

Having fun with "crash", Looking into task_struct by Ryo

Hi, I have been working on kernel dump which works after the call of panic(). Along the way, I learned a lot about kernel basics and I decided to share some of them here as my memos are getting quite messy. For this post, I will share how kernel manages tasks using the structure task_struct. You can find the source below. https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/asm/thread_info.h#L24 Here is an example of the task "Softwar~cThread" running at the moement of panic. You can see the struct task_struct has an address of ffffff805ea4be00 given at "TASK". crash> bt -c 1 PID: 2132 TASK: ffffff805ea4be00 CPU: 1 COMMAND: "Softwar~cThread" #0 [ffffffc00800bd60] crash_save_cpu at ffffffdefb15ff60 ... If you look at the definition of task_struct, there are some members that might be interesting to take a look at. The member that caught my attention is stack which points to the stack for the task. crash> struct task_struct ffffff805ea4be00 struct task_struct { thread_info = { ... }, __state = 0, stack = 0xffffffc00a110000, If you take a look at the memory where the "stack" points at, you can see the exact stack at the moment of panic. crash> rd ffffffc00a110000 0x1FFF ffffffc00a110000: 0000000057ac6e9d 0000000000000000 .n.W............ ffffffc00a110010: 0000000000000000 0000000000000000 ................ ffffffc00a110020: 0000000000000000 0000000000000000 ................ ... ffffffc00a113f90: 0000007f5869bfa0 0000007f5eb5e100 ..iX.......^.... ffffffc00a113fa0: 0000007ff7c1d8a8 0000007f5eb5e100 ...........^.... ffffffc00a113fb0: 0000007ff7c1d8d4 0000000080000000 ................ ffffffc00a113fc0: 0000007feb8f2194 0000000000000062 .!......b....... ffffffc00a113fd0: 0000000000000000 0000000000000000 ................ ffffffc00a113fe0: 0000000000000000 0000000000000000 ................ ffffffc00a113ff0: 0000000000000000 0000000000000000 rd: invalid kernel virtual address: ffffffc00a114000 type: "64-bit KVADDR" crash> One thing that I could't figure out is that I don't see thread_info at the bottom of the stack. I read a lot of articles explaining that each stack has a thread_info at its bottom... Maybe I should look deeper into how tasks are scheduled and stacks gets prepared😎.

7/30/2023

Kernel Crash Dump by Ryo

Hi, I wanted to share something that I have been working on along with the networking stack, kernel crash dump. The reason why started working on the subject is because I quite often got stuck on debugging kernel panic and I need a tool besides inserting bunch of printks😅. Along the way, I tried many different approches I found online and I finally made a kernel with functioning kexec in the event of kernel panic. Here is the source code that I prepared for ARM64(Raspberry Pi 4). https://github.com/ryofslife/dumpable-kernel You can find the details of implementation and all the researches that I have done here. https://scrapbox.io/ryozioput/ I removed some parts of the code from the original source and added a system call which triggers a kernel panic for testing the kexec rebooting of the loaded kernel. Besides the coding, I will share some of the tunings that you have to do if you want to enable kexec on Raspberry Pi(quad-core, 4GB RAM). First, you have to make sure that you have reserved enough memory for the loaded kernel. You can check memory info on /proc/meminfo and estimate how much memory your system will need. If the memory you reserved was too small, it will hang and never boot up. For my system, 512MB was enough to get away with the boot up process. You might need more if you are running additional processes after the boot up. ┌──(kali㉿kali-raspberry-pi)-[~] └─$ dmesg | grep crash [ 0.000000] crashkernel reserved: 0x000000000ac00000 - 0x000000002ac00000 (512 MB) [ 0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=0 snd_bcm2835.enable_headphones=0 snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1 bcm2708_fb.fbwidth=1824 bcm2708_fb.fbheight=984 bcm2708_fb.fbswap=1 smsc95xx.macaddr=E4:5F:01:D3:5B:D9 vc_mem.mem_base=0x3eb00000 vc_mem.mem_size=0x3ff00000 console=ttyS0,115200 console=tty1 root=PARTUUID=59536845-02 rootfstype=ext4 fsck.repair=yes rootwait net.ifnames=0 crashkernel=512M maxcpus=1 Another tip is that kexec did not work on multi-core mode at least on Raspberry Pi 4. Some of the changes that I made on the source code is that I disable the check against the number of running cores so that it can load the image regardless of the number of cores on the system. You can see that the maxcpu is set 1 on the above log from the dmesg. I learned a lot from the process of preparing kexec and I enjoyed it. Kernel crash dump is such an insteresting subject, and I might be digging deeper into it👾.

6/4/2023

Replying to ARP requests by Ryo

Hi, today I wanted to make a short post that I now have a working kernel built-in ARP(reply) stack😎. Although the stack can't yet handle ARP request, my stack is now able to receive packets from local peers! Here are the output showing the windows sending arp request and raspberry pi (my stack!) replying to the request. C:\WINDOWS\system32>arp -a Interface: 192.168.10.2 --- 0x8 Internet Address Physical Address Type 192.168.10.1 fc-99-47-12-26-7a dynamic 192.168.10.255 ff-ff-ff-ff-ff-ff static 224.0.0.22 01-00-5e-00-00-16 static 224.0.0.251 01-00-5e-00-00-fb static 224.0.0.252 01-00-5e-00-00-fc static 239.255.255.250 01-00-5e-7f-ff-fa static Interface: 172.21.176.1 --- 0x2b Internet Address Physical Address Type 172.21.179.85 00-15-5d-4a-0e-39 dynamic 172.21.191.255 ff-ff-ff-ff-ff-ff static 224.0.0.22 01-00-5e-00-00-16 static 224.0.0.251 01-00-5e-00-00-fb static 224.0.0.252 01-00-5e-00-00-fc static 224.0.1.60 01-00-5e-00-01-3c static 239.255.255.250 01-00-5e-7f-ff-fa static C:\WINDOWS\system32>ping 192.168.10.3 Pinging 192.168.10.3 with 32 bytes of data: Request timed out. Ping statistics for 192.168.10.3: Packets: Sent = 1, Received = 0, Lost = 1 (100% loss), Control-C ^C C:\WINDOWS\system32> ┌──(kali㉿kali-raspberry-pi)-[~] └─$ dmesg | grep my_arp_rcv [ 93.757253] my_arp_rcv(): address of skb 00000000f1642941 [ 93.757324] my_arp_rcv(): address of arp header0000000063ca06a6 [ 93.757349] my_arp_rcv(): sender IP address of 34252992 [ 93.757371] my_arp_rcv(): target IP address of 51030208 [ 93.757391] my_arp_rcv(): the arp requsest is for IP protocol [ 93.757430] my_arp_rcv(): found matching ip interface [ 93.757484] my_arp_rcv(): successfully sent an arp response C:\WINDOWS\system32>arp -a Interface: 192.168.10.2 --- 0x8 Internet Address Physical Address Type 192.168.10.1 fc-99-47-12-26-7a dynamic 192.168.10.3 e4-5f-01-d3-5b-d9 dynamic --> here the entry is added, fc-99-47-12-26-7a is the MAC of pi 192.168.10.255 ff-ff-ff-ff-ff-ff static 224.0.0.22 01-00-5e-00-00-16 static 224.0.0.251 01-00-5e-00-00-fb static 224.0.0.252 01-00-5e-00-00-fc static 239.255.255.250 01-00-5e-7f-ff-fa static Interface: 172.21.176.1 --- 0x2b Internet Address Physical Address Type 172.21.179.85 00-15-5d-4a-0e-39 dynamic 172.21.191.255 ff-ff-ff-ff-ff-ff static 224.0.0.22 01-00-5e-00-00-16 static 224.0.0.251 01-00-5e-00-00-fb static 224.0.0.252 01-00-5e-00-00-fc static 224.0.1.60 01-00-5e-00-01-3c static 239.255.255.250 01-00-5e-7f-ff-fa static C:\WINDOWS\system32> I recently started this service called scrapbox.io for keeping all the notes taken while I build my programs. Below is the link to the note while I was doing some debuggings for this arp reply stack. https://scrapbox.io/everydaymemo/arpリプライのデバッグ

5/7/2023

Building my own networking stack by Ryo

Hi! There is this holiday called Golden Week in Japan. It is a week long holiday and I wanted to share this project I was working on for almost 12/7😅. Its about building your own networking stack from device(using TAP) to socket. It is a great project for those who want to understand how OS networking stack works behind the Linux kernel. Below is the github link I was following along the project. https://github.com/pandax381/microps https://github.com/sititou70/klab-protocol-stack-tutorial I've gone through each stack and it really deepened my understanding of how OS handles data arriving to its physical devices and sending all the way up to sockets assigned to each application. I am thinking of sharing some of the key concepts of each stack and how they passes data to each other in the future posts! For today's post, I just wanted to share a modification that I made from the original program regarding the TCP stack. I enabled the TCP stack to be able to establish a active connection to a server on the internet and fetch some random content. Of course, the established connection can't just abandon the connection😏. It has to participate in the process of terminating connection passively. I modified the code to complete the entire procedure of such TCP connection. Below is the log from the local program, the one uses the DIY network stack. 00:18:18.434 [D] tcp_open_rfc793: connection established: local=192.0.2.2:7, foreign=194.195.86.83:8080 (tcp.c:1172) 00:18:18.434 [D] tcp_output_segment: 192.0.2.2:7 => 194.195.86.83:8080, len=100 (payload=80) (tcp.c:417) src: 7 dst: 8080 seq: 1804289384 ack: 3543150099 off: 0x50 (20) flg: 0x18 (---AP---) wnd: 65535 sum: 0x30fe up: 0 00:18:18.434 [D] ip_output_core: dev=net1, iface=192.0.2.2, protocol=TCP(0x06), len=120 (ip.c:477) vhl: 0x45 [v: 4, hl: 5 (20)] tos: 0x00 total: 120 (payload: 100) id: 131 offset: 0x0000 [flags=0, offset=0] ttl: 255 protocol: 6 (TCP) sum: 0xdfe3 (0xdfe3) src: 192.0.2.2 dst: 194.195.86.83 00:18:18.435 [D] arp_resolve: resolved, pa=192.0.2.1, ha=8e:6e:37:e9:d1:92 (arp.c:357) 00:18:18.435 [D] net_device_output: dev=net1, type=IP(0x0800), len=120 (net.c:189) 00:18:18.435 [D] ether_transmit_helper: dev=net1, type=IP(0x0800), len=134 (ether.c:108) src: 00:00:5e:00:53:01 dst: 8e:6e:37:e9:d1:92 type: 0x0800 (IP) Data with the size of 80 was sent. Closing the connection. ... 00:18:18.562 [D] tcp_input: 194.195.86.83:8080 => 192.0.2.2:7, len=67 (payload=47) (tcp.c:996) src: 8080 dst: 7 seq: 3543150099 ack: 1804289464 off: 0x50 (20) flg: 0x18 (---AP---) wnd: 29200 sum: 0xc768 up: 0 +------+-------------------------------------------------+------------------+ | 0000 | 48 54 54 50 2f 31 2e 31 20 34 30 30 20 42 61 64 | HTTP/1.1 400 Bad | | 0010 | 20 52 65 71 75 65 73 74 0d 0a 43 6f 6e 6e 65 63 | Request..Connec | | 0020 | 74 69 6f 6e 3a 20 63 6c 6f 73 65 0d 0a 0d 0a | tion: close.... | +------+-------------------------------------------------+------------------+ 00:18:18.562 [D] tcp_output_segment: 192.0.2.2:7 => 194.195.86.83:8080, len=20 (payload=0) (tcp.c:417) src: 7 dst: 8080 seq: 1804289464 ack: 3543150146 off: 0x50 (20) flg: 0x10 (---A----) wnd: 65488 sum: 0x029d up: 0 ... 00:18:18.565 [D] tcp_input: 194.195.86.83:8080 => 192.0.2.2:7, len=20 (payload=0) (tcp.c:996) src: 8080 dst: 7 seq: 3543150146 ack: 1804289464 off: 0x50 (20) flg: 0x11 (---A---F) wnd: 29200 sum: 0x905c up: 0 00:18:18.565 [D] tcp_output_segment: 192.0.2.2:7 => 194.195.86.83:8080, len=20 (payload=0) (tcp.c:417) src: 7 dst: 8080 seq: 1804289464 ack: 3543150147 off: 0x50 (20) flg: 0x10 (---A----) wnd: 65535 sum: 0x026d up: 0 ... 00:18:18.565 [D] tcp_output_segment: 192.0.2.2:7 => 194.195.86.83:8080, len=20 (payload=0) (tcp.c:417) src: 7 dst: 8080 seq: 1804289464 ack: 3543150147 off: 0x50 (20) flg: 0x11 (---A---F) wnd: 65535 sum: 0x026c up: 0 ... 00:18:18.689 [D] tcp_input: 194.195.86.83:8080 => 192.0.2.2:7, len=20 (payload=0) (tcp.c:996) src: 8080 dst: 7 seq: 3543150147 ack: 1804289465 off: 0x50 (20) flg: 0x10 (---A----) wnd: 29200 sum: 0x905b up: 0 Connection is closed passively. And here is the log from my web server hosting this web site. By comparing the logs, you can see that the TCP 3 way handshake at the beginning actively initiated by the local program of mine. At the end, the server is the one that initiating the termination of the connection as it has finished sending all the data, which in this case is a "400 Bad Request".... I made few modification on the program so that the local program can handle the state transition associated with the active establishment and the passive termination of a connection. root@ryofslife:~# tcpdump src host 180.56.119.152 -vvv ... 15:18:18.426463 IP (tos 0x48, ttl 233, id 129, offset 0, flags [none], proto TCP (6), length 40) p9209152-ipngn9901marunouchi.tokyo.ocn.ne.jp.60320 > ryofslife.com.http-alt: Flags [S], cksum 0xaed7 (correct), seq 1804289383, win 65535, length 0 ... 15:18:18.550721 IP (tos 0x48, ttl 233, id 130, offset 0, flags [none], proto TCP (6), length 40) p9209152-ipngn9901marunouchi.tokyo.ocn.ne.jp.60320 > ryofslife.com.http-alt: Flags [.], cksum 0xad84 (correct), seq 1804289384, ack 3543150099, win 65535, length 0 ... 15:18:18.554528 IP (tos 0x48, ttl 233, id 131, offset 0, flags [none], proto TCP (6), length 120) p9209152-ipngn9901marunouchi.tokyo.ocn.ne.jp.60320 > ryofslife.com.http-alt: Flags [P.], cksum 0xdb95 (correct), seq 0:80, ack 1, win 65535, length 80: HTTP, length: 80 GET / HTTP/1.1 ... 15:18:18.679744 IP (tos 0x48, ttl 233, id 132, offset 0, flags [none], proto TCP (6), length 40) p9209152-ipngn9901marunouchi.tokyo.ocn.ne.jp.60320 > ryofslife.com.http-alt: Flags [.], cksum 0xad34 (correct), seq 80, ack 48, win 65488, length 0 ... 15:18:18.682063 IP (tos 0x48, ttl 233, id 133, offset 0, flags [none], proto TCP (6), length 40) p9209152-ipngn9901marunouchi.tokyo.ocn.ne.jp.60320 > ryofslife.com.http-alt: Flags [.], cksum 0xad04 (correct), seq 80, ack 49, win 65535, length 0 15:18:18.682646 IP (tos 0x48, ttl 233, id 134, offset 0, flags [none], proto TCP (6), length 40) p9209152-ipngn9901marunouchi.tokyo.ocn.ne.jp.60320 > ryofslife.com.http-alt: Flags [F.], cksum 0xad03 (correct), seq 80, ack 49, win 65535, length 0 15:18:18.683615 IP (tos 0x48, ttl 43, id 54157, offset 0, flags [none], proto TCP (6), length 52) I am thinking of sharing the code on my github once done fixing little bits and pieces😎. Anyways, wish you all have a great week! See in the next post!!

4/23/2023

My latest topology by Ryo

Hi! I have been working on my lab and wanted to share its physical and logical topology. I think I made a huge improvement on the diagram compared to the last one from an aesthetic point of view😎. Here is the logical topology. There are networks connected by BGP and I prepared a local network for each one of them. All the three local networks are reachable from each other as they advertise their local network to their peers. Among the three routers, I installed netem to the VyOS so that I can simulate some of the WAN characteristics like latency and packet loss. And here is the physical setup and topology of my lab. I used two L2 switches to connect three routers and to prepare a local network for each of the routers. I recently took a simple benchmark regarding bandwidth and latency using this lab setup. It's great have an environment where you can gets your hands dirty😏. See you in the next post!

4/3/2023

DIY Ethernet Cable! by Ryo

Hi! I've been running out of cables for my lab and I decided to make one by myself from a 15m CAT 6 ethernet cable which I got from my local store for about $10. I had to make 4 attempts to finally get a working cable and here are the mistakes that I made. Hope it helps someone who is trying to do the same thing😅. First attempt, the pin for white/orange wire were not properly attached. It is also not looking good as the cable sheet is too short for the plug😂. Second attempt, I misaligned the blue and white/green wire. Third attempt, I realized that I was configuring the order of the wires upside-down respect to the plug🤣🤣🤣. And here is the final product! Mistakes are proof that you are learning😎. See you in the next post!

4/2/2023

Internet & TOR by Ryo

Hi! I wanted to share that my lab is finally connected to the internet! For the last 6 months ever since I got my first switch and router, my lab never had gotten out of its LAN😅. It's the first time getting out of my LAN and interacting with the internet and I'm just sooo excited about it. The reason I decided to extend my lab to the internet is because I have been looking into technologies used over the internet, TOR in particular. I'm learning how relays used in TOR allows clients to hide their identity over the internet and how it helps people in some countries with strict censorship. I found the technology as well as the role it plays in society very interesting. I believe such technology to ensure people have access to learn what is happening around the world is crucial. Having such tool gives us additional choice in what we choose from the pool of sources and I believe it could make a huge different sometimes. I am learning that there are many ways that I can take part in the community and I'm sure there is something that I can do to help people out there! https://www.torproject.org/ By the way, I noticed that my lab topology is getting pretty messy😂. I'm currently working on BGP and I'll share a nicer topology here once I'm done with all the BGP configurations that I have in my mind. See you in the next post!!!!!

3/21/2023

L2TP by Ryo

Hi! I have been working on l2tp on my lab and I wanted to leave a tip here as it took me about a week to finally make it work. I'm not sure if the problem that I faced is specific to the device that I am using, namely cisco 892 router, but here is the tip for those working on l2tp. When you are setting the interface which is used for tunneling the LAN, the one you apply "xconnect", it has to be a WAN interface! I found this very weird and confusing. Why would you want to use WAN interface for tunneling LAN interface🤣. The below link really saved me as the given answer was exactly the one I needed. Without it, I'm probably still working wondering why ping is not working even though that the tunnel is established and everything seems configured correctly. Cisco892で, "WANポート"を使わなければL2TP接続した両端の機器間でPing疎通できない I also used a lot of Switched Port Analyzer(SPAN) for debugging. It's very useful and fun tool for labbing! Below is the topology of my lab after setting up l2tp. I have been interested in benchmarking my networking devices for a while and I am hoping to make a post about it within a next couple week. Anyways, see you in the next post!

2/19/2023

VyOS by Ryo

Hi! Today, I wanted to share that I installed VyOS on my DELL desktop as I needed additional router for my home lab. I usually install this kind of softwares on Ras Pi but I learned that there is no ARM64 version of VyOS😂. The reason I turned my DELL into VyOS is only because I wanted to try out BGP with physical devices😏. See you in the next post!

2/18/2023

GRE tunneling by Ryo

Hi! Today, I wanted to share about the things that I have learned by tunneling between Ras Pi and a router through GRE. At first, I was trying GRE on packet tracer but it didn't work for some reason. So I decided to instead work on physical devices which were available at the moment. I will share some of key commands for setting up GRE on Ras Pi. For the router, you will find many resources online for setting up GRE on a cisco router😅. ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ip tunnel add gre1 mode gre remote 172.168.10.25 local 192.168.233.204 ttl 255 ┌──(kali㉿kali-raspberry-pi)-[~] └─$ ip tunnel list gre0: gre/ip remote any local any ttl inherit nopmtudisc gre1: gre/ip remote 172.168.10.25 local 192.168.233.204 ttl 255 ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ip addr add 10.10.10.1/24 dev gre1 ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ip link set gre1 up ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ip addr add 192.168.233.204/24 dev eth0 The process of setting up GRE is the same for both Ras Pi and a router, only difference is the commands😎. Once done with the above set up, you have to configure the route for both the physical interface connected to the router and the virtual tunnel interface. Below is the route table. ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ip route default via 192.168.85.77 dev wlan0 proto dhcp src 192.168.85.76 metric 600 10.10.10.0/24 dev gre1 proto kernel scope link src 10.10.10.1 172.168.10.25 dev eth0 scope link 192.168.85.0/24 dev wlan0 proto kernel scope link src 192.168.85.76 metric 600 192.168.233.0/24 dev eth0 proto kernel scope link src 192.168.233.204 Here 10.10.10.0/24 is the network for the tunnel and 172.168.10.25 is the address of the router's physical interface connected to Ras Pi. When I was working on tunneling yesterday, I couldn't figure out why ping was failing after setting up the tunnel. It was the route info that was missing🤣. See you in the next post!

2/13/2023

IPFire on Raspbeery Pi by Ryo

Hi! Today, I wanted to share that I recently turned my raspberry pi into to a firewall to make it part of my home lab. Here are some notes for setting up IPFire on raspberry pi. When I was setting up IPFire, I got stuck for a little while with a rainbow screen when trying to boot it up. 1. Set "hdmi_safe" to 0 which you will find in config.txt. hdmi_safe=0 2. Set "SERIAL-CONSOLE" to OFF which you will find in uENV.txt. SERIAL-CONSOLE=OFF Hope it helps if any one of you encounters the same issue. Firewall is something that I haven't really looked into and excited about adding new component into my home lab and learning what it is capable of!

1/15/2023

EtherChannel and STP by Ryo

Hi! Today, I configured an EtherChannel to see how it affects STP. For the setup, I prepared two switches (Switch1 & Swtich2) and connected them with 2 cables. Below shows how STP is configured on Switch1 before EtherChannel is ready on Switch2. Switch1(config)# Switch1(config)#interface range fastEthernet 0/1-2 Switch1(config-if-range)#channel-group 1 mode active //Swtich1はactiveに設定 Creating a port-channel interface Port-channel 1 Switch1(config-if-range)# Switch1(config-if-range)#channel-protocol LACP Switch1(config-if-range)#exit Switch1(config)#exit Switch1#show 00:11:48: %SYS-5-CONFIG_I: Configured from console by console % Type "show ?" for a list of subcommands Switch1#show etherchannel summary Flags: D - down P - in port-channel I - stand-alone s - suspended H - Hot-standby (LACP only) R - Layer3 S - Layer2 U - in use f - failed to allocate aggregator u - unsuitable for bundling w - waiting to be aggregated d - default port Number of channel-groups in use: 1 Number of aggregators: 1 Group Port-channel Protocol Ports ------+-------------+-----------+----------------------------------------------- 1 Po1(SD) LACP Fa0/1(I) Fa0/2(I) Switch1# Switch1#show spanning-tree VLAN0001 Spanning tree enabled protocol ieee Root ID Priority 32769 Address ec30.918e.c100 This bridge is the root Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Bridge ID Priority 32769 (priority 32768 sys-id-ext 1) Address ec30.918e.c100 Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Aging Time 300 Interface Role Sts Cost Prio.Nbr Type ---------------- ---- --- --------- -------- -------------------------------- Fa0/1 Desg FWD 19 128.1 P2p Fa0/2 Desg FWD 19 128.2 P2p As you can see from the above, since the EtherChannel is still not configured on Switch2, you can see that STP recognizes 2 ports as they are not yet bundled even though the 2 ports are registered on the channel-group 1. Below is how Switch2 is configured after setting up Switch. Switch1# Switch1#show etherchannel summary Flags: D - down P - in port-channel I - stand-alone s - suspended H - Hot-standby (LACP only) R - Layer3 S - Layer2 U - in use f - failed to allocate aggregator u - unsuitable for bundling w - waiting to be aggregated d - default port Number of channel-groups in use: 1 Number of aggregators: 1 Group Port-channel Protocol Ports ------+-------------+-----------+----------------------------------------------- 1 Po1(SU) LACP Fa0/1(P) Fa0/2(P) Switch1#show spanning-tree VLAN0001 Spanning tree enabled protocol ieee Root ID Priority 32769 Address ec30.918e.c100 This bridge is the root Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Bridge ID Priority 32769 (priority 32768 sys-id-ext 1) Address ec30.918e.c100 Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Aging Time 300 Interface Role Sts Cost Prio.Nbr Type ---------------- ---- --- --------- -------- -------------------------------- Po1 Desg FWD 12 128.56 P2p After the ports are bundled, you can see that there are only 1 port recognized by STP. Another observation you can make is that the cost of the bundle port has decreased from 19 to 12. I also tested how STP will behave if I plugged out one of the port used by the channel-group. Switch1#show etherchannel summary Flags: D - down P - in port-channel I - stand-alone s - suspended H - Hot-standby (LACP only) R - Layer3 S - Layer2 U - in use f - failed to allocate aggregator u - unsuitable for bundling w - waiting to be aggregated d - default port Number of channel-groups in use: 1 Number of aggregators: 1 Group Port-channel Protocol Ports ------+-------------+-----------+----------------------------------------------- 1 Po1(SU) LACP Fa0/1(P) Fa0/2(D) Switch1#show spanning-tree VLAN0001 Spanning tree enabled protocol ieee Root ID Priority 32769 Address ec30.918e.c100 This bridge is the root Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Bridge ID Priority 32769 (priority 32768 sys-id-ext 1) Address ec30.918e.c100 Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Aging Time 300 Interface Role Sts Cost Prio.Nbr Type ---------------- ---- --- --------- -------- -------------------------------- Po1 Desg FWD 19 128.56 P2p Comparing before and after plugging one of the port on Switch1 shows that the cost has decreased but it is still recognized as a port-channel.

1/8/2023

Redundant Links and STP by Ryo

Hi! Today, I tested STP with my two switches by simply connecting them with two cables. As shown below, one of the links belonging to the non-root bridge got blocked based on the priority number. pi#show spanning-tree vlan 1 VLAN0001 Spanning tree enabled protocol ieee Root ID Priority 32769 Address ec30.918e.c100 Cost 19 Port 5 (FastEthernet0/3) Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Bridge ID Priority 32769 (priority 32768 sys-id-ext 1) Address f029.2952.8d80 Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Aging Time 300 sec Interface Role Sts Cost Prio.Nbr Type ------------------- ---- --- --------- -------- -------------------------------- Fa0/1 Desg FWD 19 128.3 P2p Fa0/3 Root FWD 19 128.5 P2p Fa0/5 Altn BLK 19 128.7 P2p As the above shows, Fa0/3 is the root port connected to the switch on the other end. So I plugged it out to see if the connection remains up by changing the root port to Fa0/5. Below is the result. pi>show spanning-tree vlan 1 VLAN0001 Spanning tree enabled protocol ieee Root ID Priority 32769 Address ec30.918e.c100 Cost 19 Port 7 (FastEthernet0/5) Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Bridge ID Priority 32769 (priority 32768 sys-id-ext 1) Address f029.2952.8d80 Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec Aging Time 15 sec Interface Role Sts Cost Prio.Nbr Type ------------------- ---- --- --------- -------- -------------------------------- Fa0/1 Desg FWD 19 128.3 P2p Fa0/5 Root LIS 19 128.7 P2p As expected, Fa0/5 is now the root port and the connection is still up! However, one drawback of this configuration is that one of the links is left unused. In order to utilize both of the links, I can set up an etherchannel and bundle the two links. I'm currently studying etherchannel to actually test it out and see how it differs from simply connected redundant links🧐.

1/3/2023

Inter VLAN Routing by Ryo

Hi! Today, I was working on Inter VLAN Routing using a router(800) and L2 switch(Catalyst 2960). I connected a PC to each VLAN(VLAN10, VLAN20) and tested if I can ping to each other. Below is the set up for the PCs(Windows, Raspberry Pi) connected to the switch. The ip address for the Windows PC is 192.168.1.2/24 and the gateway address for 192.168.2.0/24 is 192.168.1.1/24. For Raspberry Pi, its ip address is 192.168.2.2/24 and the gateway address for 192.168.1.0/24 is 192.168.2.1/24. C:\WINDOWS\system32>route add 192.168.2.0 mask 255.255.255.0 192.168.1.1 OK! ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ifconfig eth0 192.168.2.2 ┌──(kali㉿kali-raspberry-pi)-[~] └─$ sudo ip route add 192.168.1.0/255.255.255.0 via 192.168.2.1 dev eth0 onlink ┌──(kali㉿kali-raspberry-pi)-[~] └─$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.164.146 0.0.0.0 UG 600 0 0 wlan0 192.168.1.0 192.168.2.1 255.255.255.0 UG 0 0 0 eth0 192.168.2.0 192.168.2.1 255.255.255.0 UG 0 0 0 eth0 192.168.164.0 0.0.0.0 255.255.255.0 U 600 0 0 wlan0 Then I configured the switch. I prepared vlan10 & vlan20 for the Windows PC & Raspberry Pi, respectively. After finishing setting up vlans, you need to assign ports to the respective vlans. This time, I used 4 cables, two for connecting the PCs to the switch and the other two for connecting the router. Here are the commands I used for creating vlans. Switch>enable Switch#config terminal Enter configuration commands, one per line. End with CNTL/Z. Switch(config)#vlan 10 Switch(config-vlan)#vlan 20 Switch(config-vlan)#do show vlan VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------- 1 default active Fa0/1, Fa0/2, Fa0/3, Fa0/4 Fa0/5, Fa0/6, Fa0/7, Fa0/8 Fa0/9, Fa0/10, Fa0/11, Fa0/12 Fa0/13, Fa0/14, Fa0/15, Fa0/16 Fa0/17, Fa0/18, Fa0/19, Fa0/20 Fa0/21, Fa0/22, Fa0/23, Fa0/24 Gi0/1, Gi0/2 10 VLAN0010 active 20 VLAN0020 active 1002 fddi-default act/unsup 1003 token-ring-default act/unsup 1004 fddinet-default act/unsup 1005 trnet-default act/unsup Next I assigned the ports to the respective vlans. Switch(config)#do show vlan VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------- 1 default active Fa0/1, Fa0/2, Fa0/3, Fa0/4 Fa0/5, Fa0/6, Fa0/7, Fa0/8 Fa0/9, Fa0/10, Fa0/11, Fa0/12 Fa0/13, Fa0/14, Fa0/15, Fa0/16 Fa0/17, Fa0/18, Fa0/19, Fa0/20 Fa0/21, Fa0/22, Fa0/23, Fa0/24 Gi0/1, Gi0/2 10 VLAN0010 active 20 VLAN0020 active 1002 fddi-default act/unsup 1003 token-ring-default act/unsup 1004 fddinet-default act/unsup 1005 trnet-default act/unsup VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ 1 enet 100001 1500 - - - - - 0 0 10 enet 100010 1500 - - - - - 0 0 20 enet 100020 1500 - - - - - 0 0 1002 fddi 101002 1500 - - - - - 0 0 Switch(config)#interface fa0/1 Switch(config-if)# 00:02:41: %CDP-4-NATIVE_VLAN_MISMATCH: Native VLAN mismatch discovered on FastEthernet0/3 (1), with Router FastEthernet0 (10). Switch(config-if)# 00:02:47: %CDP-4-NATIVE_VLAN_MISMATCH: Native VLAN mismatch discovered on FastEthernet0/5 (1), with Router FastEthernet1 (20). Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 10 Switch(config-if)#interface fa0/2 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 20 Switch(config-if)# 00:03:36: %CDP-4-NATIVE_VLAN_MISMATCH: Native VLAN mismatch discovered on FastEthernet0/3 (1), with Router FastEthernet0 (10). Switch(config-if)#interface fa0/3 Switch(config-if)#switchport access vlan 20 00:03:42: %CDP-4-NATIVE_VLAN_MISMATCH: Native VLAN mismatch discovered on FastEthernet0/5 (1), with Router FastEthernet1 (20). Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 10 Switch(config-if)#interface fa0/5 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 20 Switch(config-if)#switchport access vlan 20 00:04:10: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan1, changed state tmode access Switch(config-if)#do show vlan VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------- 1 default active Fa0/4, Fa0/6, Fa0/7, Fa0/8 Fa0/9, Fa0/10, Fa0/11, Fa0/12 Fa0/13, Fa0/14, Fa0/15, Fa0/16 Fa0/17, Fa0/18, Fa0/19, Fa0/20 Fa0/21, Fa0/22, Fa0/23, Fa0/24 Gi0/1, Gi0/2 10 VLAN0010 active Fa0/1, Fa0/3 20 VLAN0020 active Fa0/2, Fa0/5 1002 fddi-default act/unsup 1003 token-ring-default act/unsup 1004 fddinet-default act/unsup 1005 trnet-default act/unsup VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ 1 enet 100001 1500 - - - - - 0 0 10 enet 100010 1500 - - - - - 0 0 20 enet 100020 1500 - - - - - 0 0 1002 fddi 101002 1500 - - - - - 0 0 1003 tr 101003 1500 - - - - - 0 0 After working on the switch, I had to configure the ports on the router each connected to the switch's vlan port. At first, I tried to assign IP address to the ports directly but I got this error. Router#config terminal Enter configuration commands, one per line. End with CNTL/Z. Router(config)#interface fastethernet0 Router(config-if)#ip address 192.168.1.1 255.255.255.0 % IP addresses may not be configured on L2 links. The problem was that the port which I was configuring only works with L2 layer and an IP address can't be assigned. After doing some research, I figured out that I need to first create a vlan so that I can assign an IP address to it. The created vlan with an IP address can then be assigned to a port of your choice. Here is how I did it. Router(config)#vlan 10 Router(config-vlan)#vlan 20 Router(config-vlan)#interface vlan 10 Router(config-if)#ip address 192.168.1.1 255.255.255.0 % 192.168.1.0 overlaps with Vlan1 Router(config-if)#interface vlan 1 Router(config-if)#ip address 192.168.3.1 255.255.255.0 Router(config-if)#interface vlan 10 Router(config-if)#ip address 192.168.1.1 255.255.255.0 Router(config-if)#no shut Router(config-if)#interface vlan 20 Router(config-if)# *Jan 3 09:40:49.434: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan20, changed state to down Router(config-if)#ip address 192.168.2.1 255.255.255.0 % 192.168.2.0 overlaps with Vlan2 Router(config-if)#interface vlan 2 Router(config-if)#ip address 192.168.4.1 255.255.255.0 Router(config-if)#interface vlan 20 Router(config-if)#ip address 192.168.2.1 255.255.255.0 Router(config-if)#no shut Router(config-if)#interface fastethernet 1 Router(config-if)#switchport access vlan 10 Router(config-if)#interface fastethernet 2 Router(config-if)#switchport access vlan 20 Router(config-if)#exit Router(config)# Router(config)#do show interface (| include Vlan) ... Vlan10 is up, line protocol is up Hardware is EtherSVI, address is e4d3.f166.3fd2 (bia e4d3.f166.3fd2) Internet address is 192.168.1.1/24 MTU 1500 bytes, BW 100000 Kbit/sec, DLY 100 usec, reliability 255/255, txload 1/255, rxload 1/255 ... Vlan20 is up, line protocol is up Hardware is EtherSVI, address is e4d3.f166.3fd2 (bia e4d3.f166.3fd2) Internet address is 192.168.2.1/24 MTU 1500 bytes, BW 100000 Kbit/sec, DLY 100 usec, reliability 255/255, txload 1/255, rxload 1/255 ... Below is the routing table after configuring the router. Router>show ip route Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 ia - IS-IS inter area, * - candidate default, U - per-user static route o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP + - replicated route, % - next hop override Gateway of last resort is not set 192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks C 192.168.1.0/24 is directly connected, Vlan10 L 192.168.1.1/32 is directly connected, Vlan10 192.168.2.0/24 is variably subnetted, 2 subnets, 2 masks C 192.168.2.0/24 is directly connected, Vlan20 L 192.168.2.1/32 is directly connected, Vlan20 Now we are ready to ping the PC on the other VLAN connected by the router! Here is the result pinging from the Windows PC(192.168.1.2/24) to Raspberry Pi(192.168.2.2/24) C:\Users\Ryo>ping 192.168.2.2 Pinging 192.168.2.2 with 32 bytes of data: Reply from 192.168.2.2: bytes=32 time=1ms TTL=63 Reply from 192.168.2.2: bytes=32 time=11ms TTL=63 Reply from 192.168.2.2: bytes=32 time=1ms TTL=63 Reply from 192.168.2.2: bytes=32 time=1ms TTL=63 Ping statistics for 192.168.2.2: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 1ms, Maximum = 11ms, Average = 3ms Configuring the router was somewhat difficult as the commands I found online for inter VLAN routing didn't work for the router(800). I had to do some researching to find the commands that works for the router but it was fun as you don't get to do this kind of researching when you are working on packet tracer😎.

1/1/2023

Catalyst 2960 by Ryo

I recently bought a router and 2 switches(L2 and L3) for a studying purpose. Today I tried one of the switches, Catalyst 2960. I connected two of my PC and see if I can ping from one to the other. After connecting two of my PC to the ports Fa0/1-2, I checked if they are really connected. Switch>show mac address-table Mac Address Table ------------------------------------------- Vlan Mac Address Type Ports ---- ----------- -------- ----- All 0100.0ccc.cccc STATIC CPU All 0100.0ccc.cccd STATIC CPU All 0180.c200.0000 STATIC CPU All 0180.c200.0001 STATIC CPU All 0180.c200.0002 STATIC CPU All 0180.c200.0003 STATIC CPU All 0180.c200.0004 STATIC CPU All 0180.c200.0005 STATIC CPU All 0180.c200.0006 STATIC CPU All 0180.c200.0007 STATIC CPU All 0180.c200.0008 STATIC CPU All 0180.c200.0009 STATIC CPU All 0180.c200.000a STATIC CPU All 0180.c200.000b STATIC CPU All 0180.c200.000c STATIC CPU All 0180.c200.000d STATIC CPU All 0180.c200.000e STATIC CPU All 0180.c200.000f STATIC CPU All 0180.c200.0010 STATIC CPU All ffff.ffff.ffff STATIC CPU 1 902e.169d.b2f1 DYNAMIC Fa0/1 1 e45f.01d3.5bd9 DYNAMIC Fa0/2 Total Mac Addresses for this criterion: 22 You can see the mac address table has the mac address of the each device connected to the port(Fa0/1-2). However, I wasn't able to ping from my Windows PC(Fa0/1) to Raspberry-pi(Fa0/2). I checked the ARP table of my Windows PC and it showed the list with the mac address of raspberry pi. C:\>arp -a Interface: 192.168.1.2 --- 0x11 Internet Address Physical Address Type 192.168.1.3 e4-5f-01-d3-5b-d9 dynamic 192.168.1.255 ff-ff-ff-ff-ff-ff static The problem was my Windows PC's firewall😅. After configuring its firewall rules to allow ICMP traffic, I was able to ping! C:\Users\Ryo>ping 192.168.1.3 Pinging 192.168.1.3 with 32 bytes of data: Reply from 192.168.1.3: bytes=32 time=2ms TTL=64 Reply from 192.168.1.3: bytes=32 time=6ms TTL=64 Reply from 192.168.1.3: bytes=32 time=1ms TTL=64 Reply from 192.168.1.3: bytes=32 time<1ms TTL=64 Ping statistics for 192.168.1.3: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 6ms, Average = 2ms

1/1/2023

VLAN(vs subnet) by Ryo

I tried to understand the difference between VLAN and subnet by looking into their ARP broadcast request. First I deleted all the ARP entries on the source PC so that when I ping, there will be an ARP request broadcasted to all the devices connected to the switch. Here is how you can check and delete the ARP table. C:\>arp -a Internet Address Physical Address Type 192.168.2.4 0001.436a.8be5 dynamic C:\>arp -d C:\>arp -a No ARP Entries Found After deleting all the ARP entries, the source PC will send an ARP request as it has no mac address on its table. Here is the list of ports on the switch when an ARP request was sent. It shows an ARP reqeust is sent to all the ports except the one(FastEthernet0/3) which is connected to the source PC. In addition, even though FastEthernet0/1-2 are not within the same subnet(192.168.2.0/24), you can see that they still receive the ARP request sent by the source PC(192.168.2.2/24). 1. FastEthernet0/1 sends out the frame. #192.168.1.2 2. FastEthernet0/2 sends out the frame. #192.168.1.3 3. FastEthernet0/4 sends out the frame. #192.168.2.3 4. FastEthernet0/5 sends out the frame. #192.168.2.4 Now its time see how an ARP request will behave when the switch is divided into VLANs(192.168.1.0/24, 192.168.2.0/24) . I once again deleted all the ARP entries in the table of the source PC and here is the commands I used for creating VLANs. Switch>enable Switch#config terminal Enter configuration commands, one per line. End with CNTL/Z. Switch(config)#int fa0/1 Switch(config-if)#exit Switch(config)#vlan 10 Switch(config-vlan)#vlan 20 Switch(config-vlan)#int fa0/1 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 10 Switch(config-if)#int fa0/2 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 10 Switch(config-if)#int fa0/3 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 20 Switch(config-if)#int fa0/4 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 20 Switch(config-if)#int fa0/5 Switch(config-if)#switchport mode access Switch(config-if)#switchport access vlan 20 Switch(config-if)#do show vlan VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------- 1 default active Fa0/6, Fa0/7, Fa0/8, Fa0/9 Fa0/10, Fa0/11, Fa0/12, Fa0/13 Fa0/14, Fa0/15, Fa0/16, Fa0/17 Fa0/18, Fa0/19, Fa0/20, Fa0/21 Fa0/22, Fa0/23, Fa0/24, Gig0/1 Gig0/2 10 vlan01 active Fa0/1, Fa0/2 20 vlan02 active Fa0/3, Fa0/4, Fa0/5 1002 fddi-default active 1003 token-ring-default active 1004 fddinet-default active 1005 trnet-default active I created VLAN01 and VLAN02 for 192.168.1.0/24 and 192.168.2.0/24, respectively. And here is the list of the ports that received an ARP request sent by the source PC(192.168.2.2/24). It shows that FastEthernet0/1-2 are not receiving an ARP request any more as they no longer belong to the same VLAN as the source PC(VLAN02)! 1. FastEthernet0/4 sends out the frame. #VLAN01 2. FastEthernet0/5 sends out the frame. #VLAN02 Once you are done with the VLANs, you can place the ports back to the default VLAN by the below commands. Switch(config-if-range)#interface range Fa 0/1-5 Switch(config-if-range)#switchport access vlan 1 Switch(config-if-range)#do show vlan VLAN Name Status Ports ---- -------------------------------- --------- ------------------------------- 1 default active Fa0/1, Fa0/2, Fa0/3, Fa0/4 Fa0/5, Fa0/6, Fa0/7, Fa0/8 Fa0/9, Fa0/10, Fa0/11, Fa0/12 Fa0/13, Fa0/14, Fa0/15, Fa0/16 Fa0/17, Fa0/18, Fa0/19, Fa0/20 Fa0/21, Fa0/22, Fa0/23, Fa0/24 Gig0/1, Gig0/2 10 vlan01 active 20 vlan02 active 1002 fddi-default active 1003 token-ring-default active 1004 fddinet-default active 1005 trnet-default active Switch(config-if-range)#no vlan 10 Switch(config-if-range)#no vlan 20

12/30/2022

How does a switch know how to route ping packets? by Ryo

After studying how different devices work at different layers, I got little confused how ping works if its only given ip address to reach the destination pc connected via switch which is a layer 2 device. Here's how it works. 1. We only have the destination's ip and no mac address info. ->ARP request which is broadcasted to all devices connected to the switch. 2. Once your PC has the mac address in its mac address table, the frame is sent to the switch which contains the mac address of the destination pc. 3. Switch needs to know which port is connected to the PC with the destination mac address. ->Flood the frame to all other ports if the destination mac address is not in the mac address table. 4. Once the switch gets the reply form the destination PC, it now knows which port to send the frame to get to the destination PC! Here are ARP and Mac address tables before and after ping. Switch#show mac address-table Mac Address Table ------------------------------------------- Vlan Mac Address Type Ports ---- ----------- -------- ----- Switch#show mac address-table Mac Address Table ------------------------------------------- Vlan Mac Address Type Ports ---- ----------- -------- ----- 1 00e0.8fe3.e0b3 DYNAMIC Fa0/2 1 00e0.f7a1.365d DYNAMIC Fa0/1 C:\>arp -a No ARP Entries Found C:\>arp -a Internet Address Physical Address Type 192.168.1.2 00e0.8fe3.e0b3 dynamic

12/30/2022

Setting up static routes by Ryo

For testing static routes, I created a system with 2 routers each connected to a PC. There are 3 networks so that one PC can connect to the other after setting up a static route. Here I first configured router's interface for 192.168.1.0/24 and 192.168.1.1/24 is the default gateway for 192.168.1.0/24. I did the same for the other router responsible for 192.168.2.0/24. The third network(192.168.3.0/24) which needs to be configured is the one connecting the two routers. Router>enable Router#configure terminal Enter configuration commands, one per line. End with CNTL/Z. Router(config)#interface GigabitEthernet 0/0/0 Router(config-if)#ip address 192.168.1.1 255.255.255.0 Router(config-if)#no shutdown Router(config-if)# %LINK-5-CHANGED: Interface GigabitEthernet0/0/0, changed state to up %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet0/0/0, changed state to up Router(config-if)#do show interfaces GigabitEthernet0/0/0 is up, line protocol is up (connected) Hardware is ISR4331-3x1GE, address is 0001.4384.9c01 (bia 0001.4384.9c01) Internet address is 192.168.1.1/24 ... After setting up all three networks, I pinged form the PC with 192.168.1.2/24. But the result shows that it is still not reachable. C:\>ping 192.168.2.2 Pinging 192.168.2.2 with 32 bytes of data: Reply from 192.168.1.1: Destination host unreachable. Reply from 192.168.1.1: Destination host unreachable. Reply from 192.168.1.1: Destination host unreachable. Reply from 192.168.1.1: Destination host unreachable. Ping statistics for 192.168.2.2: Packets: Sent = 4, Received = 0, Lost = 4 (100% loss), The remaining task is to set up the static routes so that the packet can reach the PC with 192.168.2.2/24. Here is how I set up the static route for 192.168.2.2/24. Router(config)#ip route 192.168.2.0 255.255.255.0 192.168.3.2 After setting up as above, you still won't be able to get replies from the other end as the returning packets get lost at the 192.168.3.2/24. C:\>ping 192.168.2.2 Pinging 192.168.2.2 with 32 bytes of data: Request timed out. Request timed out. Request timed out. Request timed out. Ping statistics for 192.168.2.2: Packets: Sent = 4, Received = 0, Lost = 4 (100% loss), Once I set up the static route as below, I was able to get replies from 192.168.2.2/24! Router(config)#ip route 192.168.1.0 255.255.255.0 192.168.3.1 C:\>ping 192.168.2.2 Pinging 192.168.2.2 with 32 bytes of data: Reply from 192.168.2.2: bytes=32 time<1ms TTL=126 Reply from 192.168.2.2: bytes=32 time=10ms TTL=126 Reply from 192.168.2.2: bytes=32 time<1ms TTL=126 Reply from 192.168.2.2: bytes=32 time=11ms TTL=126 Ping statistics for 192.168.2.2: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 11ms, Average = 5ms

12/30/2022

Going hands-on by Ryo

I have been studying basic networking by reading books for CCNA. At this point, I think I should go hands-on with packet tracer or the router (Cisco 892) and switches (Cisco L2 and L3) I bought this week for studying purpose. Here are the list of the things I want to try hands-on. ・Static route ・OSPF ・ACL ・DHCP ・Unidirection & Bidirectional NAT ・NAPT(PAT) ・VLAN only using access ports (single switch) ・VLAN using access and trunk ports (two switches) ・VLAN rounting (using router and L2 switch, later using L3 switch)

12/25/2022

Trying packet tracer by Ryo

I started using packet tracer and enjoying the tool a lot. I configured hub, switch, and router based network using the tool. It's really fun to put the materials you learned from books into practice! Here are the commands I used for configuring the router and the details of what it's doing. Router>enable Router# Router#configure terminal Enter configuration commands, one per line. End with CNTL/Z. Router(config)#interface GigabitEthernet0/0 #select the port(interface) on the router Router(config-if)#ip address 192.168.1.4 255.255.255.0 #assign gateway IP address to the interface Router(config-if)#no shutdown #bring up the inerface Router(config-if)# %LINK-5-CHANGED: Interface GigabitEthernet0/0, changed state to up Here I tested if I am connected to the network configured above by pinging from a node within another network. C:\>ping 192.168.1.3 Pinging 192.168.1.3 with 32 bytes of data: Request timed out. Reply from 192.168.1.3: bytes=32 time=14ms TTL=127 Reply from 192.168.1.3: bytes=32 time<1ms TTL=127 Reply from 192.168.1.3: bytes=32 time=11ms TTL=127 Ping statistics for 192.168.1.3: Packets: Sent = 4, Received = 3, Lost = 1 (25% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 14ms, Average = 8ms It shows that the first packet is dropped. This is because of the switch on the network configured above does not have not have the destination pc's MAC address in its ARP table and need to get the one by 'flooding' which takes some time.

12/21/2022

ARP by Ryo

"ip addr" shows the mac address for each interface, it's e4:5f:01:d3:5b:da in the case of wlan0. "arp" shows the router's mac address. ┌──(kali㉿kali-raspberry-pi)-[/var/lib/dhcp] └─$ ip addr ... 3: wlan0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether e4:5f:01:d3:5b:da brd ff:ff:ff:ff:ff:ff inet 192.168.164.76/24 brd 192.168.164.255 scope global dynamic noprefixroute wlan0 valid_lft 2858sec preferred_lft 2858sec inet6 fe80::ed36:b7c6:afa8:838d/64 scope link noprefixroute valid_lft forever preferred_lft forever ┌──(kali㉿kali-raspberry-pi)-[/var/lib/dhcp] └─$ arp Address HWtype HWaddress Flags Mask Iface 192.168.164.146 ether ac:a8:8e:ec:6e:66 C wlan0 The first hop of "traceroute", which is 192.168.164.146, shows the router's local ip address. ┌──(kali㉿kali-raspberry-pi)-[~] └─$ traceroute 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets 1 192.168.164.146 (192.168.164.146) 40.242 ms 41.001 ms 43.085 ms 2 121.83.171.60 (121.83.171.60) 74.412 ms 74.476 ms 76.689 ms 3 100.64.3.181 (100.64.3.181) 81.472 ms 81.503 ms 83.573 ms 4 58.191.128.178 (58.191.128.178) 86.298 ms 85.972 ms 86.346 ms 5 61.205.127.233 (61.205.127.233) 86.192 ms 87.454 ms 87.482 ms 6 203.140.81.209 (203.140.81.209) 86.012 ms 48.984 ms 55.241 ms 7 60.56.20.190 (60.56.20.190) 54.917 ms 54.165 ms 62.331 ms 8 142.250.172.36 (142.250.172.36) 62.152 ms 61.755 ms 65.046 ms 9 * * * 10 dns.google (8.8.8.8) 65.708 ms 65.737 ms 65.926 ms After piging to my laptop within the same local network, my laptop's mac address is added to the arp table. But ping is failing for some reason... ┌──(kali㉿kali-raspberry-pi)-[/var/lib/dhcp] └─$ ping 192.168.164.137 PING 192.168.164.137 (192.168.164.137) 56(84) bytes of data. ^C --- 192.168.164.137 ping statistics --- 7 packets transmitted, 0 received, 100% packet loss, time 6143ms ┌──(kali㉿kali-raspberry-pi)-[/var/lib/dhcp] └─$ arp Address HWtype HWaddress Flags Mask Iface 192.168.164.146 ether ac:a8:8e:ec:6e:66 C wlan0 192.168.164.137 ether 50:c2:e8:29:9b:cb C wlan0 Wireshark shows the arp protocol is requesting the mac address of 192.168.164.137, and the response from the router shows the mac address is 50:c2:e8:29:9b:cb. However there is no response from 192.168.164.76. 2 18.664379309 Raspberr_d3:5b:da Broadcast ARP 42 Who has 192.168.164.137? Tell 192.168.164.76 3 18.680115301 CloudNet_29:9b:cb Raspberr_d3:5b:da ARP 42 192.168.164.137 is at 50:c2:e8:29:9b:cb 4 18.680196856 192.168.164.76 192.168.164.137 ICMP 98 Echo (ping) request id=0x0002, seq=1/256, ttl=64 (no response found!) I checked my laptop's firewall configuration and enable ping echo request. Ping is now working! ┌──(kali㉿kali-raspberry-pi)-[~] └─$ ping 192.168.164.137 PING 192.168.164.137 (192.168.164.137) 56(84) bytes of data. 64 bytes from 192.168.164.137: icmp_seq=1 ttl=128 time=53.2 ms 64 bytes from 192.168.164.137: icmp_seq=2 ttl=128 time=75.9 ms 64 bytes from 192.168.164.137: icmp_seq=3 ttl=128 time=8.42 ms 64 bytes from 192.168.164.137: icmp_seq=4 ttl=128 time=42.1 ms 64 bytes from 192.168.164.137: icmp_seq=5 ttl=128 time=8.71 ms ^C --- 192.168.164.137 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4006ms rtt min/avg/max/mdev = 8.417/37.644/75.852/26.122 ms

12/20/2022

Routing protocols by Ryo

I didn't know there are protocols defining the optimal path for exchanging packets between networks. It's interesting how they use different metrics(hop count, bandwidth, etc) to determine the best path.

12/19/2022

CCNA by Ryo

I started studying for CCNA hoping to learn basic networking!

12/16/2022

Compiling kernel 6 by Ryo

Here are the commands I used after finishing compiling the source code. ──(kali㉿kali-raspberry-pi)-[~/sources/linux] └─$ ls arch certs CREDITS Documentation fs init ipc Kconfig lib MAINTAINERS mm modules.builtin.modinfo modules.order net README.md scripts sound tools virt vmlinux.o block COPYING crypto drivers include io_uring Kbuild kernel LICENSES Makefile modules.builtin modules-only.symvers Module.symvers README samples security System.map usr vmlinux vmlinux.symvers ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux] └─$ sudo make modules_install ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux] └─$ sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/ ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux] └─$ sudo cp arch/arm64/boot/dts/overlays/*.dtb* /boot/overlays/ ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux] └─$ sudo cp arch/arm64/boot/dts/overlays/README /boot/overlays/ ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux] └─$ sudo cp arch/arm64/boot/Image.gz /boot/kernel-ryo-1.img ┌──(kali㉿kali-raspberry-pi)-[/boot] └─$ sudo vim config.txt # 64-bit kernel for Raspberry Pi 4 is called kernel8l (armv8a) kernel=kernel-ryo-1.img ┌──(kali㉿kali-raspberry-pi)-[/boot] └─$ sudo reboot And I got this! ┌──(kali㉿kali-raspberry-pi)-[/var/log] └─$ uname -a Linux kali-raspberry-pi 5.15.83-v8-ryos-first-kernel+ #1 SMP PREEMPT Fri Dec 16 12:25:46 UTC 2022 aarch64 GNU/Linux ┌──(kali㉿kali-raspberry-pi)-[/var/log] └─$ cat messages Dec 16 14:43:01 kali-raspberry-pi pulseaudio[968]: ICE I/O error handler called Dec 16 14:43:04 kali-raspberry-pi kernel: [ 0.000000] Hello World, I'm Ryo! Dec 16 14:43:04 kali-raspberry-pi kernel: [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083] Dec 16 14:43:04 kali-raspberry-pi kernel: [ 0.000000] Linux version 5.15.83-v8-ryos-first-kernel+ (kali@kali-raspberry-pi) (gcc (Debian 11.3.0-5) 11.3.0, GNU ld (GNU Binutils for Debian) 2.38.90.20220713) #1 SMP PREEMPT Fri Dec 16 12:25:46 UTC 2022 This time I was able to print during the boot up with my customized kernel! I can now try to do some work on the network stack and compile😁.

12/16/2022

Compiling kernel 5 by Ryo

This time, I modified /arm/arm64/kernel/setup.c as below. You can find the source code here. void __init smp_setup_processor_id(void) { u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; set_cpu_logical_map(0, mpidr); pr_info("Hello World, its Ryo!"); pr_info("Booting Linux on physical CPU 0x%010lx [0x%08x]\n", (unsigned long)mpidr, read_cpuid_id()); } Here is the commands that I used. $ KERNEL=kernel8 $ make bcm2711_defconfig $ vim .config CONFIG_LOCALVERSION="-v8-ryos-first-kernel" $ make -j4 Image.gz modules dtbs

12/15/2022

sk_buff by Ryo

The packet data received by NIC is held by sk_buff(). I'm curious how packets travels from NIC to user space programs.

12/15/2022

Compiling kernel 4 by Ryo

It's completed compiling! Here is what I did afterwards. $ make ... OBJCOPY arch/arm64/boot/Image GZIP arch/arm64/boot/Image.gz [1] + done make $ ls arch certs CREDITS Documentation fs init Kbuild kernel LICENSES Makefile modules.builtin modules-only.symvers Module.symvers README scripts sound tools virt vmlinux.o block COPYING crypto drivers include ipc Kconfig lib MAINTAINERS mm modules.builtin.modinfo modules.order net samples security System.map usr vmlinux vmlinux.symvers $ file vmlinux vmlinux: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=8d74859bebe9cce14587e1b3272c7b11fe5de611, not stripped $ sudo make modules_install INSTALL /lib/modules/5.15.44-Re4son-v8l/kernel/sound/usb/misc/snd-ua101.ko INSTALL /lib/modules/5.15.44-Re4son-v8l/kernel/sound/usb/snd-usb-audio.ko INSTALL /lib/modules/5.15.44-Re4son-v8l/kernel/sound/usb/snd-usbmidi-lib.ko DEPMOD /lib/modules/5.15.44-Re4son-v8l $ sudo make install sh ./arch/arm64/boot/install.sh 5.15.44-Re4son-v8l \ arch/arm64/boot/Image System.map "/boot" run-parts: executing /etc/kernel/postinst.d/initramfs-tools 5.15.44-Re4son-v8l /boot/vmlinuz-5.15.44-Re4son-v8l update-initramfs: Generating /boot/initrd.img-5.15.44-Re4son-v8l cryptsetup: ERROR: Couldn't resolve device /dev/root cryptsetup: WARNING: Couldn't determine root device I'm having trouble installing compiled files. I did some research and boot up process is not what I thought as Rasbarry Pi does not support grub😰. I found the kernel source code for Raspberry Pi here. Another mistake that I found is that I was working on linux/arch/arm. My Raspberry Pi is 64bits machine so the directory should be under linux/arch/arm64. Glad I found this mistake before compilation. I will once again compile the source code and see how it goes😂.

12/15/2022

Nmap SYN scanning by Ryo

Some stuff I learned about how Nmap SYN scanning works. Below is the captured packets from Wireshark. 10 13.006851 192.168.100.103 192.168.100.101 TCP 60 44276 → 445 [SYN] Seq=0 Win=1024 Len=0 MSS=1460 15 13.007423 192.168.100.101 192.168.100.103 TCP 60 445 → 44276 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 16 13.007594 192.168.100.103 192.168.100.101 TCP 60 44276 → 445 [RST] Seq=1 Win=0 Len=0 It shows that the the state of port is open as the server's reply to the nmap's SYN is SYN,ACK. You can observe that SYN scan terminates 3 way handshake by RST sent by nmap. Also, here is the source code I found which I thought might be useful for spoofing Nmap OS detection. You can find the source code here. I think the below code is the part where it specifies the window size of a packet. /* Numbers are taken from RFC3390. * * John Heffner states: * * The RFC specifies a window of no more than 4380 bytes * unless 2*MSS > 4380. Reading the pseudocode in the RFC * is a bit misleading because they use a clamp at 4380 bytes * rather than use a multiplier in the relevant range. */ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) { __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); if (!cwnd) { if (tp->mss_cache > 1460) cwnd = 2; else cwnd = (tp->mss_cache > 1095) ? 3 : 4; } return min_t(__u32, cwnd, tp->snd_cwnd_clamp); }

12/14/2022

Compiling kernel 3 by Ryo

I modified ./arch/arm/kernel/setup.c as below. You can find the source code here. void __init smp_setup_processor_id(void) { int i; u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cpu_logical_map(0) = cpu; for (i = 1; i < nr_cpu_ids; ++i) cpu_logical_map(i) = i == cpu ? 0 : i; /* * clear __my_cpu_offset on boot CPU to avoid hang caused by * using percpu variable early, for example, lockdep will * access percpu variable inside lock_release */ set_my_cpu_offset(0); pr_info("Hello world, this is Ryo speaking!\n"); pr_info("Booting Linux on physical CPU 0x%x\n", mpidr); } After the above modification, I started compiling the source code as below. $ cp /boot/config-$(uname -r) .config $ sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison $ make menuconfig No change to .config *** End of the configuration. *** Execute 'make' to start the build or try 'make help'. $ make This is going to take a while😝.

12/14/2022

Compiling kernel 2 by Ryo

I learned that you can't use printk() during the early stage of the boot up process😅. Here is the output of /var/log/messages. ┌──(kali㉿kali-raspberry-pi)-[/var/log] └─$ cat messages Dec 11 02:00:25 kali-raspberry-pi rsyslogd: [origin software="rsyslogd" swVersion="8.2206.0" x-pid="525" x-info="https://www.rsyslog.com"] rsyslogd was HUPed Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083] Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] Linux version 5.15.44-Re4son-v8l+ (root@kali-raspberry-pi) (gcc (Debian 11.2.0-19) 11.2.0, GNU ld (GNU Binutils for Debian) 2.38) #1 SMP PREEMPT Debian kali-pi (2022-07-03) Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] random: crng init done Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] Machine model: Raspberry Pi 4 Model B Rev 1.5 I once again gone through the source code and found that "Booting Linux on" is printed by pr_info() and Linux version 5.15.44-Re4son-v8l+ is printed by decompressor_printk(). I will go for pr_info() as it comes earlier than decompressor_printk()😝. ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux-5.15.44] └─$ grep -r "Booting" . ./arch/arm/kernel/setup.c: pr_info("Booting Linux on physical CPU 0x%x\n", mpidr); ┌──(kali㉿kali-raspberry-pi)-[~/sources/linux-5.15.44] └─$ grep printk * -r | grep "decompressor_printk" arch/s390/boot/pgm_check_info.c: decompressor_printk("Linux version %s\n", kernel_version);

12/13/2022

Compiling kernel by Ryo

I check my Raspberry Pi kernel version and its 5.15.44. $ uname -r 5.15.44-Re4son-v8l+ I want to printk during the boot up process so I look through the kernel source code where "Booting Linux on..." is printed as shown below. ┌──(kali㉿kali-raspberry-pi)-[/var/log] └─$ cat messages Dec 11 02:00:25 kali-raspberry-pi rsyslogd: [origin software="rsyslogd" swVersion="8.2206.0" x-pid="525" x-info="https://www.rsyslog.com"] rsyslogd was HUPed Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083] Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] Linux version 5.15.44-Re4son-v8l+ (root@kali-raspberry-pi) (gcc (Debian 11.2.0-19) 11.2.0, GNU ld (GNU Binutils for Debian) 2.38) #1 SMP PREEMPT Debian kali-pi (2022-07-03) Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] random: crng init done Dec 11 02:27:19 kali-raspberry-pi kernel: [ 0.000000] Machine model: Raspberry Pi 4 Model B Rev 1.5 Seems like "Booting Linux on..." is printed by pr_info(), not printk(). Not yet sure where the first printk() is... You can find the source code for version 5.15.44 here.

12/12/2022

Inserting kernel modules by Ryo

Today I inserted a kernel module which simply prints "Hello Ryo!" under /var/log/messages. Here is the c program. int init_module(void) { //printk(KERN_INFO "Hello world 1.\n"); printk(KERN_INFO "Hello Ryo!\n"); return 0; } void cleanup_module(void) { //printk(KERN_INFO "Goodbye world 1.\n"); printk(KERN_INFO "Bye Ryo!\n"); } MODULE_LICENSE("GPL"); initi_module() is used to initialize the module and cleanup_module is responsible for shutting down the module. When you are using printk(), you can give eight 8 levels of different logs at the part of "KERN_INFO". Below is the commands I used for initializing and removing the kernel. make -C /lib/modules/`uname -r`/build/ M=${PWD} modules sudo insmod hello_world.ko sudo rmmod hello_world.ko Here is the output of the above operation. Dec 12 14:21:27 kali-raspberry-pi kernel: [ 8233.939103] Hello Ryo! Dec 12 14:22:33 kali-raspberry-pi kernel: [ 8299.742310] Bye Ryo! I will start looking into where I can printk() inside the kernel source code during the boot up process!

12/11/2022

Kernel? by Ryo

I've been working on TUN device for a while and thought I should look into how packets are handled within the kernel. TUN device allows us to handle packets above layer 3. The corresponding entry point within the kernel is ip_rcv() whih can be found here. ip_local_deliver_finish() is the function whichis the exit of the layer 3 responsible for passing data to the layer 4 stack based on the protocol found in the ip header. You can find the function https://elixir.bootlin.com/linux/v2.6.20/source/net/ipv4/ip_input.c#L199. After ip_local_deliver_finish(), the data is sent to the function handling layer 4 protocol such as tcp_v4_rcv(), udp_rcv(), icmp_rcv(). Might be fun to customize your own network stack and make a kernel of your own😝.

12/11/2022

Analyzing packets by Ryo

I am getting used to reading the hexs shown in Wireshark. Here is the summary of what is going with the below packet sent by my TUN program. 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0x89, 0x4b, 0x40, 0x00, 0x40, 0x01, 0x39, 0x59, 0xcb, 0x00, 0x71, 0x02, 0xcb, 0x00, 0x71, 0x01, 0x08, 0x00, 0x2a, 0xc7, 0x00, 0x19, 0x00, 0x07, 0xc8, 0xb6, 0x8c, 0x63, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x2b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 The first 4 bit (4 of 0x45) ・Version: the fist field tells us which IP version we are using, only IPv4 uses this header so you will always find decimal value 4 here. The first 4 bit (5 of 0x45) ・The length of the ip header. In the case of this example, 5=>5*4(bytes)=>20(bytes)=>20 pair(0x45)s, as each hex is 4 bits. ・Because of the maximum possible value f=>15, the maximum ip header length is 15*4byte=60byte. Protocol: 0x01 ・1 stands for ICMP, 6 stands for tcp, 17 stands for UDP Source and destination address: 0xcb, 0x00, 0x71, 0x02, 0xcb, 0x00, 0x71, 0x01 ・In decimal, 203.0.113.2 and 203.0.113.1 respectively.

12/8/2022

Sending packets with TUN device by Ryo

Below is the c program for sending receiving packets using TUN device. You should comment out either the dump_packet() or send_packet(). Otherwise, the program will be sending and receiving packets of its own. void dump_packet(int fd, int count, char* buffer) { printf("the fd is %d. read %d bytes!\n", fd, count); int i; for (i=0; i IFNAMSIZ) { return 1; } // Request a TUN device: int fd = open("/dev/net/tun", O_RDWR); if (fd == -1) { return 1; } struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; strncpy(ifr.ifr_name, device_name, IFNAMSIZ); int res = ioctl(fd, TUNSETIFF, &ifr); if (res == -1) { return 1; } printf("hello world\n"); //char buffer[BUFFLEN]; char *dumpbuffer = (char *) calloc(300, sizeof(char)); //char *sendbuffer = (char *) calloc(300, sizeof(char)); while (1) { ssize_t count = read(fd, dumpbuffer, 100); if (count < 0) return 1; dump_packet(fd, count, dumpbuffer); send_packet(fd); } return 0; } Wireshark shows the packet are exchanged as below. It's working! 1 0.000000000 203.0.113.2 203.0.113.1 ICMP 86 Echo (ping) request id=0x0019, seq=7/1792, ttl=64 (reply in 2) 2 0.000082333 203.0.113.1 203.0.113.2 ICMP 84 Echo (ping) reply id=0x0019, seq=7/1792, ttl=64 (request in 1)

12/7/2022

Nmap OS spoofing? 2 by Ryo

Below is the database file which Nmap uses as a reference to packet info specific to OS. It is at /usr/share/nmap/nmap-os-db in the case of Ubuntu 20.04.4 LTS. # Linux 2.6.30-ARCH #1 SMP PREEMPT Wed Sep 9 12:37:32 UTC 2009 i686 AMD Athlon(tm) XP 2000+ AuthenticAMD GNU/Linux Fingerprint Linux 2.6.30 Class Linux | Linux | 2.6.X | general purpose CPE cpe:/o:linux:linux_kernel:2.6.30 SEQ(SP=C1-CB%GCD=1-6%ISR=C5-CF%TI=Z%II=I%TS=U) OPS(O1=M5B4NNSNW6%O2=M5B4NNSNW6%O3=M5B4NW6%O4=M5B4NNSNW6%O5=M5B4NNSNW6%O6=M5B4NNS) WIN(W1=16D0%W2=16D0%W3=16D0%W4=16D0%W5=16D0%W6=16D0) ECN(R=Y%DF=Y%T=3B-45%TG=40%W=16D0%O=M5B4NNSNW6%CC=N%Q=) T1(R=Y%DF=Y%T=3B-45%TG=40%S=O%A=S+%F=AS%RD=0%Q=) T2(R=N) T3(R=Y%DF=Y%T=3B-45%TG=40%W=16D0%S=O%A=S+%F=AS%O=M5B4NNSNW6%RD=0%Q=) T4(R=N) T5(R=Y%DF=Y%T=3B-45%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) T6(R=N) T7(R=Y%DF=Y%T=3B-45%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) U1(DF=N%T=3B-45%TG=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G) IE(DFI=N%T=3B-45%TG=40%CD=S) The Nmap source code can be found here.

12/6/2022

Nmap OS spoofing? by Ryo

I'm curious how Nmap OS detection works. Project like below is something that I am interested! https://nmap.org/misc/defeat-nmap-osdetect.html

12/5/2022

Receiving packets using TUN devoce by Ryo

I added the below code to the previous post to receive ICMP packets. char *buffer = (char *) calloc(150, sizeof(char)); ssize_t count = read(fd, buffer, 100); Below is how read() can be used. The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor, fildes, into the buffer pointed to by buf. In the absence of errors, or if error detection is not performed, the read() function shall return zero and have no other results. reference Below is the received packet in hex. 00 00 08 00 45 00 00 54 89 4b 40 00 40 01 39 59 cb 00 71 01 cb 00 71 02 08 00 2a c7 00 19 00 07 c8 b6 8c 63 00 00 00 00 af 2b 0a 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 The above shows that the source address is "cb 00 71 01->203.0.113.1" and the destination address is "cb 00 71 02->203.0.113.290". I'll try to send packets next time! I'm curious simply switching the source and destination address will be enough to send back the packet?

12/4/2022

Creating TUN device by Ryo

I created a TUN interface with the below c program. int main(int argc, char** argv) { if (argc != 2) return 1; const char* device_name = argv[1]; if (strlen(device_name) + 1 > IFNAMSIZ) { return 1; } int fd = open("/dev/net/tun", O_RDWR); if (fd == -1) { return 1; } struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; strncpy(ifr.ifr_name, device_name, IFNAMSIZ); int res = ioctl(fd, TUNSETIFF, &ifr); if (res == -1) { return 1; } printf("the created device is only available during this program\n"); while (1) { } return 0; } The important part in the above code is below. You can provide the name of the interface to "ifr.ifr_name" and spcify whether you want the interface to be TUN or TAP with "ifr.ifr_flags". int fd = open("/dev/net/tun", O_RDWR); int res = ioctl(fd, TUNSETIFF, &ifr); There is another way of creating TUN device using ip command which is shown below. $ sudo ip tuntap add dev tun0 mode tun My next attempt is to receive and read packets using read() and send(). I also want to see how packets are being exchanged using Wireshark.

11/27/2022

TUN/TAP? by Ryo

Maybe TUN/TAP is a good place to start understanding how low-level networking works?

11/23/2022

Device driver? by Ryo

You can check the file descriptor and associated device files with the below command. $ lsof cat 307 ryo 1w REG 8, 32 0 106248 /home/ryo/ctf/kernel/file1.txt Above shows that device files have major and minor numbers to identify the associated device drivers. You can see that 8, 32 are the major and minor number in the above case. You can check which device number has 8, 32 by the below command. /dev$ ls -la brw------- 1 root root 8, 32 Nov 23 11:51 sdc Maybe I should start looking into device drivers used for networking?

11/22/2022

Observing packets with Wireshark by Ryo

I used Wireshark to observe how packets are exchanged between client and server. Packets are sent by client form some random port. Packets are received by the server with the specified port by the running program. Client socket program written in python import socket # AF_INET refers to ipv4 # SOCK_STREAM refers to TCP protocol clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 3 way handshake(SYN) as socket.SOCK_STREAM is the selected type # clientSocket.connect(('127.0.0.1', 12345)) clientSocket.connect(('192.168.50.130', 1234)) dataFromServer = clientSocket.recv(1024) print(dataFromServer.decode()) Server socket program written in python import socket s = socket.socket() port = 12345 s.bind(('', port)) s.listen(5) while True: # 3 way handshake(ACK) as socket.SOCK_STREAM is the selected type clientSocket, addr = s.accept() print(addr) clientSocket.send('Thank you for connecting'.encode()) clientSocket.close() break Packets form Wireshark 1 0.000000000 127.0.0.1 127.0.0.1 TCP 74 44070 → 1234 [SYN] Seq=0 Win=65495 Len=0 MSS=65495 SACK_PERM=1 TSval=4210716831 TSecr=0 WS=128 2 0.000113299 127.0.0.1 127.0.0.1 TCP 74 1234 → 44070 [SYN, ACK] Seq=0 Ack=1 Win=65483 Len=0 MSS=65495 SACK_PERM=1 TSval=4210716831 TSecr=4210716831 WS=128

11/20/2022

Socket Basics by Ryo

Some stuff I learned about socket programming ・client socket socket.socket, socket.connect ・server socket socket.connect, socket.bind, socket.listen, socket.accept Client socket sends SYN with socket.connect and server socket sends ACK with socket.accept. Server socket create client-like(temporary) socket for every incoming client socket.