277 lines
5.7 KiB
Common Lisp
277 lines
5.7 KiB
Common Lisp
*process or(!) source xref attributes macro options;
|
|
/*********************************************************************
|
|
* Program to parse an IP address into --> IPv4 or IPv6 format
|
|
* 28.05.2013 Walter Pachl translated from REXX version 3
|
|
* x2d was the hard part :-)
|
|
*********************************************************************/
|
|
ip: proc options(main);
|
|
Dcl ipa char(50) Var;
|
|
Dcl ipi char(50) Var;
|
|
Dcl ipax char(50) Var Init('');
|
|
Dcl ipad char(50) Var Init('');
|
|
Dcl space char(4);
|
|
Dcl port char(5) Var;
|
|
dcl head Char(132) Var;
|
|
head=' input IP address hex IP address '!!
|
|
' decimal IP address space port';
|
|
Put Edit(head)(Skip,a);
|
|
Put Edit(copies('_',30),
|
|
copies('_',32),
|
|
copies('_',39),
|
|
copies('_', 5),
|
|
copies('_', 5))
|
|
(Skip,6(a,x(1)));
|
|
|
|
call expand('127.0.0.1');
|
|
call expand('127.0.0.1:80');
|
|
call expand('2605:2700:0:3::4713:93e3');
|
|
call expand('[2605:2700:0:3::4713:93e3]:80');
|
|
call expand('::1');
|
|
call expand('[::1]:80');
|
|
|
|
expand: procedure(s);
|
|
Dcl s Char(50) Var;
|
|
ipi=s;
|
|
ipa=s;
|
|
If index(ipa,'.')>0 Then
|
|
Call expand_ipv4;
|
|
Else
|
|
Call expand_ipv6;
|
|
ipad=x2d(ipax);
|
|
Put Edit(left(ipi,30),right(ipax,32),right(ipad,39),
|
|
right(space,5),right(port,5))
|
|
(Skip,6(a,x(1)));
|
|
End;
|
|
|
|
expand_ipv4: Proc;
|
|
Dcl a(4) Char(3) Var;
|
|
Dcl (pp,j) Bin Fixed(31);
|
|
space='IPv4';
|
|
pp=index(ipa,':');
|
|
If pp>0 Then Do;
|
|
port=substr(ipa,pp+1);
|
|
ipa=left(ipa,pp-1);
|
|
End;
|
|
Else
|
|
Port='';
|
|
Call parse((ipa),'.',a);
|
|
ipax='';
|
|
do j=1 To 4;
|
|
ipax=ipax!!a(j);
|
|
end;
|
|
End;
|
|
|
|
expand_ipv6: Proc;
|
|
Dcl a(8) Char(4) Var;
|
|
Dcl (s,o1,o2) Char(50) Var Init('');
|
|
Dcl (i,ii,pp,j,n) Bin Fixed(31) Init(0);
|
|
space='IPv6';
|
|
pp=index(ipa,']:');
|
|
If pp>0 Then Do;
|
|
port=substr(ipa,pp+2);
|
|
ipa=substr(ipa,2,pp-2);
|
|
End;
|
|
Else
|
|
Port='';
|
|
s=ipa;
|
|
j=0;
|
|
Do i=1 To 8 While(s>'');
|
|
pp=index(s,':');
|
|
dcl temp Char(6) Var;
|
|
If pp>1 Then
|
|
temp=left(s,pp-1);
|
|
Else
|
|
temp=s;
|
|
temp=right(temp,4,'0');
|
|
Select(pp);
|
|
When(0) Do;
|
|
a(i)=temp;
|
|
s='';
|
|
End;
|
|
When(1) Do;
|
|
a(i)='----';
|
|
ii=i;
|
|
s=substr(s,pp+1);
|
|
If left(s,1)=':' Then
|
|
s=substr(s,2);
|
|
End;
|
|
Otherwise Do;
|
|
a(i)=temp;
|
|
s=substr(s,pp+1);
|
|
End;
|
|
End;
|
|
End;
|
|
n=i-1;
|
|
o1='';
|
|
o2='';
|
|
Do i=1 To n;
|
|
If i=ii Then Do;
|
|
o1=o1!!'----';
|
|
Do j=1 To 9-n;
|
|
o2=o2!!'0000';
|
|
End;
|
|
End;
|
|
Else Do;
|
|
o1=o1!!right(a(i),4,'0');
|
|
o2=o2!!right(a(i),4,'0');
|
|
End;
|
|
End;
|
|
ipax=o2;
|
|
End;
|
|
|
|
parse: Proc(s,c,a);
|
|
Dcl s Char(50) Var;
|
|
Dcl c Char( 1);
|
|
Dcl a(*) Char(*) Var;
|
|
Dcl (i,p) Bin Fixed(31);
|
|
a='';
|
|
Do i=1 By 1 While(length(s)>0);
|
|
p=index(s,c);
|
|
If p>0 Then Do;
|
|
a(i)=left(s,p-1);
|
|
s=substr(s,p+1);
|
|
End;
|
|
Else Do;
|
|
a(i)=s;
|
|
s='';
|
|
End;
|
|
End;
|
|
End;
|
|
|
|
/*
|
|
underscore: Proc(s) Returns(char(132) Var);
|
|
Dcl s Char(*);
|
|
Dcl r Char(length(s)) Var Init('');
|
|
Dcl i Bin Fixed(31);
|
|
Dcl us Bit(1) Init('0'b);
|
|
Do i=1 To length(s)-1;
|
|
If substr(s,i,1)>' ' Then Do;
|
|
r=r!!'_';
|
|
us='1'b;
|
|
End;
|
|
Else Do;
|
|
If substr(s,i+1,1)>' ' & us Then
|
|
r=r!!'_';
|
|
Else Do;
|
|
r=r!!' ';
|
|
us='0'b;
|
|
End;
|
|
End;
|
|
End;
|
|
If substr(s,length(s),1)>' ' Then
|
|
r=r!!'_';
|
|
Return(r);
|
|
End;
|
|
|
|
center: Proc(s,l) Returns(char(50) Var);
|
|
Dcl s char(50) Var;
|
|
Dcl (l,b) Bin Fixed(31);
|
|
b=(l-length(s))/2;
|
|
Return(left(copies(' ',b)!!s,l));
|
|
End;
|
|
*/
|
|
copies: Proc(c,n) Returns(char(50) Var);
|
|
Dcl c char(50) Var;
|
|
Dcl n Bin Fixed(31);
|
|
Return(repeat(c,n-1));
|
|
End;
|
|
|
|
|
|
c2d: Procedure(s) Returns(Char(50) Var);
|
|
Dcl s Char(*) Var;
|
|
Dcl d Pic'99';
|
|
Dcl (v,part,result,old) Char(100) Var;
|
|
Dcl i Bin Fixed(31);
|
|
result='0';
|
|
v='1';
|
|
|
|
Do i=length(s) To 1 By -1;
|
|
d=c2d(substr(s,i,1));
|
|
part=longmult((v),(d));
|
|
result=longadd((result),(part));
|
|
v=longmult((v),'16');
|
|
End;
|
|
Do While(left(result,1)='0');
|
|
result=substr(result,2);
|
|
End;
|
|
Return(result);
|
|
/*
|
|
dbg: Proc(txt);
|
|
Dcl txt Char(*);
|
|
Put Skip list(txt);
|
|
End;
|
|
*/
|
|
x2d: Procedure(c) Returns(Char(2));
|
|
Dcl c Char(1);
|
|
Dcl res Char(2);
|
|
Select(c);
|
|
When('a','A') res='10';
|
|
When('b','B') res='11';
|
|
When('c','C') res='12';
|
|
When('d','D') res='13';
|
|
When('e','E') res='14';
|
|
When('f','F') res='15';
|
|
Otherwise res='0'!!c;
|
|
End;
|
|
Return(res);
|
|
End;
|
|
|
|
longmult: Procedure(as,bs) Returns(Char(1000) Var);
|
|
/* REXX **************************************************************
|
|
* Multiply(as,bs) -> as*bs
|
|
*********************************************************************/
|
|
Dcl (as,bs) Char(*);
|
|
Dcl (a(1000),b(1000),r(1000)) Pic'9';
|
|
Dcl (p,s) Pic'99';
|
|
Dcl (al,bl) Bin Fixed(31);
|
|
Dcl (i,ai,bi,ri,rim) Bin Fixed(31);
|
|
Dcl res Char(1000) Var Init((1000)'0');
|
|
al=length(as); Do ai=al To 1 By -1; a(ai)=substr(as,al-ai+1,1); End;
|
|
bl=length(bs); Do bi=bl To 1 By -1; b(bi)=substr(bs,bl-bi+1,1); End;
|
|
r=0;
|
|
rim=0;
|
|
Do bi=1 To bl;
|
|
Do ai=1 To al;
|
|
ri=ai+bi-1;
|
|
p=a(ai)*b(bi);
|
|
Do i=ri by 1 Until(p=0);
|
|
s=r(i)+p;
|
|
r(i)=mod(s,10);
|
|
p=s/10;
|
|
End;
|
|
rim=max(rim,i);
|
|
End;
|
|
End;
|
|
res='';
|
|
Do i=1 To rim;
|
|
res=r(i)!!res;
|
|
End;
|
|
Return(res);
|
|
End;
|
|
|
|
longadd: proc(as,bs) Returns(Char(100) Var);
|
|
Dcl (as,bs) Char(*) Var;
|
|
Dcl cs Char(100) Var Init('');
|
|
Dcl (al,bl,cl,i) Bin Fixed(31);
|
|
Dcl a(100) Pic'9' Init((100)0);
|
|
Dcl b(100) Pic'9' Init((100)0);
|
|
Dcl c(100) Pic'9' Init((100)0);
|
|
Dcl temp Pic'99';
|
|
al=length(as);
|
|
bl=length(bs);
|
|
Do i=1 To al; a(i)=substr(as,al-i+1,1); End;
|
|
Do i=1 To bl; b(i)=substr(bs,bl-i+1,1); End;
|
|
cl=max(al,bl)+1;
|
|
Do i=1 To cl;
|
|
temp=a(i)+b(i)+c(i);
|
|
c(i)=mod(temp,10);
|
|
c(i+1)=c(i+1)+temp/10;
|
|
End;
|
|
Do i=1 To cl;
|
|
cs=c(i)!!cs;
|
|
End;
|
|
Return(cs);
|
|
End;
|
|
End;
|
|
|
|
end;
|