Annotation of XNU/osfmk/kdp/kdp_udp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1993 NeXT Computer, Inc.  All rights reserved.
                     24:  *
                     25:  * kdp_udp.c -- Kernel Debugging Protocol UDP implementation.
                     26:  *
                     27:  */
                     28: 
                     29: #include <mach_kdb.h>
                     30: #include <mach/boolean.h>
                     31: #include <mach/exception_types.h>
                     32: #include <mach/mach_types.h>
                     33: #include <kern/debug.h>
                     34: 
                     35: #include <kdp/kdp_internal.h>
                     36: #include <kdp/kdp_en_debugger.h>
                     37: #include <kdp/kdp_udp.h>
                     38: 
                     39: #define DO_ALIGN       1       /* align all packet data accesses */
                     40: 
                     41: extern int kdp_getc(void);
                     42: 
                     43: static
                     44: u_short ip_id;                          /* ip packet ctr, for ids */
                     45: 
                     46: /*     @(#)udp_usrreq.c        2.2 88/05/23 4.0NFSSRC SMI;     from UCB 7.1 6/5/86     */
                     47: 
                     48: /*
                     49:  * UDP protocol implementation.
                     50:  * Per RFC 768, August, 1980.
                     51:  */
                     52: #define UDP_TTL        60 /* deflt time to live for UDP packets */
                     53: int            udp_ttl=UDP_TTL;
                     54: static unsigned char   exception_seq;
                     55: 
                     56: static struct {
                     57:     unsigned char      data[KDP_MAXPACKET];
                     58:     unsigned int       off, len;
                     59:     boolean_t          input;
                     60: } pkt, saved_reply;
                     61: 
                     62: struct {
                     63:     struct {
                     64:        struct in_addr          in;
                     65:        struct ether_addr       ea;
                     66:     } loc;
                     67:     struct {
                     68:        struct in_addr          in;
                     69:        struct ether_addr       ea;
                     70:     } rmt;
                     71: } adr;
                     72: 
                     73: static char
                     74: *exception_message[] = {
                     75:     "Unknown",
                     76:     "Memory access",           /* EXC_BAD_ACCESS */
                     77:     "Failed instruction",      /* EXC_BAD_INSTRUCTION */
                     78:     "Arithmetic",              /* EXC_ARITHMETIC */
                     79:     "Emulation",               /* EXC_EMULATION */
                     80:     "Software",                        /* EXC_SOFTWARE */
                     81:     "Breakpoint"               /* EXC_BREAKPOINT */
                     82: };
                     83: 
                     84: static kdp_send_t kdp_en_send_pkt = 0;
                     85: static kdp_receive_t kdp_en_recv_pkt = 0;
                     86: 
                     87: static void kdp_handler( void  *);
                     88: 
                     89: void
                     90: kdp_register_send_receive(kdp_send_t send, kdp_receive_t receive)
                     91: {
                     92: #define        KDP_READY       0x1
                     93: 
                     94:        kdp_en_send_pkt = send;
                     95:        kdp_en_recv_pkt = receive;
                     96:        kdp_flag |= KDP_READY;
                     97:        if (current_debugger == NO_CUR_DB)
                     98:                current_debugger = KDP_CUR_DB;
                     99:        if (halt_in_debugger) {
                    100:                kdp_call(); 
                    101:                halt_in_debugger=0;
                    102:        }
                    103: }
                    104: 
                    105: static 
                    106: void
                    107: enaddr_copy(
                    108:     void       *src,
                    109:     void       *dst
                    110: )
                    111: {
                    112:     bcopy((char *)src, (char *)dst, sizeof (struct ether_addr));
                    113: }
                    114: 
                    115: static 
                    116: unsigned short
                    117: ip_sum(
                    118:     unsigned char      *c,
                    119:     unsigned int       hlen
                    120: )
                    121: {
                    122:     unsigned int       high, low, sum;
                    123:     
                    124:     high = low = 0;
                    125:     while (hlen-- > 0) {
                    126:        low += c[1] + c[3];
                    127:        high += c[0] + c[2];
                    128:        
                    129:        c += sizeof (int);
                    130:     }
                    131:     
                    132:     sum = (high << 8) + low;
                    133:     sum = (sum >> 16) + (sum & 65535);
                    134:     
                    135:     return (sum > 65535 ? sum - 65535 : sum);
                    136: }
                    137: 
                    138: static
                    139: void
                    140: kdp_reply(
                    141:     unsigned short             reply_port
                    142: )
                    143: {
                    144:     struct udpiphdr            aligned_ui, *ui = &aligned_ui;
                    145:     struct ip                  aligned_ip, *ip = &aligned_ip;
                    146:     struct in_addr             tmp_ipaddr;
                    147:     struct ether_addr          tmp_enaddr;
                    148:     struct ether_header                *eh;
                    149:     
                    150:     if (!pkt.input)
                    151:        kdp_panic("kdp_reply");
                    152:        
                    153:     pkt.off -= sizeof (struct udpiphdr);
                    154: 
                    155: #if DO_ALIGN    
                    156:     bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
                    157: #else
                    158:     ui = (struct udpiphdr *)&pkt.data[pkt.off];
                    159: #endif
                    160:     ui->ui_next = ui->ui_prev = 0;
                    161:     ui->ui_x1 = 0;
                    162:     ui->ui_pr = IPPROTO_UDP;
                    163:     ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
                    164:     tmp_ipaddr = ui->ui_src;
                    165:     ui->ui_src = ui->ui_dst;
                    166:     ui->ui_dst = tmp_ipaddr;
                    167:     ui->ui_sport = htons(KDP_REMOTE_PORT);
                    168:     ui->ui_dport = reply_port;
                    169:     ui->ui_ulen = ui->ui_len;
                    170:     ui->ui_sum = 0;
                    171: #if DO_ALIGN
                    172:     bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
                    173:     
                    174:     bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
                    175: #else
                    176:     ip = (struct ip *)&pkt.data[pkt.off];
                    177: #endif
                    178:     ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
                    179:     ip->ip_v = IPVERSION;
                    180:     ip->ip_id = htons(ip_id++);
                    181:     ip->ip_hl = sizeof (struct ip) >> 2;
                    182:     ip->ip_ttl = udp_ttl;
                    183:     ip->ip_sum = 0;
                    184:     ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
                    185: #if DO_ALIGN
                    186:     bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
                    187: #endif
                    188:     
                    189:     pkt.len += sizeof (struct udpiphdr);
                    190:     
                    191:     pkt.off -= sizeof (struct ether_header);
                    192:     
                    193:     eh = (struct ether_header *)&pkt.data[pkt.off];
                    194:     enaddr_copy(eh->ether_shost, &tmp_enaddr);
                    195:     enaddr_copy(eh->ether_dhost, eh->ether_shost);
                    196:     enaddr_copy(&tmp_enaddr, eh->ether_dhost);
                    197:     eh->ether_type = htons(ETHERTYPE_IP);
                    198:     
                    199:     pkt.len += sizeof (struct ether_header);
                    200:     
                    201:     // save reply for possible retransmission
                    202:     bcopy((char *)&pkt, (char *)&saved_reply, sizeof(pkt));
                    203: 
                    204:     (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
                    205: 
                    206:     // increment expected sequence number
                    207:     exception_seq++;
                    208: }
                    209: 
                    210: static
                    211: void
                    212: kdp_send(
                    213:     unsigned short             remote_port
                    214: )
                    215: {
                    216:     struct udpiphdr            aligned_ui, *ui = &aligned_ui;
                    217:     struct ip                  aligned_ip, *ip = &aligned_ip;
                    218:     struct ether_header                *eh;
                    219:     
                    220:     if (pkt.input)
                    221:        kdp_panic("kdp_send");
                    222: 
                    223:     pkt.off -= sizeof (struct udpiphdr);
                    224: 
                    225: #if DO_ALIGN
                    226:     bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
                    227: #else
                    228:     ui = (struct udpiphdr *)&pkt.data[pkt.off];
                    229: #endif
                    230:     ui->ui_next = ui->ui_prev = 0;
                    231:     ui->ui_x1 = 0;
                    232:     ui->ui_pr = IPPROTO_UDP;
                    233:     ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
                    234:     ui->ui_src = adr.loc.in;
                    235:     ui->ui_dst = adr.rmt.in;
                    236:     ui->ui_sport = htons(KDP_REMOTE_PORT);
                    237:     ui->ui_dport = remote_port;
                    238:     ui->ui_ulen = ui->ui_len;
                    239:     ui->ui_sum = 0;
                    240: #if DO_ALIGN
                    241:     bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
                    242:     bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
                    243: #else
                    244:     ip = (struct ip *)&pkt.data[pkt.off];
                    245: #endif
                    246:     ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
                    247:     ip->ip_v = IPVERSION;
                    248:     ip->ip_id = htons(ip_id++);
                    249:     ip->ip_hl = sizeof (struct ip) >> 2;
                    250:     ip->ip_ttl = udp_ttl;
                    251:     ip->ip_sum = 0;
                    252:     ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
                    253: #if DO_ALIGN
                    254:     bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
                    255: #endif
                    256:     
                    257:     pkt.len += sizeof (struct udpiphdr);
                    258:     
                    259:     pkt.off -= sizeof (struct ether_header);
                    260:     
                    261:     eh = (struct ether_header *)&pkt.data[pkt.off];
                    262:     enaddr_copy(&adr.loc.ea, eh->ether_shost);
                    263:     enaddr_copy(&adr.rmt.ea, eh->ether_dhost);
                    264:     eh->ether_type = htons(ETHERTYPE_IP);
                    265:     
                    266:     pkt.len += sizeof (struct ether_header);
                    267:     
                    268:     (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
                    269: }
                    270: 
                    271: static
                    272: void
                    273: kdp_poll(
                    274:     void
                    275: )
                    276: {
                    277:     struct ether_header                *eh;
                    278:     struct udpiphdr            aligned_ui, *ui = &aligned_ui;
                    279:     struct ip                  aligned_ip, *ip = &aligned_ip;
                    280:     static int                 msg_printed;
                    281: 
                    282:     if (pkt.input)
                    283:        kdp_panic("kdp_poll");
                    284:  
                    285:     if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
                    286:        if( msg_printed == 0) {
                    287:            msg_printed = 1;
                    288:             printf("kdp_poll: no debugger device\n");
                    289:        }
                    290:        return;
                    291:     }
                    292: 
                    293:     pkt.off = 0;
                    294:     (*kdp_en_recv_pkt)(pkt.data, &pkt.len, 3/* ms */);
                    295: 
                    296:     if (pkt.len == 0)
                    297:        return;
                    298:     
                    299:     if (pkt.len < (sizeof (struct ether_header) + sizeof (struct udpiphdr)))
                    300:        return;
                    301:        
                    302:     eh = (struct ether_header *)&pkt.data[pkt.off];
                    303:     pkt.off += sizeof (struct ether_header);
                    304:     if (ntohs(eh->ether_type) != ETHERTYPE_IP) {
                    305:        return;
                    306:     }
                    307: 
                    308: #if DO_ALIGN
                    309:     bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
                    310:     bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
                    311: #else
                    312:     ui = (struct udpiphdr *)&pkt.data[pkt.off];
                    313:     ip = (struct ip *)&pkt.data[pkt.off];
                    314: #endif
                    315: 
                    316:     pkt.off += sizeof (struct udpiphdr);
                    317:     if (ui->ui_pr != IPPROTO_UDP) {
                    318:        return;
                    319:     }
                    320:  
                    321:     if (ip->ip_hl > (sizeof (struct ip) >> 2)) {
                    322:        return;
                    323:     }
                    324: 
                    325:     if (ntohs(ui->ui_dport) != KDP_REMOTE_PORT) {
                    326:        return;
                    327:     }
                    328:        
                    329:     if (!kdp.is_conn) {
                    330:        enaddr_copy(eh->ether_dhost, &adr.loc.ea);
                    331:        adr.loc.in = ui->ui_dst;
                    332: 
                    333:        enaddr_copy(eh->ether_shost, &adr.rmt.ea);
                    334:        adr.rmt.in = ui->ui_src;
                    335:     }
                    336: 
                    337:     /*
                    338:      * Calculate kdp packet length.
                    339:      */
                    340:     pkt.len = ntohs((u_short)ui->ui_ulen) - sizeof (struct udphdr);
                    341:     pkt.input = TRUE;
                    342: 
                    343: }
                    344: 
                    345: static
                    346: void
                    347: kdp_handler(
                    348:     void                       *saved_state
                    349: )
                    350: {
                    351:     unsigned short             reply_port;
                    352:     kdp_hdr_t                  aligned_hdr, *hdr = &aligned_hdr;
                    353: 
                    354: 
                    355:     kdp.saved_state = saved_state;  // see comment in kdp_raise_exception
                    356: 
                    357:     do {
                    358:        while (!pkt.input)
                    359:            kdp_poll();
                    360:                        
                    361: #if DO_ALIGN
                    362:        bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
                    363: #else
                    364:        hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
                    365: #endif
                    366: 
                    367:        // ignore replies -- we're not expecting them anyway.
                    368:        if (hdr->is_reply) {
                    369:            goto again;
                    370:        }
                    371:        
                    372:        // check for retransmitted request
                    373:        if (hdr->seq == (exception_seq - 1)) {
                    374:            /* retransmit last reply */
                    375:            (*kdp_en_send_pkt)(&saved_reply.data[saved_reply.off],
                    376:                            saved_reply.len);
                    377:            goto again;
                    378:        } else if (hdr->seq != exception_seq) {
                    379:            printf("kdp: bad sequence %d (want %d)\n",
                    380:                        hdr->seq, exception_seq);
                    381:            goto again;
                    382:        }
                    383:        
                    384:        if (kdp_packet((unsigned char*)&pkt.data[pkt.off], 
                    385:                        (int *)&pkt.len, 
                    386:                        (unsigned short *)&reply_port)) {
                    387:            kdp_reply(reply_port);
                    388:        }
                    389: 
                    390: again:
                    391:        pkt.input = FALSE;
                    392:     } while (kdp.is_halted);
                    393: }
                    394: 
                    395: static
                    396: void
                    397: kdp_connection_wait(
                    398:     void
                    399: )
                    400: {
                    401:     unsigned short     reply_port;
                    402:     boolean_t kdp_call_kdb();
                    403: 
                    404:     printf("\nWaiting for remote debugger connection.\n");
                    405: #ifdef MACH_PE
                    406:     if( 0 != kdp_getc())
                    407: #endif
                    408:     {
                    409:         printf("Options.....    Type\n");
                    410:         printf("------------    ----\n");
                    411:         printf("continue....    'c'\n");
                    412:         printf("reboot......    'r'\n");
                    413: #if MACH_KDB
                    414:         printf("enter kdb...    'k'\n");
                    415: #endif
                    416:     }
                    417: 
                    418:     exception_seq = 0;
                    419:     do {
                    420:        kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
                    421:        
                    422:        while (!pkt.input) {
                    423:            int c;
                    424:            c = kdp_getc();
                    425:            switch(c) {
                    426:                case 'c':
                    427:                    printf("Continuing...\n");
                    428:                    return;
                    429:                case 'r':
                    430:                    printf("Rebooting...\n");
                    431:                    kdp_reboot();
                    432:                    break;
                    433: #if MACH_KDB
                    434:                case 'k':
                    435:                    printf("calling kdb...\n");
                    436:                    if (kdp_call_kdb())
                    437:                        return;
                    438:                    else
                    439:                        printf("not implemented...\n");
                    440: #endif
                    441:                default:
                    442:                    break;
                    443:            }
                    444:            kdp_poll();
                    445:        }
                    446: 
                    447:        // check for sequence number of 0
                    448: #if DO_ALIGN
                    449:        bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
                    450: #else
                    451:        hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
                    452: #endif
                    453:        if (hdr->request == KDP_HOSTREBOOT) {
                    454:                kdp_reboot();
                    455:                /* should not return! */
                    456:        }
                    457:        if ((hdr->request == KDP_CONNECT) &&
                    458:                !hdr->is_reply && (hdr->seq == exception_seq)) {
                    459:            if (kdp_packet((unsigned char *)&pkt.data[pkt.off], 
                    460:                        (int *)&pkt.len, 
                    461:                        (unsigned short *)&reply_port))
                    462:                kdp_reply(reply_port);
                    463:          }
                    464:            
                    465:        pkt.input = FALSE;
                    466:     } while (!kdp.is_conn);
                    467:     
                    468:     if (current_debugger == KDP_CUR_DB)
                    469:        active_debugger=1;
                    470:     printf("Connected to remote debugger.\n");
                    471: }
                    472: 
                    473: static
                    474: void
                    475: kdp_send_exception(
                    476:     unsigned int               exception,
                    477:     unsigned int               code,
                    478:     unsigned int               subcode
                    479: )
                    480: {
                    481:     unsigned short             remote_port;
                    482:     unsigned int               timeout_count;
                    483: 
                    484:     timeout_count = 300;       // should be about 30 seconds
                    485:     do {
                    486:        pkt.off = sizeof (struct ether_header) + sizeof (struct udpiphdr);
                    487:        kdp_exception((unsigned char *)&pkt.data[pkt.off], 
                    488:                        (int *)&pkt.len, 
                    489:                        (unsigned short *)&remote_port,
                    490:                        (unsigned int)exception, 
                    491:                        (unsigned int)code, 
                    492:                        (unsigned int)subcode);
                    493:     
                    494:        kdp_send(remote_port);
                    495:     
                    496: again:
                    497:        kdp_poll();
                    498:        
                    499:        if (pkt.input) {
                    500:            if (!kdp_exception_ack(&pkt.data[pkt.off], pkt.len)) {
                    501:                pkt.input = FALSE;
                    502:                goto again; 
                    503:            }
                    504:        } else {
                    505:                pkt.input = FALSE;
                    506:                goto again;
                    507:        }
                    508:        pkt.input = FALSE;
                    509:        if (kdp.exception_ack_needed)
                    510:            kdp_us_spin(100000);        // 1/10 sec
                    511: 
                    512:     } while (kdp.exception_ack_needed && timeout_count--);
                    513:     
                    514:     if (kdp.exception_ack_needed) {
                    515:        // give up & disconnect
                    516:        printf("kdp: exception ack timeout\n");
                    517:        kdp_reset();
                    518:     }
                    519: }
                    520: 
                    521: void
                    522: kdp_raise_exception(
                    523:     unsigned int               exception,
                    524:     unsigned int               code,
                    525:     unsigned int               subcode,
                    526:     void                       *saved_state
                    527: )
                    528: {
                    529:     int                        s; 
                    530:     int                        index;
                    531: 
                    532:     if (saved_state == 0) 
                    533:        printf("kdp_raise_exception with NULL state\n");
                    534: 
                    535:     index = exception;
                    536:     if (exception != EXC_BREAKPOINT) {
                    537:        if (exception > EXC_BREAKPOINT || exception < EXC_BAD_ACCESS) {
                    538:            index = 0;
                    539:        }
                    540:        printf("%s exception (%x,%x,%x)\n",
                    541:                exception_message[index],
                    542:                exception, code, subcode);
                    543:     }
                    544: 
                    545:     kdp_sync_cache();
                    546: 
                    547:     /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
                    548:      * do this. I think the client and the host can get out of sync.
                    549:      */
                    550:     kdp.saved_state = saved_state;
                    551: 
                    552:     if (pkt.input)
                    553:        kdp_panic("kdp_raise_exception");
                    554: 
                    555:     if (!kdp.is_conn)
                    556:        kdp_connection_wait();
                    557:     else
                    558:        kdp_send_exception(exception, code, subcode);
                    559: 
                    560:     if (kdp.is_conn) {
                    561:        kdp.is_halted = TRUE;           /* XXX */
                    562:        kdp_handler(saved_state);
                    563:        if (!kdp.is_conn)
                    564:            printf("Remote debugger disconnected.\n");
                    565:     }
                    566: 
                    567:     kdp_sync_cache();
                    568: }
                    569: 
                    570: void
                    571: kdp_reset(void)
                    572: {
                    573:     kdp.reply_port = kdp.exception_port = 0;
                    574:     kdp.is_halted = kdp.is_conn = FALSE;
                    575:     kdp.exception_seq = kdp.conn_seq = 0;
                    576: }
                    577: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.