educoder--ip地址的预处理

ip地址的预处理

任务描述
熟悉ip地址的多种表现形式,理解ip地址,子网掩码,网络地址的涵义。
熟悉不同形式之间的转换,为后续实现arp协议做准备。

第一个任务,根据ip和子网掩码获得该ip的网络地址。完成函数:

/*根据掩码获取ip地址对应的网络地址*/  
uint32 get_netaddr(uint32 ip, uint32 mask);  

第二个任务,就是做上述变换的逆变换,将unsigned int 的ip地址变为字符串的形式。完成函数:

/*将数据表示的ip地址转为点10进制表示的字符串*/  
char* ip2str(uint32 ip, char *ipstr)  

第三个任务:完成字符串形式的ip地址,如“192.168.1.2”,转换成32位的ip地址,即转为unsigned int 符号网络字节顺序的32位无符号整数。
将地址设为无符号整数,比设为unsigned char[4]这样的数组,在进行比较操作,与掩码作运算时更方便。完成函数:

/*将字符串表示的点10进制表示的ip地址转为数值表示*/  
uint32 str2ip(char *ipstr) ;  

代码

#include"datalink_arp.h"
/*去掉读入的字符串中的多余空格字符*/
char *strtrim(char *str) {
    int i = 0, k = 0;
    while (str[i] != '\0') {
        if ((str[i] >= '0'&&str[i] <= '9') || (str[i] >= 'a'&&str[i] <= 'z') || str[i] == ':'||str[i]=='.') {
            str[k] = str[i]; k++;
        }
        i++;
    }
    str[k] = '\0';
    return str;
}
/*从配置文件中获取字符串表示的本地ip,mask,gate,dns*/
void getconfig(char*file, char *ipstr,char *maskstr,char *gatestr,char*dnsstr) {
    FILE *f = fopen(file, "r");
    if (f == NULL)
        return;
    char str[100];
    while (fgets(str, 100, f) != NULL) {
        strtrim(str);
        int i = 0;
        while (str[i] != ':') i++;
        i++;
        switch (str[0]) {
            case 'i':strcpy(ipstr, str + i ); break;
            case 'm':strcpy(maskstr, str + i ); break;
            case 'g':strcpy(gatestr, str + i ); break;
            case 'd':strcpy(dnsstr, str + i); break;
        }
    }
}
/*根据掩码获取ip地址对应的网络地址*/
uint32 get_netaddr(uint32 ip, uint32 mask) {
    uint32 netaddr=0;
    /*******Begin 1 ***********/
    mask = htonl(mask);
    ip = htonl(ip);
    // printf("ip : %u\n", ip);
    for(int i = 0; i < 32 ; i++){
        // printf("netaddr : %u\n", netaddr);
        if((mask >> i) % 2 == 0){
            continue;
        }
        // printf("i : %d\n", i);
        netaddr = (ip >> i);
        netaddr <<= i;
        break;
    }

    /********End  1 **********/
    return htonl(netaddr);
}
/*将数据表示的ip地址转为点10进制表示的字符串*/
char* ip2str(uint32 ip, char *ipstr) {
    /*******Begin 2 ***********/
    // printf("ip : %u\n", ip);
    char* t[4][100];
    int len[4];
    for(int i = 0; i < 4; i++){
        int sum = 0;
        for(int j = 0; j <= 7; j++){
            int k = ip % 2;
            // printf("k : %d\n", k);
            ip >>= 1;
            sum += k * (pow(2, j));
        }
        int j = 0;
        if(sum == 0){
            t[i][j] = '0';
            j++;
        }
        while(sum){
            int k = sum % 10;
            sum /= 10;
            t[i][j] = k + '0';
            j++;
        }
        len[i] = j;
    }
    int q = 0;
    for(int i = 0; i <= 3; i++){
        for(int j = len[i] - 1; j >= 0; j--){
            ipstr[q] = t[i][j];
            q++;
        }
        if(i == 3){
            ipstr[q] = '\0';
            break;
        }
        ipstr[q] = '.';
        q++;
    }
    /********End 2 **********/
    return ipstr;
}
/*将字符串表示的点10进制表示的ip地址转为数值表示*/
uint32 str2ip(char *ipstr) {
    uint32 ip=0;
    /**********Begin 3 *******/
    for(int i = 0; ipstr[i] != '\0'; i++){
        int sum = 0;
        while(ipstr[i] != '.' && ipstr[i] != '\0'){
            sum *= 10;
            sum += ipstr[i] - '0';
            i++;
        }
        ip <<= 8;
        ip += sum;
    }
    // printf("%u\n", );
    /**********End 3 ********/
    return htonl(ip);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值