?? bclient.c
字號:
#if !defined(i386) && !defined (i960)
LanStop();
#endif
if (Bootp_Replied) {
retval = 0;
/* If raw packet is wanted, just copy and return here */
if ((flags & RAW) == RAW)
bmemcpy((UCHAR *)&BootpReplyPkt, (UCHAR *)ret_params, sizeof(bootppkt_t));
/* Extract returned parameters */
else
retval = extract_bootpkt(&BootpReplyPkt, (bootpparms_t *)ret_params);
}
else
retval = 0xffffffff;
return (retval);
}
/***********************************************************************/
/* broadcast_bootp: Build a BOOTP_REQUEST packet to be broadcast */
/* and call network interface to send it. */
/* */
/* INPUTS: NiLanPtr - Ptr to NI to do broadcast on. */
/* */
/* RETURNS: 0 for success, 0xffffffff for failure */
/* */
/***********************************************************************/
static ULONG broadcast_bootp(long (*ni_entry)(ULONG, union nientry *))
{
union nientry getpkb_ni, brdcast_ni;
char *pkb_ptr;
#if NI_RAWMEM
mblk_t *m;
frtn_t free;
#endif
#if NI_RAWMEM
free.free_func = 0;
free.free_arg = 0;
m = besballoc((UCHAR *)&BootpBuf, IP_SZ + UDP_SZ + BOOTP_SZ, 0, &free);
if (m == 0)
return (0xFFFFFFFF);
m->b_wptr = (UCHAR *)(m->b_wptr + IP_SZ + UDP_SZ + BOOTP_SZ);
brdcast_ni.nibrdcast.buff_addr = (char *)m;
#else
getpkb_ni.nigetpkb.count = IP_SZ + UDP_SZ + BOOTP_SZ;
getpkb_ni.nigetpkb.hwa_ptr = 0;
getpkb_ni.nigetpkb.if_num = BOOTP_IFNUM;
if ((pkb_ptr=(char *)(*ni_entry)(NI_GETPKB, &getpkb_ni)) == (char *)-1)
return (0xffffffff);
bootp_ip_packet(pkb_ptr);
brdcast_ni.nibrdcast.buff_addr = (char *)pkb_ptr;
#endif
brdcast_ni.nibrdcast.count = IP_SZ + UDP_SZ + BOOTP_SZ;
brdcast_ni.nibrdcast.type = IP_TYPE;
brdcast_ni.nibrdcast.if_num = BOOTP_IFNUM;
(*ni_entry)(NI_BROADCAST, &brdcast_ni);
return 0;
}
/***********************************************************************/
/* bootp_ip_packet: build an IP packet for BOOTP request */
/* */
/* INPUTS: bootpbuf: pointer to IP packet to be built */
/* */
/***********************************************************************/
static void bootp_ip_packet(char *bootpbuf)
{
struct iphdr *ip;
struct udphdr *udp;
bootppkt_t *bootp;
UCHAR *exts;
struct mib_ifreq ifr;
union nientry ni;
/* reset packet memory area */
bmemset((UCHAR *)bootpbuf, 0, IP_SZ + UDP_SZ + BOOTP_SZ);
/* Fill in BOOTP request area */
bootp = (bootppkt_t *)(bootpbuf + IP_SZ + UDP_SZ);
bootp->op = BOOTP_REQUEST;
bootp->htype = HTYPE_ETH;
bootp->xid = BootpXid = htonl(InitialXid++);
bootp->secs = htons(SecsSinceStart);
bootp->flags = 0;
bmemset((UCHAR *)&ni, 0, sizeof(union nientry));
ni.niioctl.cmd = SIOCGIFTYPE;
ni.niioctl.arg = (long *)𝔦
ni.niioctl.if_num = BOOTP_IFNUM;
(*MyNiLan)(NI_IOCTL, &ni);
bootp->hlen = ifr.ie_type;
bmemcpy(EthAddrPtr, bootp->chaddr, bootp->hlen);
strcpy((UCHAR *)BootpServerName, (UCHAR *)(bootp->sname));
strcpy((UCHAR *)BootpFileName, (UCHAR *)(bootp->file));
/* Initialize vendor extensions */
((vendexts_t *)(bootp->vend))->cookie = htonl(BOOTP_COOKIE);
exts = ((vendexts_t *)(bootp->vend))->extensions;
*exts = END_TAG;
/* Fill in UDP header */
udp = (struct udphdr *)(bootpbuf + IP_SZ);
udp->uh_sport = htons(IPPORT_BOOTPC);
udp->uh_dport = htons(IPPORT_BOOTPS);
udp->uh_ulen = htons(UDP_SZ + BOOTP_SZ);
udp->uh_sum = 0;
/* Fill in IP header */
ip = (struct iphdr *)bootpbuf;
ip->ip_v = IPVERSION;
ip->ip_hl = IP_SZ >> 2;
ip->ip_len = htons(IP_SZ + UDP_SZ + BOOTP_SZ);
ip->ip_id = htons(ip_id++);
ip->ip_ttl = UDP_TTL * 2;
ip->ip_p = IPPROTO_UDP;
ip->ip_src = 0;
ip->ip_dst = htonl(INADDR_BROADCAST);
ip->ip_sum = in_cksum((UCHAR *)ip, IP_SZ);
}
/***********************************************************************/
/* process_bootp: Called from the NI as a result of (1) polling the NI */
/* to check available packet (2) examing if pSOS is up */
/* */
/* INPUTS: type - Protocol number of packet being announced. */
/* buff_addr - Pointer to the packet being announced. */
/* */
/* NOTE: If buff_addr is NULL, it is not for announcing packet, */
/* just return PsosUp state. */
/* */
/***********************************************************************/
static ULONG process_bootp(int type, char *buff_addr)
{
char *bp;
union nientry retpkb_ni;
bootppkt_t *bootp;
struct udphdr *udp;
/* struct iphdr *ip; --delete by szg */
if (buff_addr == NULL)
return(PsosUp);
if (!Bootp_Replied && (type == IP_TYPE)) {
#if NI_RAWMEM
bp = (char *) ((mblk_t *)buff_addr)->b_rptr;
#else
bp = (char *)buff_addr;
#endif
/* ip = (struct iphdr *)bp; -- chg by szg just for restraining warning */
udp = (struct udphdr *)(bp+IP_SZ);
bootp = (bootppkt_t *)(bp+IP_SZ+UDP_SZ);
if ((ntohs(udp->uh_sport) == IPPORT_BOOTPS) &&
(ntohs(udp->uh_dport) == IPPORT_BOOTPC) &&
(bootp->xid == BootpXid) &&
(bootp->op == BOOTP_REPLY)) {
bmemcpy((UCHAR *)bp+IP_SZ+UDP_SZ, (UCHAR *)&BootpReplyPkt, BOOTP_SZ);
Bootp_Replied = TRUE;
}
}
#if NI_RAWMEM
bfreemsg((mblk_t *)buff_addr);
#else
retpkb_ni.niretpkb.buff_addr = buff_addr;
retpkb_ni.niretpkb.if_num = BOOTP_IFNUM;
(*MyNiLan)(NI_RETPKB, &retpkb_ni);
#endif
return PsosUp;
}
/***********************************************************************/
/* extract_bootpkt: extract information from BOOTP reply packet */
/* */
/* INPUTS: bootp: BOOTP reply packet address */
/* ret: address for copying extracted information */
/* */
/***********************************************************************/
#define extractlong(c) \
((((char *)c)[0] << 24) | (((char *)c)[1] << 16) | \
(((char *)c)[2] << 8) | (((char *)c)[3]))
#define extractshort(c) \
((((char *)c)[0] << 8) | (((char *)c)[1]))
static ULONG extract_bootpkt(bootppkt_t *bootp, bootpparms_t *retp)
{
unsigned long retval = 0;
unsigned char *exts, tag, len;
unsigned long ltag;
unsigned short stag;
((bootpparms_t *)retp)->yourIP = bootp->yiaddr;
((bootpparms_t *)retp)->TFTPserverIP = bootp->siaddr;
strcpy((UCHAR *)(bootp->file), (UCHAR *)(retp->bootfile_name));
/* Extract parameters from vendor extension area, if any */
if (ntohl(((vendexts_t *)bootp->vend)->cookie) != BOOTP_COOKIE)
retval = 0xffffffff;
exts = ((vendexts_t *)(bootp->vend))->extensions;
while ((exts - ((vendexts_t *)(bootp->vend))->extensions) <
VEND_SZ-sizeof(ULONG)) {
tag = *exts++;
switch(tag) {
case SUBNET_MASK_TAG :
len = *exts++;
ltag = extractlong(exts);
((bootpparms_t *)retp)->subnetmask = htonl(ltag);
exts += len;
break;
case GATEWAY_TAG :
len = *exts++;
ltag = extractlong(exts);
((bootpparms_t *)retp)->gatewayIP.s_addr = htonl(ltag);
exts += len;
break;
case HOSTNAME_TAG :
len = *exts++;
bmemset((UCHAR *)(((bootpparms_t *)retp)->hostname), 0, sizeof(((bootpparms_t *)retp)->hostname));
strncpy(((bootpparms_t *)retp)->hostname, (char *)exts, len);
exts += len;
break;
case BOOTFILE_SIZE_TAG :
len = *exts++;
stag = extractshort(exts);
((bootpparms_t *)retp)->bootfile_size = 512 * stag;
exts += len;
break;
case BOOTP_SERVER_TAG :
len = *exts++;
ltag = extractlong(exts);
((bootpparms_t *)retp)->BOOTPserverIP.s_addr = htonl(ltag);
exts += len;
break;
case END_TAG :
break;
default:
len = *exts++;
exts += len;
break;
} /* switch */
} /* while */
return (retval);
}
/***********************************************************************/
/* bmemcpy: Copy a memory block */
/* */
/* INPUTS: src - Source address */
/* dest - Destination address */
/* nbytes - Number of bytes to copy */
/* */
/***********************************************************************/
static void bmemcpy(UCHAR *src, UCHAR *dest, ULONG nbytes)
{
UCHAR *srcp = src, *destp = dest;
while (nbytes--)
*destp++ = *srcp++;
}
/***********************************************************************/
/* bmemset: set memory with defined values */
/* */
/* INPUTS: ptr: address of block */
/* fill: contents of memory */
/* count: length of block */
/* */
/***********************************************************************/
static void bmemset(UCHAR *ptr, register UCHAR fill, register ULONG count)
{
while (count--)
*ptr++ = fill;
}
/***********************************************************************/
/* strcpy: Copy a string */
/* */
/* INPUTS: src - Source address */
/* dest - Destination address */
/* */
/***********************************************************************/
static void strcpy(UCHAR *src, UCHAR *dst)
{
while ((*dst++ = *src++) != '\0');
}
/***********************************************************************/
/* sleep: wait for specified seconds */
/* */
/***********************************************************************/
static void sleep(int count)
{
int i;
if (PsosUp)
tm_wkafter(count * anchor->psosct->kc_ticks2sec);
else
for (i = 0; i < count*10; ++i) Delay100ms();
}
/*****************************************************************************/
/* in_cksum - Compute Internet (1's complement sum) Checksum */
/* */
/* INPUT : count is number of bytes to checksum */
/* addr is the starting address */
/* OUTPUT : the 1's complement sum of the buffer */
/*****************************************************************************/
USHORT in_cksum(UCHAR *addr, int count)
{
ULONG sum = 0;
while (count > 1) {
sum += *((USHORT *)addr);
addr += 2;
count -= 2;
}
/* Add left-over byte, if any */
if (count > 0)
sum += (*(USHORT *) addr) << 8;
/* Fold 32-bit sum to 16 bits */
while (sum & 0xFFFF0000)
sum = (sum & 0x0000FFFF) + ((sum & 0xFFFF0000) >> 16);
return((USHORT)~sum);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -