/*------------------------------------------------------------------------- * mon_bootp_request - *------------------------------------------------------------------------- */ int mon_bootp_request(int secs) { struct bootp_msg bppacket; struct ep *pep; struct ip *pip; struct udp *pup; pep = (struct ep *)getbuf(mon_bufpool); if (pep == 0) { #ifdef PRINTERR kprintf("bootp_request: !! no buffer\n"); #endif return SYSERR; } pip = (struct ip *)pep->ep_data; pup = (struct udp *)pip->ip_data; make_bootp_packet(&bppacket, secs); /* set the BOOTP data */ blkcopy(pup->u_data, &bppacket, BOOTP_SIZE); /* now set the UDP header info */ pup->u_src = hs2net(BOOTP_CPORT); pup->u_dst = hs2net(BOOTP_SPORT); pup->u_len = hs2net(U_HLEN + BOOTP_SIZE); pup->u_cksum = 0; /* now set the IP header info */ pip->ip_proto = IPT_UDP; pip->ip_verlen = (IP_VERSION<<4) | IP_MINHLEN; pip->ip_tos = 0; pip->ip_len = hs2net(IPMHLEN + U_HLEN + BOOTP_SIZE); pip->ip_id = 0; pip->ip_fragoff = 0; pip->ip_ttl = IP_TTL; pip->ip_src = 0; pip->ip_dst = mon_ip_maskall; pip->ip_cksum = 0; pip->ip_cksum = mon_cksum(pip, IPMHLEN); /* now set the ethernet info */ blkcopy(pep->ep_eh.eh_dst, EP_BRC, EP_ALEN); pep->ep_eh.eh_type = EPT_IP; return((mon_nif[0].ni_write)(pep, EP_HLEN+U_HLEN+IPMHLEN+BOOTP_SIZE)); }
int arpfind(IPaddr faddr) { int i; int arindex; struct arpent *atabptr; for (arindex=0; arindex<Arp.atabsiz; arindex++) { atabptr = &Arp.arptab[arindex]; if (blkequ((uint8_t *)atabptr->arp_Iad, (uint8_t *)faddr, IPLEN) && atabptr->arp_state != AR_FREE) return(arindex); } if (Arp.atabsiz < AR_TAB) { Arp.atabsiz++; } arindex = Arp.atabnxt++; if (Arp.atabnxt >= AR_TAB) Arp.atabnxt = 0; atabptr = &Arp.arptab[arindex]; atabptr->arp_state = AR_ALLOC; blkcopy((uint8_t *)atabptr->arp_Iad, (uint8_t *)faddr, IPLEN); for(i=0 ; i<EPADLEN ; i++) atabptr->arp_Ead[i] = '\0'; atabptr->arp_dev = -1; return(arindex); }
int send(unsigned int to, void *buffer, unsigned int len, struct proc_ctrl_blk *fr_p) { struct proc_ctrl_blk *to_p = getproc(to); struct proc_ctrl_blk *i; if (to_p->state == BLOCKED) { // ready to send blkcopy(to_p->buffer, buffer, MIN(len, to_p->buflen)); to_p->state = READY; return MIN(len, fr_p->buflen); } else if (to_p->state == READY) { fr_p->buffer = buffer; fr_p->buflen = len; // add to sender linked list i = to_p->sender; if (i != NULL) { for (; i->next != NULL; i = i->next); i->next = fr_p; } else to_p->sender = fr_p; return -1; // yield until ready } else { return -2; // bad pid specified } }
/*------------------------------------------------------------------------ * setsegs - initialize the 386 processor *------------------------------------------------------------------------ */ setsegs() { extern int start, etext; struct sd *psd; unsigned int np, npages, lostk, limit; npages = sizmem(); /* maxaddr = (char *)(npages * NBPG - 1); */ //maxaddr = (char *)( 1536 * NBPG - 1); /* 10M size */ /* the top 10M is used for backing store */ // new max address 1024 pages: 0x0400000-1 maxaddr = (char *)( 1024 * 4096 - 1); /* 4M size */ psd = &gdt_copy[1]; /* kernel code segment */ np = ((int)&etext + NBPG-1) / NBPG; /* # code pages */ psd->sd_lolimit = np; psd->sd_hilimit = np >> 16; #if 0 psd = &gdt_copy[2]; /* kernel data segment */ psd->sd_lolimit = npages; psd->sd_hilimit = npages >> 16; psd = &gdt_copy[3]; /* kernel stack segment */ psd->sd_lolimit = npages; psd->sd_hilimit = npages >> 16; #endif psd = &gdt_copy[4]; /* bootp code segment */ psd->sd_lolimit = npages; /* Allows execution of 0x100000 CODE */ psd->sd_hilimit = npages >> 16; /* Set the descriptors for the tasks */ /* Main Xinu task */ psd = &gdt_copy[5]; psd->sd_hibase = ((unsigned int) i386_tasks) >> 24; psd->sd_midbase = (((unsigned int) i386_tasks)>>16) & 0xff; psd->sd_lobase = ((unsigned int) i386_tasks) & 0xffff; /* Page Fault handler task */ psd = &gdt_copy[6]; psd->sd_hibase = ((unsigned int) & i386_tasks[1]) >> 24; psd->sd_midbase = (((unsigned int) & i386_tasks[1]) >> 16) & 0xff; psd->sd_lobase = ((unsigned int) & i386_tasks[1]) & 0xffff; blkcopy(gdt, gdt_copy, sizeof(gdt_copy)); /* initial stack must be in physical memory. */ /* initsp = npages*NBPG - 4; */ initsp = 1024*NBPG - 4; }
/*------------------------------------------------------------------------ * mon_netinit - init nif[] *------------------------------------------------------------------------ */ int mon_netinit() { struct ethdev *ped = &mon_eth[0]; extern short girmask; extern int mon_clkint(); /* clock int. handler, for retx purpose */ blkcopy(mon_nif[0].ni_hwa.ha_addr, ped->ed_paddr, EP_ALEN); blkcopy(mon_nif[0].ni_hwb.ha_addr, ped->ed_bcast, EP_ALEN); mon_nif[0].ni_state = NIS_UP; girmask = 0xfffb; /* * 1. Set monitor's clock interrupt handler (for retx purpose). * (It sets the corresponding mask bit in "girmask" to 0.) * 2. Sets the Ethernet mask bit in "girmask" to 0. * 3. call enable() to enable clock & ethernet interrupts. */ set_evec(IRQBASE, (unsigned int) mon_clkint); girmask = (girmask & ~(1 << ped->ed_irq)); enable(); return(OK); }
void blkcopy(int dreg, int doff, int sreg, int soff, int size, int tmp[]) { assert(size >= 0); if (size == 0) return; else if (size <= 2) blkunroll(size, dreg, doff, sreg, soff, size, tmp); else if (size == 3) { blkunroll(2, dreg, doff, sreg, soff, 2, tmp); blkunroll(1, dreg, doff+2, sreg, soff+2, 1, tmp); } else if (size <= 16) { blkunroll(4, dreg, doff, sreg, soff, size&~3, tmp); blkcopy(dreg, doff+(size&~3), sreg, soff+(size&~3), size&3, tmp); } else (*IR->x.blkloop)(dreg, doff, sreg, soff, size, tmp); }
/*------------------------------------------------------------------------- * make_bootp_packet - *------------------------------------------------------------------------- */ static int make_bootp_packet(struct bootp_msg *bptr, int secs) { bzero(bptr, BOOTP_SIZE); bptr->op = BOOTREQUEST; bptr->htype = AR_HARDWARE; bptr->hlen = EP_ALEN; bptr->xid = 47; /* just a random number that's nonzero */ bptr->secs = hs2net(secs); blkcopy(bptr->chaddr, (char *)&(mon_eth[0].ed_paddr), EP_ALEN); *(int *)bptr->vend = hl2net(RFC1084); bptr->vend[5] = 0xff; #ifdef DEBUG kprintf("Using ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", bptr->chaddr[0], bptr->chaddr[1], bptr->chaddr[2], bptr->chaddr[3], bptr->chaddr[4], bptr->chaddr[5]); #endif return(OK); }
int recv(int *from, void *buffer, unsigned int len, struct proc_ctrl_blk *to_p) { struct proc_ctrl_blk *fr_p; if (to_p->sender != NULL) { // ready to receive fr_p = to_p->sender; blkcopy(buffer, fr_p->buffer, MIN(len, fr_p->buflen)); *from = getpid(fr_p); fr_p->sysret = MIN(len, fr_p->buflen); fr_p->state = READY; to_p->sender = to_p->sender->next; // reset sender return MIN(len, fr_p->buflen); } else { to_p->sysret = (int)from; // store pointer to 'from' arg in sysret to_p->buflen = len; to_p->buffer = buffer; return -1; } }
/*------------------------------------------------------------------------ * snmpd - open the SNMP port and handle incoming queries *------------------------------------------------------------------------ */ int snmpd() { int snmpdev, len; struct xgram *query; struct req_desc rqd; char str[128]; IPaddr from; sninit(); query = (struct xgram *) getmem(sizeof (struct xgram)); /* open the SNMP server port */ if ((snmpdev = xinu_open(UDP, ANYFPORT, SNMPPORT)) == SYSERR) return SYSERR; while (TRUE) { /* * In this mode, give read the size of xgram, it returns * number of bytes of *data* in xgram. */ len = xinu_read(snmpdev, query, sizeof(struct xgram)); blkcopy(from, query->xg_fip, IP_ALEN); xinu_sprintf(str, "\n snmpd: from %u.%u.%u.%u", BYTE(from, 0), BYTE(from, 1), BYTE(from, 2), BYTE(from, 3)); xinu_write(SNMPLOG, str, xinu_strlen(str)); /* parse the packet into the request desc. structure */ if (snparse(&rqd, query->xg_data, len) == SYSERR) { snfreebl(rqd.bindlf); continue; } /* convert ASN.1 representations to internal forms */ if (sna2b(&rqd) == SYSERR) { snfreebl(rqd.bindlf); continue; } if (snrslv(&rqd) == SYSERR) { len = mksnmp(&rqd, query->xg_data, PDU_RESP); /* above call frees string memory */ query->xg_data[rqd.pdutype_pos] = PDU_RESP; query->xg_data[rqd.err_stat_pos] = rqd.err_stat; query->xg_data[rqd.err_idx_pos] = rqd.err_idx; if (xinu_write(snmpdev, query, len) == SYSERR) return SYSERR; snfreebl(rqd.bindlf); continue; } len = mksnmp(&rqd, query->xg_data, PDU_RESP); if (len == SYSERR) { query->xg_data[rqd.pdutype_pos] = PDU_RESP; query->xg_data[rqd.err_stat_pos] = rqd.err_stat; query->xg_data[rqd.err_idx_pos] = rqd.err_idx; if (xinu_write(snmpdev, query, len) == SYSERR) return SYSERR; snfreebl(rqd.bindlf); continue; } if (xinu_write(snmpdev, query, len) == SYSERR) return SYSERR; snfreebl(rqd.bindlf); } }
int send(struct pcb* this_process, int dest_pid, void *buffer, int buffer_len ){ struct pcb* dest_process = findProcess(dest_pid); struct pcb* expected_sender; int buffer_limit; if(dest_process==-1) return -1; //no matching pid if(this_process->pid==dest_process->pid) return -2; //sending to itself expected_sender = dest_process->msg_queue; //kprintf("sending %d to %d\n",this_process->pid,dest_pid); while(expected_sender){ //matching receiver found if(expected_sender->pid==this_process->pid && dest_process->state==RECV_BLOCKED){ //kprintf("match again!\n"); if(dest_process->buffer.size < buffer_len) buffer_limit = dest_process->buffer.size; else buffer_limit = buffer_len; //copy data blkcopy(dest_process->buffer.addr,buffer,buffer_limit); //dequeue expected sender from sender queue dest_process->msg_queue = dequeue(dest_process->msg_queue,expected_sender); //unblock destination process ready(dest_process); //return bytes return buffer_limit; } expected_sender = expected_sender->next; } //no match, receiver is not receiving yet if(dest_process->buffer.ipc_pid==-1){ //destination is in receive from all mode if(dest_process->buffer.size < buffer_len) buffer_limit = dest_process->buffer.size; else buffer_limit = buffer_len; //copy data blkcopy(dest_process->buffer.addr,buffer,buffer_limit); //unblock destination process ready(dest_process); //return bytes return buffer_limit; } this_process->buffer.ipc_pid = dest_process->pid; this_process->buffer.addr = buffer; this_process->buffer.size = buffer_len; this_process->state = SEND_BLOCKED; //add this process to receiver's sender queue dest_process->msg_queue = addtoqueue(dest_process->msg_queue,this_process); //remember to set this_process->next to NULL after calling next() return -3; //destination process not yet receiving }
int recv(struct pcb* this_process, int *from_pid, void *buffer, int buffer_len ){ struct pcb* src_process; int buffer_limit; //kprintf("in receive\n"); if(*from_pid==0){ if(this_process->msg_queue){ kprintf("send queue is not empty!\n"); *from_pid = this_process->msg_queue->pid; } kprintf("pid not specified, receiving from anyone\n"); } if(*from_pid!=0){ src_process = findProcess(*from_pid); kprintf("receiving from pid %d to %d\n",*from_pid,this_process->pid); } if(src_process==-1) return -1; //no matching pid if(this_process->pid==src_process->pid) return -2; //sending to itself //receiving from a process that's receiving from you if(src_process){ if(src_process->state==RECV_BLOCKED){ if(src_process->buffer.ipc_pid=this_process->pid) return -4; } } if(src_process->state==SEND_BLOCKED && src_process->buffer.ipc_pid==this_process->pid && *from_pid!=0){ //match found, proceed with data transfer if(src_process->buffer.size > buffer_len) buffer_limit = buffer_len; else buffer_limit = src_process->buffer.size; //copy data blkcopy(buffer,src_process->buffer.addr,buffer_limit); printQueue(this_process->msg_queue); //dequeue src process from sender list this_process->msg_queue = dequeue(this_process->msg_queue,src_process); //update the pointer to from pid //blkcopy(*from_pid,&(src_process->pid),sizeof(int)); printQueue(this_process->msg_queue); //while(1); //unblock sending process, put it back on ready queue ready(src_process); //return received bytes return buffer_limit; }else{ if(*from_pid!=0){ //add source process to send queue this_process->msg_queue = addtoqueue(this_process->msg_queue,src_process); //printQueue(this_process->msg_queue); this_process->buffer.ipc_pid = src_process->pid; }else{ kprintf("no senders\n"); this_process->buffer.ipc_pid = -1; } this_process->buffer.addr = buffer; this_process->buffer.size = buffer_len; this_process->state = RECV_BLOCKED; return -3; //source process not yet sending } }
/*------------------------------------------------------------------------ * kbmputc - write one character to the physical monitor *------------------------------------------------------------------------ */ static void kbmputc( unsigned char c ) { unsigned cursorat; unsigned short was; unsigned char *cp; static unsigned char *crtat = 0; if (c == 0) return; if (crtat == 0) { /* XXX probe to find if a color or monochrome display */ was = *(unsigned short *)Crtat; *(unsigned short *)Crtat = 0xA55A; if (*(unsigned short *)Crtat != 0xA55A) { Crtat = (unsigned char *) MONO_BUF; addr_6845 = MONO_BASE; } *(unsigned short *)Crtat = was; /* Extract cursor location */ outb(addr_6845,14); cursorat = inb(addr_6845+1)<<8 ; outb(addr_6845,15); cursorat |= inb(addr_6845+1); if (cursorat <= COL * ROW) crtat = Crtat + cursorat * CHR; else crtat = Crtat; /* clean display */ for (cp = crtat; cp < Crtat+ROW*COL*CHR; cp += 2) { cp[0] = ' '; cp[1] = att; } } switch (c) { case '\t': do kbmputc(' '); while ((int)crtat % (8*CHR)); break; case '\010': crtat -= CHR; break; case '\n': crtat += COL*CHR ; /* fall through */ case '\r': crtat -= (crtat - Crtat) % (COL*CHR); break; default: crtat[0] = c; crtat[1] = att; crtat += CHR; break ; } /* implement a scroll */ if (crtat >= Crtat+COL*ROW*CHR) { /* move text up */ blkcopy(Crtat, Crtat+COL*CHR, COL*(ROW-1)*CHR); /* clear line */ for (cp = Crtat+ COL*(ROW-1)*CHR; cp < Crtat + COL*ROW*CHR ; cp += 2) cp[0] = ' '; crtat -= COL*CHR ; } cursor((crtat-Crtat)/CHR); }