⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bclient.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -