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

📄 ethernet.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 3 页
字号:
        break;    case ecs(ETHERTYPE_ARP):        arpp = (struct arphdr *)(ehdr+1);        printf("  Type = ARP %s from IP %d.%d.%d.%d)\n",            arpp->operation == ecs(ARP_RESPONSE) ? "RESPONSE" : "REQUEST",            arpp->senderia[0],arpp->senderia[1],            arpp->senderia[2],arpp->senderia[3]);        break;    case ecs(ETHERTYPE_REVARP):        printf("  Type = REVARP\n");        break;    default:        printf("  Type = 0x%04x ???\n", ehdr->ether_type);        break;    }}/* *  printIp(p) */intprintIp(struct ip *ihdr){    int i;    struct ip *icpy;    char    buf[16], buf1[16];    ulong   tmp[sizeof(struct ip)/2];    /* Copy data to aligned memory space so printf doesn't crash. */    memcpy((char *)tmp,(char *)ihdr,sizeof(struct ip));    icpy = (struct ip *)tmp;    printf("  IP:  vhl/tos  len    id     offset  ttl/proto  csum\n");    printf("       x%02x%02x    x%04x  x%04x  x%04x   x%02x%02x      x%04x\n",        icpy->ip_vhl,icpy->ip_tos, ecs(icpy->ip_len),        ecs(icpy->ip_id), ecs(icpy->ip_off),        icpy->ip_ttl, icpy->ip_p, ecs(icpy->ip_sum));    printf("       src          dest\n");    printf("       %s  %s\n",        IpToString(icpy->ip_src.s_addr,buf),        IpToString(icpy->ip_dst.s_addr,buf1));    if (icpy->ip_p == IP_UDP) {        printUdp((struct Udphdr *)(ihdr+1));        return(0);    }    for(i=0;protocols[i].pname;i++) {        if (icpy->ip_p == protocols[i].pnum) {            printf("  Protocol: %s\n",protocols[i].pname);            return(0);        }    }    printf("  <%02x>: unknown IP protocol\n", icpy->ip_p);    return (1);}/* *  printUdp(p) */intprintUdp(struct Udphdr *p){    ushort  dport, sport;    dport = ecs(p->uh_dport);    sport = ecs(p->uh_sport);#if INCLUDE_DHCPBOOT    if ((dport == DhcpServerPort) || (dport == DhcpClientPort)) {        printDhcp(p);        return(0);    }#endif    printf("  UDP: sport dport ulen sum\n");    printf("       %4d  %4d  %4d %4d\n",        sport, dport, ecs(p->uh_ulen),ecs(p->uh_sum));    return(0);}intIpToBin(char *ascii,uchar *binary){    int i, digit;    char    *acpy;    acpy = ascii;    for(i=0;i<4;i++) {        digit = (int)strtol(acpy,&acpy,10);        if (((i != 3) && (*acpy++ != '.')) ||            ((i == 3) && (*acpy != 0)) ||            (digit < 0) || (digit > 255)) {            printf("Misformed IP addr: %s\n",ascii);            return(-1);        }        binary[i] = (uchar)digit;    }    return(0);}/* IpToString(): *  Incoming ascii pointer is assumed to be pointing to at least 16 *  characters of available space.  Conversion from long to ascii is done *  and string is terminated with NULL.  The ascii pointer is returned. */char *IpToString(ulong ipadd,char *ascii){    uchar   *cp;    cp = (uchar *)&ipadd;    sprintf(ascii,"%d.%d.%d.%d",        (int)cp[0],(int)cp[1],(int)cp[2],(int)cp[3]);    return(ascii);}char *EtherToString(uchar *etheradd,char *ascii){    sprintf(ascii,"%02x:%02x:%02x:%02x:%02x:%02x",(int)etheradd[0],        (int)etheradd[1],(int)etheradd[2],(int)etheradd[3],        (int)etheradd[4],(int)etheradd[5]);    return(ascii);}/* ipChksum(): *  Compute the checksum of the IP header. *  The incoming pointer to an IP header is directly populated with *  the result. */voidipChksum(struct ip *ihdr){    register int    i;    register ushort *sp;    register long   csum;    csum = 0;    ihdr->ip_sum = 0;    sp = (ushort *) ihdr;    for (i=0;i<((int)sizeof(struct ip)/(int)sizeof(ushort));i++,sp++) {        csum += *sp;        if (csum & 0x80000000)            csum = (csum & 0xffff) + (csum >> 16);    }    while(csum >> 16)        csum = (csum & 0xffff) + (csum >> 16);    ihdr->ip_sum = ~csum;}/*  udpChksum(): *  Compute the checksum of the UDP packet. *  The incoming pointer is to an ip header, the udp header after that ip *  header is directly populated with the result. *  Got part of this code out of Steven's TCP/IP Illustrated Volume 2. */voidudpChksum(struct ip *ihdr){    register int    i;    register ushort *datap;    register long   sum;    int     len;    struct  Udphdr *uhdr;    struct  UdpPseudohdr    pseudohdr;    uhdr = (struct Udphdr *)(ihdr+1);    uhdr->uh_sum = 0;    /* Note that optionally, the checksum can be forced to zero here,     * so a return could replace the remaining code.     * That would be kinda dangerous, but it is an option according to     * the spec.     */    /* Start with the checksum of the pseudo header:     * Note that we have to use memcpy because we don't know if the incoming     * stream is aligned properly.     */    memcpy((char *)&pseudohdr.ip_src.s_addr,(char *)&ihdr->ip_src.s_addr,4);    memcpy((char *)&pseudohdr.ip_dst.s_addr,(char *)&ihdr->ip_dst.s_addr,4);    pseudohdr.zero = 0;    pseudohdr.proto = ihdr->ip_p;    pseudohdr.ulen = uhdr->uh_ulen;    /* Get checksum of pseudo header: */    sum = 0;    datap = (ushort *) &pseudohdr;    for (i=0;i<(sizeof(struct UdpPseudohdr)/sizeof(ushort));i++) {        sum += *datap++;        if (sum & 0x80000000)            sum = (sum & 0xffff) + (sum >> 16);    }    len = ecs(uhdr->uh_ulen);    datap = (ushort *) uhdr;    /* If length is odd, pad with zero and add 1... */    if (len & 1) {        uchar   *ucp;        ucp = (uchar *)uhdr;        ucp[len] = 0;        len++;    }    while(len) {        sum += *datap++;        if (sum & 0x80000000)            sum = (sum & 0xffff) + (sum >> 16);        len -= 2;    }    while(sum >> 16)        sum = (sum & 0xffff) + (sum >> 16);    uhdr->uh_sum = ~sum;}struct  ether_header *EtherCopy(struct ether_header *re){    struct  ether_header *te;    te = (struct ether_header *) getXmitBuffer();    memcpy((char *)&(te->ether_shost),(char *)&(re->ether_dhost),6);    memcpy((char *)&(te->ether_dhost),(char *)&(re->ether_shost),6);    te->ether_type = re->ether_type;    return(te);}ushortipId(void){    return(++UniqueIpId);}/* getTuneup(): *  The DHCP, TFTP and ARP timeout & retry mechanism can be tuned based on *  the content of the shell variables DHCPRETRYTUNE, TFTPRETRYTUNE and *  ARPRETRYTUNE respectively. *  Return 0 if variable is not found, -1 if there is a detected error in *  the content of the shell variable; else 1 indicating that the three *  parameters have been loaded from the content of the shell variable. */intgetTuneup(char *varname,int *rexmitdelay,int *giveupcount,int *rexmitdelaymax){    char *vp, *colon1, *colon2;        vp = getenv(varname);    if (!vp)        return(0);    colon1 = strchr(vp,':');    if (colon1) {        colon2 = strchr(colon1+1,':');        if (colon2) {            *rexmitdelay = (int)strtol(vp,0,0);            *giveupcount = (int)strtol(colon1+1,0,0);            *rexmitdelaymax = (int)strtol(colon2+1,0,0);            return(1);        }    }    printf("Syntax error in %s\n",varname);    return(-1);}/* RetransmitDelay(): *  This function provides a common point for retransmission delay *  calculation.  It is an implementation "similar" to the recommendation *  made in the RFC 2131 (DHCP) section 4.1 paragraph #8... * *  The delay before the first retransmission is 4 seconds randomized by *  the value of a uniform random number chosen from the range -1 to +2. *  The delay before the next retransmission is 8 seconds randomized by *  the same number as previous randomization.  Each subsequent retransmission *  delay is doubled up to a maximum of 66 seconds.  Once a delay of 66 *  seconds is reached, return that value for for 6 subsequent delay *  requests, then return RETRANSMISSION_TIMEOUT (-1) indicating that the *  requestor should give up. * *  The value of randomdelta will be 2, 1, 0 or -1 depending on the target's *  IP address. * *  The return values will be... *  4+randomdelta, 8+randomdelta, 16+randomdelta, etc... up to 64+randomdelta. *  Then after returning 64+randomdelta 6 times, return RETRANSMISSION_TIMEOUT. * *  NOTE: if DELAY_RETURN is the opcode, then RETRANSMISSION_TIMEOUT is *        never returned, once the max is reached, it is always the value *        returned; *        if DELAY_OR_TIMEOUT_RETURN is the opcode, then once maxoutcount *        reaches 6, RETRANSMISSION_TIMEOUT is returned. * *  NOTE1: this function supports the ability to modify the above-discussed *         parameters.  Start with DELAY_INIT_DHCP to set up the parameters *         discussed above; start with DELAY_INIT_XXXX for others. */intRetransmitDelay(int opcode){    static int randomdelta;     /* Used to slightly randomize the delay.                                 * Taken from the 2 least-significant-bits                                 * of the IP address (range = -1 to 2).                                 */    static int rexmitdelay;     /* Doubled each time DELAY_INCREMENT                                 * is called until it is greater than the                                 * value stored in rexmitdelaymax.                                 */    static int rexmitdelaymax;  /* See rexmitdelay. */    static int maxoutcount;     /* Number of times the returned delay has                                 * reached its max.                                 */    static int giveupcount;     /* Once maxoutcount reaches this value, we                                 * give up and return TIMEOUT.                                 */    int     rexmitstate;    rexmitstate = RETRANSMISSION_ACTIVE;    switch(opcode) {        case DELAY_INIT_DHCP:                   if (getTuneup("DHCPRETRYTUNE",&rexmitdelay,                &giveupcount,&rexmitdelaymax) <= 0) {                rexmitdelay = 4;                giveupcount = 6;                rexmitdelaymax = 64;            }            maxoutcount = 0;            randomdelta = (int)(BinIpAddr[3] & 3) - 1;            break;        case DELAY_INIT_TFTP:            if (getTuneup("TFTPRETRYTUNE",&rexmitdelay,                &giveupcount,&rexmitdelaymax) <= 0) {                rexmitdelay = 4;                giveupcount = 3;                rexmitdelaymax = 32;            }            maxoutcount = 0;            randomdelta = (int)(BinIpAddr[3] & 3) - 1;            break;        case DELAY_INIT_ARP:            if (getTuneup("ARPRETRYTUNE",&rexmitdelay,                &giveupcount,&rexmitdelaymax) <= 0) {                rexmitdelay = 1;                    giveupcount = 0;                rexmitdelaymax = 4;            }            maxoutcount = 0;            randomdelta = 0;            break;        case DELAY_INCREMENT:            if (rexmitdelay < rexmitdelaymax)                rexmitdelay <<= 1;      /* double it. */            else                 maxoutcount++;            if (maxoutcount > giveupcount)                rexmitstate = RETRANSMISSION_TIMEOUT;            break;        case DELAY_OR_TIMEOUT_RETURN:            if (maxoutcount > giveupcount)                rexmitstate = RETRANSMISSION_TIMEOUT;            break;        case DELAY_RETURN:            break;        default:            printf("\007TimeoutAlgorithm error 0x%x.\n",opcode);            rexmitstate = RETRANSMISSION_TIMEOUT;            break;    }    if (rexmitstate == RETRANSMISSION_TIMEOUT)        return(RETRANSMISSION_TIMEOUT);    else        return(rexmitdelay+randomdelta);}#endif/* EtherToBin(): *  Convert ascii MAC address string to binary.  Note that this is outside *  the #if INCLUDE_ETHERNET because it is used by password.c.  This correctly *  implies that if there is no ethernet interface, then we need a different *  solution for the password backdoor!. */intEtherToBin(char *ascii,uchar *binary){    int i, digit;    char    *acpy;    acpy = ascii;    for(i=0;i<6;i++) {        digit = (int)strtol(acpy,&acpy,16);        if (((i != 5) && (*acpy++ != ':')) ||            ((i == 5) && (*acpy != 0)) ||            (digit < 0) || (digit > 255)) {            printf("Misformed ethernet addr: %s\n",ascii);            return(-1);        }        binary[i] = (uchar)digit;    }    return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -