ecn kg 発表

Download ECN KG  発表

Post on 08-Jan-2016

60 views

Category:

Documents

1 download

Embed Size (px)

DESCRIPTION

ECN KG 発表. カーネルをハックしてみよう. ネットワークスタックをいぢる. FreeBSD のカーネルコードに printf をいれて処理を追ってみる 今日のターゲットは ICMP です!. まずは QEMU を手に入れよう. 既に QEMU をダウンロードしてありますよね? http://www.ht.sfc.keio.ac.jp/~sada/etc/qemu-0.7.zip 下記媒体でも配布します。 CD-R SD カード コンパクトフラッシュ QEMU を手に入れたら、ローカルの好きな場所においてください. FreeBSD@QEMU の起動. - PowerPoint PPT Presentation

TRANSCRIPT

  • ECN KG

  • FreeBSDprintfICMP

  • QEMUQEMUhttp://www.ht.sfc.keio.ac.jp/~sada/etc/qemu-0.7.zipCD-RSDQEMU

  • FreeBSD@QEMU qemu-freebsd.batrootIPdhclient ed0port 22qemu-freebsd.batportQEMU 10.0.2.2FreeBSD 10.0.2.16

  • /usrsrcsysi386kernnetnetinetsysufsvmX86TCP/IPUnix

  • ICMP Echo Request, Reply ip_output()applicationether_output()arpresolve()rip_input()applicationip_input()ether_input()icmp_input()

  • ICMP ECHO RequestICMP Echo Request ping ip_output()IPether_output()arpresolve()arp

  • printfprintf#define DBG(fmt, arg...) printf("%s: "fmt "\n", __FUNCTION__, ## arg)

    ip_outputsys/netinet/ip_output.c

  • ip_output()(IP)ip_output(){ip = mtod(m, struct ip *); if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { ip->ip_v = IPVERSION; ip->ip_hl = hlen >> 2; ip->ip_id = ip_newid(); ipstat.ips_localout++; } else { hlen = ip->ip_hl
  • ip_output()()ip_output(){ dst = (struct sockaddr_in *)&ro->ro_dst;again: if (ip->ip_src.s_addr == INADDR_ANY) { /* Interface may have no addresses. */ if (ia != NULL) { ip->ip_src = IA_SIN(ia)->sin_addr; } }

  • ip_output()()ip_output(){ error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, ro->ro_rt); goto done; }}IP

  • IP headerip_vip_hltosip_tosip_lenip_idip_offTTLip_ttlip_pip_sumIPip_srcIPip_dst

  • 32bit#define IP_ADDR_FORMAT(addr)\ ((addr) & 0xff), \ (((addr) >> 8) & 0xff), \ (((addr) >> 16) & 0xff), \ (((addr) >> 24) & 0xff)

    DBG(ip_src %d.%d.%d.%d ip_dst %d.%d.%d.%d",IP_ADDR_FORMAT(ip->ip_src.s_addr), IP_ADDR_FORMAT(ip->ip_dst.s_addr));

  • cd /usr/src/sys/i386/compile/ECNmake kernelmake kernel-installmake clean make shutdown -r now

  • Pingdhclient ed0ping 10.0.2.2dmesg

  • splip_outputsplnet(), splx()FreeBSDsplnet(), splimp()splimpsplnetsplimp

  • spl

    spl0splsoftclocksplnetsplttyI/OsplbioI/OsplimpI/Osplclocksplhighsplx(x)

  • ether_output()sys/net/if_ethersubr.c

  • ether_output(ARP)intether_output(){ case AF_INET: error = arpresolve(ifp, rt0, m, dst, edst); if (error) return (error == EWOULDBLOCK ? 0 : error);type = htons(ETHERTYPE_IP); break;

    ARParpresolvARPether_output

  • ether_output()intether_output(){ M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); if (m == NULL) senderr(ENOBUFS); eh = mtod(m, struct ether_header *); (void)memcpy(&eh->ether_type, &type, sizeof(eh->ether_type)); (void)memcpy(eh->ether_dhost, edst, sizeof (edst));

    M_PREPENDIPETHER

    ICMPIPICMPIPeth

  • ether_output_frame()intether_output_frame(){ IFQ_HANDOFF(ifp, m, error); return (error);}

    printf

  • Ether Headerstruct ether_header{u_char ether_dhost[6]; u_char ether_shost[6]; u_short ether_type;}IPv4type0x0800

  • MACdefine

    voidmac_print(u_char *macaddr){ int n;printf("mac = ["); for (n=0; n

  • arpresolveether_output()ARPARPARP2arpresolveARParprequestarprequestARP

  • arpresolve(ARP)sys/netinet/if_ether.cintarpresolve(){ rt = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0);. if ((rt->rt_expire == 0 || rt->rt_expire > time_second) && sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {

    arplookupARPARP

  • arpresolve(ARP)intarpresolve(){ if (rt->rt_expire) { rt->rt_flags &= ~RTF_REJECT; if (la->la_asked == 0 || rt->rt_expire != time_second) { rt->rt_expire = time_second; if (la->la_asked++ < arp_maxtries) { struct in_addr sin = SIN(rt->rt_ifa->ifa_addr)->sin_addr;

    RT_UNLOCK(rt); arprequest(ifp, &sin, &SIN(dst)->sin_addr, IF_LLADDR(ifp));

    ARPARPARParprequest()

  • arprequest(ARP)static void arprequest(){ if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) return;ARPmbuf ah->ar_pro = htons(ETHERTYPE_IP); ah->ar_hln = ifp->if_addrlen; ah->ar_pln = sizeof(struct in_addr);

    (*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);

  • ARP()if_ether.h struct arphdr { u_short ar_hrd; HW u_char ar_hln; u_char ar_pln; u_short ar_op; ARP};

    struct ether_arp { struct arphdr ea_hdr; ARPu_char arp_sha[ETHER_ADDR_LEN]; MAC u_char arp_spa[4]; u_char arp_tha[ETHER_ADDR_LEN]; MAC u_char arp_tpa[4]; };

    ether_arparphdr

  • IPMACARP

  • cd /usr/src/sys/i386/compile/ECNmake kernelmake kernel-installmake clean make shutdown -r now

  • dmesg

  • ICMP ECHO ReplyICMP Echo Reply ping ether_input()etherip_input()IPicmp_input()ICMP

  • ether_input()sys/net/if_ethersubr.c static voidether_input(){ eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); ether_demux(ifp, m);} ether_demuxether

  • ether_demux()voidether_demux(){ m_adj(m, ETHER_HDR_LEN);ether switch (ether_type) { case ETHERTYPE_IP: if (ip_fastforward(m)) return; isr = NETISR_IP; break; netisr_dispatch(isr, m); return;ether_type

  • ip_input(IP)schednetisrsys/netinet/ip_input.cvoidip_input(){ ip = mtod(m, struct ip *); if (ip->ip_v != IPVERSION) { ipstat.ips_badvers++; goto bad; }IP

  • ip_input() voidip_input(){if (hlen > sizeof (struct ip) && ip_dooptions(m, 0)) return;IP LIST_FOREACH(ia, INADDR_HASH(ip->ip_dst.s_addr), ia_hash) {if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr && (!checkif || ia->ia_ifp == m->m_pkthdr.rcvif))

  • ip_input() voidip_input(){ if (ip->ip_off & (IP_MF | IP_OFFMASK)) { m = ip_reass(m); (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); return;

  • icmp_input(ICMP)sys/netinet/ip_icmp.cvoidicmp_input(){ ip = mtod(m, struct ip *); m->m_len -= hlen; m->m_data += hlen; icp = mtod(m, struct icmp *);

    if (in_cksum(m, icmplen)) {

    mbuficmpICMP ICMPIP

  • icmp_input(raw input)voidicmp_input(){ code = icp->icmp_code; switch (icp->icmp_type) {. case ICMP_ECHOREPLY: default: break; }raw: rip_input(m, off); return;

  • cd /usr/src/sys/i386/compile/ECNmake kernelmake kernel-installmake clean make shutdown -r now

  • pingICMP ECHO Request replyarp requestreply

    (e.g.AA)

    mtodmbufFlagsp218IP_FORWARDINGTypeM_PREPENDIP14IFQ_HANDOFF:if_var.h SIN:struct sockaddr_in sockaddr_dl Link-levelsockaddrnet/if_dl.h Ip_fastforward:Netisr_dispatchIP_MF: 10IP_OFFMASK8