본문 바로가기

리눅스 커널

(42)
nvme_reset_work 흐름 nvme_reset_work(struct work_struct * work) from nvme_probe ->struct nvme_dev * dev = container_of(work, struct nvme_dev, ctrl.reset_work); ->nvme_pci_configure_admin_queues(dev); ->nvmeq = dev->queues[0]; ->nvmeq = nvme_alloc_queue(...); ->nvmeq = kzalloc_node(sizeof(*nvmeq), GFP_KERNEL, node); ->nvmeq->cqes = dma_zalloc_coherent(...); ->dev->queues[qid] = nvmeq; ->dev->ctrl.queue_count++; ->nvm..
nvme 자료구조 관계 struct nvme_dev queus -> struct nvme_queue * -> [nvme_queue][nvme_queue]...[nvme_queue] tagset - struct blk_mq_tag_set : io를 위한 tag를 관리 admin_tagset - struct blk_mq_tag_set : admin을 위한 tag를 관리 online_queues : 활성화된 큐 개수 max_qid : queues 배열의 마지막 인덱스 q_depth : nvme_queue 하나가 처리할 수 있는 최대 io request 개수 ctrl - struct nvme_ctrl : nvme controller struct nvme_queue dev -> struct nvme_dev q_lock : spinloc..
NVMe 디바이스 드라이버 초기화 흐름 NVMe Device Driver init flow, kernel version 4.13.10 from drivers/nvme/host/pci.c static struct pci_driver nvme_driver = { .name= "nvme", .id_table= nvme_id_table, .probe= nvme_probe, .remove= nvme_remove, .shutdown= nvme_shutdown, .driver= { .pm= &nvme_dev_pm_ops, }, .sriov_configure = nvme_pci_sriov_configure, .err_handler= &nvme_err_handler, }; static int __init nvme_init(void) { return pci_r..
Wireless packet capture IEEE802.11 패킷을 캡쳐하기 위해선 먼저 PC가 무선랜을 지원해야 한다. 그리고 이 때 해당 인터페이스의 이름이 wlan0임을 가정하고 정리하겠다. 1. Aircrack-ng 툴 사용 [1] #airmon-ng start wlan0 [2] #airodump-ng wlan0mon [1] 실행 후 iwconfig를 실행하면 인터페이스 이름이 wlan0 -> wlan0mon 으로 바뀌어 있을 것이다. 또한 인터페이스의 모드가 Managed -> Monitor 로 바뀌어 있을 것이다. 무선 패킷 캡쳐를 위해 가장 먼저 해야할 일이 인터페이스 모드를 Monitor모드로 바꾸는 것이다. [2] 실행 후에는 주위에 모든 무선 패킷을 볼 수 있다. [3] CTRL-C [4] #airmon-ng stop wlan..
TCP Handshake 1. 3-way handshaking 주로 초기 연결 시 사용되는 메커니즘이다. ----------------------------------------------------------------------------------------------------- (1) Client------(SEQ: 1000)------>Server 클라이언트가 서버로 SYN: 1이 설정된 TCP 패킷을 보내어 연결 요청을 함 ------------------------------------------------------------------------------------------------------ (2) ClientServer 클라이언트가 서버로 ACK: 1이 설정된 TCP패킷을 보내어 해당 패킷을 잘 받았음..
Check Sum Layer 4 네트워크에서 패킷 전송 후 수신함에 있어 비트 에러 감지를 위해 체크섬을 사용한다. 체크섬의 계산 과정은 다음과 같다. 패킷을 2바이트 단위로 접근 하여 그 값을 더해 나가는데, Carry가 발생하면 이 값을 다시 더해 나가는 것이다. 이 후 마지막 2바이트에 대해서도 계산을 마무리 하면 1의 보수를 취하면 된다. 이를 코드로 구현하면 다음과 같다. unsigned short cksum(unsigned char * buff, int len) { unsigned short * buf = (unsigned short *)buff; unsigned int sum = 0; for (; len > 0; len -= 2) { if (len == 1) sum += (unsigned short)(*(unsigned c..
netlink example #include #include #include #include #include #include #include #include #define BUFSIZE 8192 struct gw_info { uint32_t ip; unsigned char mac[ETH_ALEN]; }; int send_req(int sock, char *buf, size_t nlseq, size_t req_type) { struct nlmsghdr *nlmsg; memset(buf, 0, BUFSIZE); //init nlmsg = (struct nlmsghdr *)(buf); nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); //struct rtmsg nlmsg->nlmsg_typ..
promiscuous mode #include #include #include #include #include #include #include #include "pktfilter.c" int main(void) { int sock; unsigned char buf[65536]; struct packet_mreq pm; sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock < 0) { perror("socket error"); return -1; } memset(&pm, 0, sizeof(pm)); pm.mr_ifindex = 2; //normally, 1: lo, 2: ens33(or eth0) pm.mr_type = PACKET_MR_PROMISC; if (setsockop..
DHCP DHCP packet format Message type(1) [1: request, 2: reply] HW type(1) [1: Ethernet] HW address length(1) [6: Ethernet] Hops(1) Transaction ID(4) Seconds elapsed(2) Bootp flags(2) Client IP address(4) Your(client) IP address(4) Next server IP address(4) Relay agnet IP address(4) Client MAC address(6) Client HW address padding(10) empty(128) Magic cookie(4) option, opcode 53 : DHCP message type(3) ..
Kernel handler packet capture #include #include #include #include #include static struct packet_type pt; static int proto_handler(struct sk_buff * skb, struct net_device * dev1, struct packet_type * pktype, struct net_device * dev2) { struct ethhdr * eth = eth_hdr(skb); struct iphdr * ip = ip_hdr(skb); printk("%pM -> %pM\n", eth->h_source, eth->h_dest); printk("%pI4 -> %pI4\n", &ip->saddr, &ip->daddr); return NF_ACCEPT; } in..