/*------------------------------------------------------------------------ * mkarp - allocate and fill in an ARP or RARP packet *------------------------------------------------------------------------ */ static struct ep * mkarp(int ifn, short type, short op, IPaddr spa, IPaddr tpa) { register struct arp *parp; struct ep *pep; pep = (struct ep *) getbuf(Net.netpool); if ((int)pep == SYSERR) return (struct ep *)SYSERR; memcpy(pep->ep_dst, nif[ifn].ni_hwb.ha_addr, EP_ALEN); pep->ep_order = ~0; pep->ep_type = type; parp = (struct arp *)pep->ep_data; parp->ar_hwtype = hs2net(AR_HARDWARE); parp->ar_prtype = hs2net(EPT_IP); parp->ar_hwlen = EP_ALEN; parp->ar_prlen = IP_ALEN; parp->ar_op = hs2net(op); memcpy(SHA(parp), nif[ifn].ni_hwa.ha_addr, EP_ALEN); memcpy(SPA(parp), &spa, IP_ALEN); memcpy(THA(parp), nif[ifn].ni_hwa.ha_addr, EP_ALEN); memcpy(TPA(parp), &tpa, IP_ALEN); return pep; }
void arp_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { const struct arp_pkthdr *ap; u_short pro, hrd, op, linkaddr; ap = (const struct arp_pkthdr *)bp; ND_TCHECK(*ap); hrd = HRD(ap); pro = PRO(ap); op = OP(ap); /* if its ATM then call the ATM ARP printer for Frame-relay ARP most of the fields are similar to Ethernet so overload the Ethernet Printer and set the linkaddr type for linkaddr_string() accordingly */ switch(hrd) { case ARPHRD_ATM2225: atmarp_print(ndo, bp, length, caplen); return; case ARPHRD_FRELAY: linkaddr = LINKADDR_FRELAY; break; default: linkaddr = LINKADDR_ETHER; break; } if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) { ND_PRINT((ndo, "[|ARP]")); ND_DEFAULTPRINT((const u_char *)ap, length); return; } if (!ndo->ndo_eflag) { ND_PRINT((ndo, "ARP, ")); } /* print hardware type/len and proto type/len */ if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || PROTO_LEN(ap) != 4 || HRD_LEN(ap) == 0 || ndo->ndo_vflag) { ND_PRINT((ndo, "%s (len %u), %s (len %u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), HRD_LEN(ap), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), PROTO_LEN(ap))); /* don't know know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ printf("%s%s ", ndo->ndo_vflag ? ", " : "", tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap)))); if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0) ND_PRINT((ndo, " (%s)", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)))); ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap)))); break; case ARPOP_REPLY: ND_PRINT((ndo, "%s is-at %s", ipaddr_string(SPA(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_REVREQUEST: ND_PRINT((ndo, "who-is %s tell %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_REVREPLY: ND_PRINT((ndo, "%s at %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), ipaddr_string(TPA(ap)))); break; case ARPOP_INVREQUEST: ND_PRINT((ndo, "who-is %s tell %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_INVREPLY: ND_PRINT((ndo,"%s at %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), ipaddr_string(TPA(ap)))); break; default: ND_DEFAULTPRINT((const u_char *)ap, caplen); return; } out: ND_PRINT((ndo, ", length %u", length)); return; trunc: ND_PRINT((ndo, "[|ARP]")); }
void arp_print(register const u_char *bp, u_int length, u_int caplen) { register const struct ether_arp *ap; register const struct ether_header *eh; register u_short pro, hrd, op; ap = (struct ether_arp *)bp; if ((u_char *)(ap + 1) > snapend) { printf("[|arp]"); return; } if (length < sizeof(struct ether_arp)) { (void)printf("truncated-arp"); default_print((u_char *)ap, length); return; } pro = EXTRACT_16BITS(&ap->arp_pro); hrd = EXTRACT_16BITS(&ap->arp_hrd); op = EXTRACT_16BITS(&ap->arp_op); if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || ap->arp_hln != sizeof(SHA(ap)) || ap->arp_pln != sizeof(SPA(ap))) { (void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)", op, pro, ap->arp_pln, hrd, ap->arp_hln); return; } if (pro == ETHERTYPE_TRAIL) (void)printf("trailer-"); eh = (struct ether_header *)packetp; switch (op) { case ARPOP_REQUEST: (void)printf("arp who-has %s", ipaddr_string(TPA(ap))); if (memcmp((char *)ezero, (char *)THA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(THA(ap))); (void)printf(" tell %s", ipaddr_string(SPA(ap))); if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(SHA(ap))); break; case ARPOP_REPLY: (void)printf("arp reply %s", ipaddr_string(SPA(ap))); if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(SHA(ap))); (void)printf(" is-at %s", etheraddr_string(SHA(ap))); if (memcmp((char *)EDST(eh), (char *)THA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(THA(ap))); break; case REVARP_REQUEST: (void)printf("rarp who-is %s tell %s", etheraddr_string(THA(ap)), etheraddr_string(SHA(ap))); break; case REVARP_REPLY: (void)printf("rarp reply %s at %s", etheraddr_string(THA(ap)), ipaddr_string(TPA(ap))); break; default: (void)printf("arp-#%d", op); default_print((u_char *)ap, caplen); return; } if (hrd != ARPHRD_ETHER) printf(" hardware #%d", hrd); }
/* If no request is currently being processed and there's new requests in the queue, process the first one. This can be called from an interrupt or the normal kernel context. */ void do_request(blkreq_t *req) { fd_dev_t *dev; u_long track, sect, cyl, head, big_sect, sects; u_long flags; int i; save_flags(flags); /* This label is used to eliminate tail-recursion. */ top: cli(); if(current_req != NULL) { if(req != NULL) append_node(&fd_reqs, &req->node); load_flags(flags); return; } for(i = 0; i < 2; i++) { if(fd_devs[i].recalibrate) { fdc_recal(&fd_devs[i]); if(req != NULL) append_node(&fd_reqs, &req->node); load_flags(flags); return; } } if(req == NULL) { if(!list_empty_p(&fd_reqs)) { req = (blkreq_t *)fd_reqs.head; remove_node(&req->node); } else { load_flags(flags); return; } } current_req = req; #if 0 req->retries = 0; #endif load_flags(flags); dev = REQ_FD_DEV(req); DB(("fd:do_request: req=%p drive=%d block=%d nblocks=%d cmd=%d buf=%p\n", req, dev->drvno, req->block, req->nblocks, req->command, req->buf)); switch(req->command) { case FD_CMD_SEEK: /* We wanna MOVE DA HEAD! */ /* Do da seek. */ if(fdc_seek(dev, req->block) == FALSE) { handle_error("FD_CMD_SEEK, seek"); goto top; break; } /* Then Sense Interrupt Status */ if(fdc_sense() == FALSE) { handle_error("FD_CMD_SEEK, fdc_sense"); goto top; break; } /* and now we have to Read the ID */ if(fdc_read_id(dev) == FALSE) { handle_error("FD_CMD_SEEK, read_id"); goto top; break; } fd_end_request(0); req = NULL; goto top; case FD_CMD_TIMER: fd_end_request(0); req = NULL; goto top; } if(req->block >= dev->total_blocks) { kprintf("fd: Device %s (%p) doesn't have a block %d!\n", dev->name, dev, req->block); fd_end_request(-1); req = NULL; goto top; } big_sect = req->block; sects = req->nblocks; track = big_sect / dev->disk_p->sectors; sect = big_sect % dev->disk_p->sectors + 1; head = track % dev->disk_p->heads; cyl = track / dev->disk_p->heads; DB(("fd:do_request: cyl=%d sect=%d head=%d sects=%d\n", cyl, sect, head, sects)); switch(req->command) { case FD_CMD_READ: /* We wanna READ the floppy! */ #if 0 fd_end_request(0); req = NULL; goto top; #endif /* We need to seek to the right cylinder. */ if(fdc_seek(dev, cyl) == FALSE) { handle_error("FD_CMD_READ, seek"); goto top; break; } /* Then Sense Interrupt Status */ if(fdc_sense() == FALSE) { handle_error("FD_CMD_READ, fdc_sense"); goto top; break; } /* and now we have to Read the ID */ if(fdc_read_id(dev) == FALSE) { handle_error("FD_CMD_READ, read_id"); goto top; break; } #define TPA(XX) ((u_long)TO_PHYSICAL(XX)) /* Tell the DMA what to do, and hope for the best! */ /* Should move this inside fdc, in fdc_read() i think */ DMAbuf.Buffer = track_buf; DMAbuf.Page = (u_int8)((TPA(track_buf) >> 16) & 0xff); DMAbuf.Offset = (u_int16)(TPA(track_buf) & 0xffff); DMAbuf.Len = (u_int16)(dev->disk_p->sectors * dev->disk_p->heads * FD_SECTSIZ) - 1; DMAbuf.Chan = FLOPPY_DMA; kernel->setup_dma(&DMAbuf, DMA_READ); /* Now we issue a read command. */ if(fdc_read(dev, cyl) == FALSE) { handle_error("FD_CMD_READ, read"); goto top; break; } break; case FD_CMD_WRITE: /* We wanna WRITE it too! */ fd_end_request(0); req = NULL; goto top; default: kprintf("fd:do_request: Unknown command in fd_req, %d\n", req->command); fd_end_request(-1); req = NULL; goto top; } }