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);
}