Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

141 lines
3.5 KiB

/*++
Copyright (c) 2002 Microsoft Corporation
Module Name:
wsautils.h
Abstract:
IPv6 related functions
Author:
kumarp 18-July-2002 created
Revision History:
--*/
#include <lsapch2.h>
#include "wsautils.h"
//
// taken from /nt/net/sockets/winsock2/wsp/afdsys/kdext/tdiutil.c
//
// the only changes were:
// -- made type of S as PWCHAR instead of PCHAR
// -- _snprintf ==> _snwprintf
// -- format strings "foo" ==> L"foo"
//
//
INT
MyIp6AddressToString (
PIN6_ADDR Addr,
PWCHAR S,
INT L
)
{
int maxFirst, maxLast;
int curFirst, curLast;
int i;
int endHex = 8, n = 0;
// Check for IPv6-compatible, IPv4-mapped, and IPv4-translated
// addresses
if ((Addr->s6_words[0] == 0) && (Addr->s6_words[1] == 0) &&
(Addr->s6_words[2] == 0) && (Addr->s6_words[3] == 0) &&
(Addr->s6_words[6] != 0)) {
if ((Addr->s6_words[4] == 0) &&
((Addr->s6_words[5] == 0) || (Addr->s6_words[5] == 0xffff)))
{
// compatible or mapped
n += _snwprintf(&S[n], L-1-n, L"::%s%u.%u.%u.%u",
Addr->s6_words[5] == 0 ? L"" : L"ffff:",
Addr->s6_bytes[12], Addr->s6_bytes[13],
Addr->s6_bytes[14], Addr->s6_bytes[15]);
S[n]=0;
return n;
}
else if ((Addr->s6_words[4] == 0xffff) && (Addr->s6_words[5] == 0)) {
// translated
n += _snwprintf(&S[n], L-1-n, L"::ffff:0:%u.%u.%u.%u",
Addr->s6_bytes[12], Addr->s6_bytes[13],
Addr->s6_bytes[14], Addr->s6_bytes[15]);
S[n]=0;
return n;
}
}
// Find largest contiguous substring of zeroes
// A substring is [First, Last), so it's empty if First == Last.
maxFirst = maxLast = 0;
curFirst = curLast = 0;
// ISATAP EUI64 starts with 00005EFE (or 02005EFE)...
if (((Addr->s6_words[4] & 0xfffd) == 0) && (Addr->s6_words[5] == 0xfe5e)) {
endHex = 6;
}
for (i = 0; i < endHex; i++) {
if (Addr->s6_words[i] == 0) {
// Extend current substring
curLast = i+1;
// Check if current is now largest
if (curLast - curFirst > maxLast - maxFirst) {
maxFirst = curFirst;
maxLast = curLast;
}
}
else {
// Start a new substring
curFirst = curLast = i+1;
}
}
// Ignore a substring of length 1.
if (maxLast - maxFirst <= 1)
maxFirst = maxLast = 0;
// Write colon-separated words.
// A double-colon takes the place of the longest string of zeroes.
// All zeroes is just "::".
for (i = 0; i < endHex; i++) {
// Skip over string of zeroes
if ((maxFirst <= i) && (i < maxLast)) {
n += _snwprintf(&S[n], L-1-n, L"::");
i = maxLast-1;
continue;
}
// Need colon separator if not at beginning
if ((i != 0) && (i != maxLast))
n += _snwprintf(&S[n], L-1-n, L":");
n += _snwprintf(&S[n], L-1-n, L"%x", RtlUshortByteSwap(Addr->s6_words[i]));
}
if (endHex < 8) {
n += _snwprintf(&S[n], L-1-n, L":%u.%u.%u.%u",
Addr->s6_bytes[12], Addr->s6_bytes[13],
Addr->s6_bytes[14], Addr->s6_bytes[15]);
}
S[n] = 0;
return n;
}