static void dump_pagetable(unsigned long asce, unsigned long address) { unsigned long *table = __va(asce & _ASCE_ORIGIN); pr_alert("AS:%016lx ", asce); switch (asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: table += (address & _REGION1_INDEX) >> _REGION1_SHIFT; if (bad_address(table)) goto bad; pr_cont("R1:%016lx ", *table); if (*table & _REGION_ENTRY_INVALID) goto out; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_REGION2: table += (address & _REGION2_INDEX) >> _REGION2_SHIFT; if (bad_address(table)) goto bad; pr_cont("R2:%016lx ", *table); if (*table & _REGION_ENTRY_INVALID) goto out; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_REGION3: table += (address & _REGION3_INDEX) >> _REGION3_SHIFT; if (bad_address(table)) goto bad; pr_cont("R3:%016lx ", *table); if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE)) goto out; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_SEGMENT: table += (address & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; if (bad_address(table)) goto bad; pr_cont("S:%016lx ", *table); if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE)) goto out; table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); } table += (address & _PAGE_INDEX) >> _PAGE_SHIFT; if (bad_address(table)) goto bad; pr_cont("P:%016lx ", *table); out: pr_cont("\n"); return; bad: pr_cont("BAD\n"); }
void ip_address::parse(const std::string& s) { if( inet_pton(AF_INET, s.c_str(), &addr) == 1 ) { af = addr_family::ipv4; return; } if( inet_pton(AF_INET6, s.c_str(), &addr) == 1 ) { af = addr_family::ipv6; return; } throw bad_address("Invalid address: " + s); }
ip_address::ip_address(const struct sockaddr* ifa_addr) { if( ifa_addr->sa_family == AF_INET ) { af = addr_family::ipv4; const struct sockaddr_in* p = (const struct sockaddr_in*)ifa_addr; std::memcpy(&addr, &(p->sin_addr), sizeof(struct in_addr)); return; } if( ifa_addr->sa_family == AF_INET6 ) { af = addr_family::ipv6; const struct sockaddr_in6* p = (const struct sockaddr_in6*)ifa_addr; std::memcpy(&addr, &(p->sin6_addr), sizeof(struct in6_addr)); return; } throw bad_address("Invalid address family"); }
/* * map any virtual address of the current process to its * physical one. */ static unsigned long long any_v2p(unsigned long long vaddr) { pgd_t *pgd = pgd_offset(current->mm, vaddr); #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) p4d_t *p4d; #endif pud_t *pud; pmd_t *pmd; pte_t *pte; /* to lock the page */ struct page *pg; unsigned long long paddr; if (bad_address(pgd)) { printk(KERN_ALERT "[nskk] Alert: bad address of pgd %p\n", pgd); goto bad; } if (!pgd_present(*pgd)) { printk(KERN_ALERT "[nskk] Alert: pgd not present %lu\n", *pgd); goto out; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) p4d = p4d_offset(pgd, vaddr); if (p4d_none(*p4d)) return 0; pud = pud_offset(p4d, vaddr); #else pud = pud_offset(pgd, vaddr); #endif if (bad_address(pud)) { printk(KERN_ALERT "[nskk] Alert: bad address of pud %p\n", pud); goto bad; } if (!pud_present(*pud) || pud_large(*pud)) { printk(KERN_ALERT "[nskk] Alert: pud not present %lu\n", *pud); goto out; } pmd = pmd_offset(pud, vaddr); if (bad_address(pmd)) { printk(KERN_ALERT "[nskk] Alert: bad address of pmd %p\n", pmd); goto bad; } if (!pmd_present(*pmd) || pmd_large(*pmd)) { printk(KERN_ALERT "[nskk] Alert: pmd not present %lu\n", *pmd); goto out; } pte = pte_offset_kernel(pmd, vaddr); if (bad_address(pte)) { printk(KERN_ALERT "[nskk] Alert: bad address of pte %p\n", pte); goto bad; } if (!pte_present(*pte)) { printk(KERN_ALERT "[nskk] Alert: pte not present %lu\n", *pte); goto out; } pg = pte_page(*pte); #if 1 paddr = (pte_val(*pte) & PHYSICAL_PAGE_MASK) | (vaddr&(PAGE_SIZE-1)); #else pte->pte |= _PAGE_RW; // | _PAGE_USER; paddr = pte_val(*pte); #endif out: return paddr; bad: printk(KERN_ALERT "[nskk] Alert: Bad address\n"); return 0; }