reconstructed from isdn-18 with reverse application of the individual
patches.
This commit is contained in:
Matthias Urlichs 1995-09-12 05:07:18 +02:00 committed by Harald Welte
parent 215846b0ff
commit 1097952088
330 changed files with 13890 additions and 23279 deletions

338
DOKU
View File

@ -15,11 +15,25 @@ unter der GPL bzw. ihrem deutschen
Achtung:
=======
Mit der Version für 1.2.0 hat sich die Syntax der cf-Datei leicht geändert.
Mit der Version 11 ist das OK am Ende des statischen Teils der AT/L-Ausgabe
weggefallen, weil das zu viele Leute irritiert hat.
Mit der Version 11 hat sich die Installationsprozedur fuer ISDN-Karten
geaendert. Vorher: Config.c editieren, Modul bauen. Jetzt: d_teles.o
laden, dann fuer jede Karte "insmod -o Tel0 teles.o name=$(cardname Tel0)
mem=0xD6000 irq=5" ausfuehren. Daten anpassen! Unterschiedliche Namen
verwenden! Das rc-Skript in tools/ wurde entsprechend angepasst.
16-Bit-Karten: Zusaetzlich "ipl=X" (X=1..3) fuer die erste bis dritte Karte.
Damit sollte es problemlos sein, zwischen verschiedenen Systemen (mit
einigermaßen identisch konfigurierten Kernels) die Treiber auszutauschen.
Mit der Version für 1.2.0 hat sich die Syntax der cf-Datei leicht geändert:
Der :ea-Parameter in der P-Zeile wurde durch den :lr-Parameter ersetzt:
verwende ":lr /X" statt ":ea X".
hänge an die DL-Zeile einen / an.
- verwende ":lr /X" statt ":ea X".
- hänge an die DL-Zeile an die Nummer einen / an und danach ":pr 0 :sp 65
:pr 63" für 1TR6 oder :sp 8 für Euro-ISDN.
Generell steht nun "/" für EAZs und so; "." steht für Nebenstellennummern.
Bei externen Nummern verwende ich generell ".", aber das ist
Geschmackssache.
@ -28,7 +42,7 @@ Einige Konfigzeilen haben als zus
verpaßt bekommen.
Die Parameter :pr und :sp stehen nun in der DL-Zeile und nicht mehr in
der P-Zeile; siehe unten.
der P-Zeile.
Die I- und O-Flags werden nun klein geschrieben.
@ -63,9 +77,10 @@ Die Konfigurationsdatei ist manchmal etwas undurchsichtig.
_Ich_ werde das nicht ändern, keine Zeit; wenn jemand ein Frontend
schreiben will -- nur zu!
Das Masterprogramm könnte noch Speicherlecks haben...
Das Masterprogramm hat noch Speicherlecks.
Euro-ISDN ist moderat getestet; Gebührenerfassen geht noch nicht.
Euro-ISDN ist moderat getestet; Gebührenerfassen während der Verbindung
geht noch nicht.
Login über ISDN macht noch leichte Probleme.
@ -122,11 +137,17 @@ wer kann und will, m
Kernelpatches
=============
Die Patches basieren auf dem Kernel Linux-1.1.86. Frühere und spätere
Kernels auf eigene Gefahr bzw. Bastelei.
Die Patches basieren auf dem in der Versionsnummer bezeichneten Kernel.
Frühere bzw. spätere Kernels auf eigene Gefahr bzw. Bastelei.
Was die einzelnen Patches machen und ob sie benötigt werden,
steht in den einzelnen Dateien am Anfang.
Der Kernel muß mit CONFIG_MODVERSION gebaut werden. Alternativ (aber das ist
unsicherer) kann im ISDN-Paket aus config/config.data -DCONFIG_MODVERSION
entfernt werden. Das modutils-1.2.8-Paket wird in jedem Fall benötigt, um
Parameter an die einzelnen Module zu übergeben.
Grundstruktur
=============
@ -149,7 +170,7 @@ Sache des Steuerprogramms (D-Kanal) bzw. anderer Streams-Module (B-Kan
Ein kommunikationswilliges Programm öffnet einen freien ISDN-Port
(/dev/isdn/isdnX, X von 1 bis 99 oder so) und sendet einen Verbindungs-
wunsch an das Steuerprogramm ("atd/subnet/login", ffnen einer Verbindung
wunsch an das Steuerprogramm ("atd/subnet/login", öffnen einer Verbindung
zum System "subnet" im Protokollmodus "login"). Das Steuerprogramm schiebt
diesem Kanal nun automatisch die notwendigen B-Kanal-Module unter (X.75,
T.70, V.110, was-auch-immer), baut die Verbindung auf, meldet den Zustand
@ -162,14 +183,8 @@ Dasselbe passiert bei abgehenden Anrufen, die auf das zust
beschränkt sind, zB TCP/IP.
Beispiel:
% kermit
> set lin /dev/isdn/isdn31
% cu -l isdn/isdn22
beliebig, muß nur frei sein.
> set spe 1200
Die eingestellte Geschwindigkeit wird ignoriert, aber Kermit besteht
darauf...
> c
Verbindung herstellen.
AT
OK
Der Interpreter im Kontrollprogramm tut so, als wäre er ein Modem mit
@ -180,12 +195,12 @@ ATD/subnet/login
RRING
CONNECT
login:
Die Verbindung steht. Viel Spaß beim Hacken eines Paßworts für die subnet. ;-)
Die Verbindung steht. Viel Spaß beim Hacken eines Paßworts. ;-)
BETA-BEMERKUNG: Loginverbindungen sind in der jetztigen Version nicht allzu
gut getestet. Was sehr gut tut, ist TCP/IP; siehe dazu die Beispielkonfi-
guration cf.tcp. Ein Anrufbeantworter existiert ebenfalls (leider noch ohne
DMTF-Erkennung); siehe dazu die Beispielkonfiguration cf.answer.
guration. Ein Anrufbeantworter existiert ebenfalls (leider noch ohne
DMTF-Erkennung).
Statt eines Sitenamens tut auch ATD und die Nummer; /login ist der Default
für das Protokoll.
@ -209,9 +224,12 @@ vi config/config.data
vi isdn/cards/dumb/Config.c # Speicherlage+Interrupts der ISDN-Karten
make.isdn
make load # Einbau der Module in den laufenden Kernel
cd /usr/local/isdn
vi cf.tcp # ISDN-Nummern, Dienste, etc. eintragen
bin/master cf.tcp # geht automatisch in den Hintergrund
cd /usr/local/isdn/bin
vi /etc/isdn.conf # ISDN-Nummern, Dienste, etc. eintragen
bin/master /etc/isdn.conf # geht automatisch in den Hintergrund
Sämtliche Gerätedateien werden automatisch angelegt.
Testen:
-------
@ -238,18 +256,27 @@ AT/K
Kann nur vom Superuser ausgeführt werden.
AT/Kn
Beendet die Verbindung <n>, beendet das betreffende Programm.
Kann nur vom Superuser ausgeführt werden.
AT/L
Listet den momentanen Status aller Verbindungen.
<n> <Art> <Partner> <Key> <pid> <Modus/Karte> <UnitNow> <UnitAll> <Stat>
<Modus> ist:
<[minor:]id> <Art> <Partner> <Key> <pid> <Modus/Karte> <UnitNow> <UnitAll> <Status>
<minor> Nummer der Verbindung, für AT/K o.ä.
<n> interne Folgenummer der Statusmeldung; Meldungen, die einen
alten Status ersetzen, bekommen dieselbe Nummer.
<pid> PID des Prozesses, der für die Verbindung gestartet wurde.
<Modus>
off Verbindung nicht aktiv, wird bei ankommendem Ruf reaktiviert.
down Standby; sobald ein Datenpaket ansteht, wird die Verbindung
aufgebaut.
up Verbindung steht
->down
->up Verbindung wird gerade ab- bzw. aufgebaut.
Ein Ausrufezeichen an erster Stelle bedeutet, daß die Verbindung bereits
->down
->up Verbindung wird gerade ab- bzw. aufgebaut.
<UnitNow> Einheiten in der aktuellen Verbindung.
<UnitAll> Einheiten insgesamt seit Start des Prozesses.
<Flags> interner Zustand der Verbindung, komma remote-Nummer,
strichpunkt lokale-Nummer (jeweils wenn bekannt/vorhanden)
<Status> Text; Meldung der Vermittlung (Groß/Kleinschreibung) oder
interner Zustand (Großschreibung).
Ein Ausrufezeichen an erster Stelle bedeutet, daß die Verbindung intern
nicht mehr bekannt ist, der Zustand aber noch eine Zeitlang angezeigt wird.
Bis zum nächsten AT-Befehl bleibt der Kanal im Monitormodus und meldet
@ -257,7 +284,7 @@ AT/L
AT/I
Listet den internen Zustand. In der ersten Zeile stehen die erkannten
ISDN-Karten, die zweite Zeile enthält den internen Zustand des ISDN-
Protokolls.
Systems. Zum Debuggen.
AT/M foo
Sendet den Systembefehl "foo" nach unten. Gefährlich.
Kann zum Online-Rekonfigurieren von Modulen verwendet werden. Beispiel:
@ -284,7 +311,7 @@ ATH
Diverse andere Befehle sind 100% ungetestet. <BREAK> habe ich seit Ewigkeiten
nicht mehr ausprobiert.
ATA existiert übrigens nicht; stattdessen Konfigdatei ändern.
ATA existiert nicht; stattdessen Konfigdatei ändern.
Einschub: Was ist dieser Streams-Kram eigentlich?
@ -301,28 +328,31 @@ pro Fragment) oder von der Gegenseite weggeschmissen werden (Overhead:
unendlich ;-) , muß man sie so kennzeichnen, daß die Gegenseite sie direkt
wieder zusammensetzen kann (Overhead: 2 Bytes; braucht aber besagte gesicherte
Verbindung, um vernünftig zu funktionieren). BTX beispielsweise arbeitet
so.
so. Außerdem ist ISDN bytesynchrton, d.h. irgendjemand muß kennzeichnen, wo
ein Datenpaket aufhört und wo/wann das nächste anfängt. Dafür gibt es, wie
üblich, mehrere Methoden...
Streams sind nun eine Möglichkeit, mehrere speziell geschriebene Module
so auf einem ebenfalls speziell geschriebenen Treiber so zu stapeln, daß
jedes Modul eine Einzelaufgabe dieser Arbeit erledigt. Im Idealfall sind
die einzelnen Module recht klein und damit debugbar, lassen sich vielseitig
auf einem ebenfalls speziell geschriebenen Treiber so zu stapeln, daß jedes
Modul eine Einzelaufgabe dieser Arbeit erledigt. Im Idealfall sind die
einzelnen Module recht klein und damit debugbar, lassen sich vielseitig
zusammenstöpseln, etc.pp. In der Praxis ist die Sache natürlich nicht ganz
so einfach; insbesondere ist der Overhead, die Pakete von einem Modul zum
nächsten zu schaufeln, nicht zu vernachlässigen. Er ist aber tolerierbar,
vor allem wenn man auf die ganzen überflüssigen "Features" (von vielen
vernünftigen Menschen als "Bugs" oder "Designfehler" bezeichnet...)
verzichtet, die USL und Co. in Sys5 Release 4 dazuerfunden haben.
vor allem wenn man auf die ganzen überflüssigen "Features" (von manchen
Menschen als "Bugs" oder "Designfehler" bezeichnet...) verzichtet, die
USL und Co. in Sys5 Release 4 dazuerfunden haben.
Die einzelnen Module müssen parametrisiert werden. Im Normalfall spricht
man sich mit der Gegenseite vorher ab, ob beispielsweise X.75 verwendet
wird und in welchem Modus. Alternativ, und wenn man die Normen auswendig
weiß, schaltet man ein Monitor-Modul zuunterst auf den Datenstrom, ruft
die Gegenseite an, beobachte genau was da passiert, und richtet die Konfi-
guration entsprechend ein. (Das klingt nicht nur kompliziert, das ist
es auch. Außerdem gibt es ein paar Details, die sich nicht ohne weiteres
beobachten lassen.) Zum Glück haben sich ein paar "normale" Betriebsarten
herauskristallisiert, an die sich die meisten Systeme halten.
weiß, schaltet man ein Monitor-Modul zuunterst auf den Datenstrom, läßt
sich von der Gegenseite anrufen, beobachtet genau was da passiert, und
richtet die Konfiguration entsprechend ein. (Das klingt nicht nur
kompliziert, das ist es auch. Außerdem gibt es ein paar Details, die sich
nicht ohne weiteres beobachten lassen.) Zum Glück haben sich ein paar
"normale" Betriebsarten herauskristallisiert, an die sich die meisten
Systeme halten.
Noch ein Einschub: TCP-IP-Routing
@ -340,48 +370,51 @@ Wichtige Spezialf
slipto mit -d starten und auf den ganzen anderen Rechnern im lokalen Netz
eine Defaultroute zum ISDN-Rechner eintragen. ACHTUNG! ALLE LOKALEN
RECHNER BRAUCHEN OFFIZIELL ZUGETEILTE IP-NUMMERN. Das Weiterleiten von
Nummernbereichen nach RFC 1597 muß unterbunden werden (IP-Firewall in den
Kernel einbauen); andere unzulässige Netznummern müssen durch einen
zweiten Gatewayrechner mit zwei Ethernetkarten o.ä., auf dem _keine_
Route eingetragen ist, die auf den ISDN-Rechner zeigt, abgeschottet
werden.
Nummernbereichen nach RFC 1597 muß unterbunden werden (wenn diese lokal
verwendet werden: unbedingt IP-Firewall in den Kernel einbauen und
rausfiltern); andere unzulässige Netznummern müssen durch einen zweiten
Gatewayrechner mit zwei Ethernetkarten o.ä. abgeschottet werden.
- Ein System, das eigentlich Teil des lokalen Netzes wäre, sitzt am anderen
Ende der Leitung. Am einfachsten ist hier Proxy-ARP; der benötigte Befehl
beim Booten lautet "arp -s IP_der_entfernten_Kiste Ether_des_ISDN_-
_Rechners pub". Die Ethernetadresse spuckt "ifconfig eth0" aus.
diplogin (für IP über serielle Leitung) kann den arp-Eintrag automatisch
setzen. Wenn jemand entsprechende Patches für slipto macht -> her zu mir.
- Ein Netz mit stupidem ISDN-Router, der ein Transfernetz sehen will, ist
auf der anderen Seite. Einfachste Methode: Vom lokalen Netzbereich wird
ein 4-Adressen-Bereich abgezwackt und als Transfernetz mißbraucht. Sei
die lokale Adresse 129.130.131.x, so wird zum Beispiel der Bereich x =
[224..227] verwendet (die beiden untersten Bits der unteren Kante des
[224..227] verwendet (die beiden untersten Bits des unteren Endes des
Adressbereichs, hier 224, müssen(!!!) 00 sein). Die nächste Adresse
(hier: 225) wird die lokale Adresse (am besten eintragen via
dummy-Interface: "ifconfig dummy0 129.130.131.225; route add -host
129.130.131.225 dev lo" -- in der Konfigdatei wird die normale
Ethernetadresse des Rechners als lokale Adresse verwendet). Danach (hier
..226) kommt die entfernte Adresse (eintragen via Proxy-ARP).
(hier: 225) wird die lokale Adresse (entweder als lokale Adresse im
slipto, oder via dummy-Interface: "ifconfig dummy0 129.130.131.225; route
add -host 129.130.131.225 dev lo" -- in der Konfigdatei wird in diesem
Fall die normale Ethernetadresse des Rechners als lokale Adresse
verwendet). Danach (hier; .226) kommt die entfernte Adresse (eintragen
via Proxy-ARP).
Auf der Gegenstelle wird dann das Transfernetz mit einer Netmask von
255.255.255.252 konfiguriert, die ..225 wird dort die entfernte
Adresse und die Defaultroute an der Gegenstelle zeigt darauf.
(Außerdem muß manchmal eine Route für das Netz, hier 129.130.131.0,
eingetragen werden.)
eingetragen werden, die auf die Gegenseite, hier .225, zeigt.)
Diese Methode verschwendet 75% des Adressbereichs (die Nummern ..224,
..225 und ..227 werden nie in Erscheinung treten) und einer der Rechner
auf der Gegenseite verwendet dummerweise eine Nummer aus dem lokalen
Netz, für die ein funktionierender Nameserver-Eintrag gepflegt werden
muß, hat aber den Vorteil, daß sie funktioniert.
Diese Methode verschwendet 75% des Adressbereichs (die Nummern .224,
.225 und .227 werden im Internet nie in Erscheinung treten) und einer der
Rechner auf der Gegenseite verwendet dummerweise eine Nummer aus dem
lokalen Netz, für die ein funktionierender Nameserver-Eintrag gepflegt
werden muß, hat aber den Vorteil, daß sie funktioniert.
Es fällt außerdem auf, daß die lokale Adresse und Konfiguration des
ISDN-Links nichts, aber auch gar nichts, mit dem zu tun hat, was die
Gegenseite von uns denkt. Das ist auch total egal. Das einzige, auf das
es ankommt, ist, daß die jeweils lokalen Adressen auch als lokal
angesehen werden und _nicht_ irgendwie wieder zur Gegenseite geroutet
werden. Pingpongpakete haben auf einer ISDN-Leitung nichts verloren!
(Und auch nirgends anders.)
ISDN-Links nichts mit dem zu tun haben muß, was die Gegenseite von uns
denkt. Das ist auch total egal -- im Gegensatz zu PPP werden die Adressen
nicht mit der Gegenstelle abgeglichen. Das einzige, auf das es ankommt,
ist, daß die jeweils lokalen Adressen auch als lokal angesehen werden und
_nicht_ irgendwie wieder zur Gegenseite geroutet werden. Pingpongpakete
haben auf einer ISDN-Leitung nichts verloren! (Und auch nirgends anders.)
Es fällt außerdem auf, daß ich nichts von routed und ähnlichen Programmen
gesagt habe. Das ist Absicht. Konfiguriert eure Routen lieber statisch,
@ -409,8 +442,8 @@ Alle Zeilentypen:
behandlung verpassen.
<Parameter...> ist eine Folge von einem oder mehr Parameter-Wert-Angaben.
(Manche Parameter haben keine Wertangabe.)
Merke: Zeilen ohne Parameter sind im allgemeinen nicht sinnvoll
und führen (momentan noch) zu Fehlverhalten des Treibers.
Merke: Zeilen ohne Parameter sind im allgemeinen nicht sinnvoll
und führen (momentan noch) zu Fehlverhalten des Treibers.
P-Zeile ("Protokoll")
@ -420,11 +453,7 @@ Form:
P <Art> <Partner> <Key> <Karte> <Mod> <Parameter...>
Beispiel:
P login * * R :sv 0700 :nr .2 :ea 2 :pr 0 :sp 65
Anderes Beispiel, mit derselben Wirkung:
P login * * R :sv 0700 :nr .2 :ea 2
P * * * MX :pr 0 :sp 65
P login * * R :sv 0700 :nr .2 :lr /2
Parameter:
:Ft Bei Festverbindungen angeben. (Erzwingt das Laden des
@ -437,6 +466,8 @@ Parameter:
Bei Festverbindungen wird dieser Parameter nicht benötigt.
:bc Zu verwendender B-Kanal, 1 oder 2. Nur für Festverbindungen
interessant; im normalen ISDN managt die Vermittlung B-Kanäle für uns.
:nj Kann der Ruf nicht angenommen werden, wird BUSY statt CallRejected
gesendet.
:xi Wenn ankommende und abgehende Anrufe kollidieren, soll der an-
kommende abgewiesen werden. (Default: Der abgehende Ruf wird
abgebrochen.) (Nicht allzu gut getestet.)
@ -478,8 +509,8 @@ Spezifisch f
Angaben lokale und
Mod:
R Die Zeile kann primär für einen Verbindungsaufbau verwendet werden.
M Die Zeile wird nur dann analysiert, wenn eine über ihr gefundene R-Zeile
R Die Zeile wird primär für einen Verbindungsaufbau verwendet.
M Die Zeile wird nur dann analysiert, wenn eine über ihr gefundene P-Zeile
"paßt".
X Wenn diese Zeile (oder eine darüberliegende) "paßt", wird das Scannen
nach weiteren passenden Angaben hier abgebrochen.
@ -603,8 +634,54 @@ DL Tel0 +49=911-34567. :pr 0 :sp 8 :pr 63
Beispiel Festverbindung:
DL Tel2 - :pr 64
Beispiel intelligente Karte mit CAPI:
DL Bin0 +49=911-45678. :pr 65
Bedeutung der Spezialzeichen in der Nummer: Siehe "DP" unten.
Protokolle und Flags in der DL-Zeile:
--------------------
Die Reihenfolge ist wichtig.
:pp Punkt-zu-Punkt-Verbindung, feste TEI (0x00). :kl ebenfalls
angeben!
:mp Verbindung am Bus, variabler TEI-Identifier. Bei manchen 1TR6-
Vermittlungen und Nebenstellenanlagen sinnvoll.
:mf Verbindung am Bus, fester TEI-Identifier. Default.
:mt Verbindung am Bus, feste TEI(0x12). In Spezialfällen notwendig.
:ud XX Verzögerung zwischen dem Verbindungsaufbau (D-Kanal) und dem
eigentlichen Datenaustausch (B-Kanal). Zehntelsekunden; max.
2 Sekunden; Default 1/4 Sekunde. Mit :ud 0 geht der Verbindungs-
aufbau entweder etwas schneller, oder das erste Paket wird
verschluckt, oder die Vermittlung kommt durcheinander und die
Verbindung ist tot. :-(
:pr 0 Normaler ISDN-D-Kanal, angeschlossen am Netz oder an einer
Telefonanlage. Darf nur zusammen mit TEI-Handler (:pr 63)
verwendet werden.
:kl Level-2-Verbindung zur Vermittlung nicht trennen. Bei Punkt-
zu-Punkt-Verbindungen und bei entsprechend konfigurierten
ISDN-Anschlüssen ("Dauer-irgendwas") notwendig.
:cl Level-2-Verbindung zur Vermittlung trennen. Default.
:sp 8 DSS1, Euro-ISDN.
:sp 65 1TR6, deutscher Standard.
:ai Ankommenden Anruf mit dem ISDN-Äquivalent von "RINGING"
beantworten, dann prüfen ob der Anruf angenommen werden kann.
Notwendig bei langsamen Rechnern.
:ad Ankommende Anrufe erst prüfen, dann annehmen (oder auch nicht).
Default.
:pr 63 TEI-Handler (Transport Endpoint Identifier).
:ti TEI sofort zuordnen lassen. Notwendig bei langsamen / sehr
beschäftigten Rechnern und bei manchen Telefonanlagen.
:td TEI beim ersten Verbindungsaufbau zuordnen lassen. Default.
:pr 64 Festverbindung: kein D-Kanal.
:pr 65 Intelligente Karte mit CAPI 1.x-Schnittstelle.
(Noch nicht!)
DP-Zeile ("Dial Prefix")
--------
@ -623,9 +700,13 @@ typischerweise eine vorgestellte Null o.
Gesprächen nicht mit angezeigt wird.
Die Zeichen sind immer "+" für internationale Verbindungen, "=" für
nationale Verbindungen, "-" für Ortsverbindungen und "." für Verbindungen
innerhalb einer Nebenstellenanlage. Außerdem gibt es noch "/" für EAZs etc.,
die bei externen Nummern verwendet werden können. Beispiel:
nationale Verbindungen, "-" für Ortsverbindungen, "." oder "/" für
Verbindungen innerhalb einer Nebenstellenanlage oder EAZs/MSNs etc. Der
Unterschied ist, daß Nummern einer Nebenstellenanlage direkt angerufen
werden können, während ich für eine Verbindung zu einer anderen MSN die
Teilnehmernummer mitwählen muß.
Beispiel: Eine Konfiguration
D ... -1234/[456]
DL... -23456
DP... -
@ -647,6 +728,10 @@ oder abgehenden Gespr
mit "R"-Zeile ist also direkt nicht möglich, da der Datenaustausch zum
betreffenden Programm geht.
Eine R-Zeile wird ignoriert, sobald das betreffende Programm einen Fehler
gemeldet hat (Exitstatus != 0) oder bei der Verbindungssteuerung ein Fehler
aufgetreten ist.
Im Environment dieses Programms werden folgende Variablen abgelegt:
SITE <Partner>
PROTOCOL <Art>
@ -662,6 +747,7 @@ Mod:
nach n Sekunden der Verbindungsaufbau wieder erlaubt. (Noch nicht
implementiert)
$ Die Befehlszeile wird nicht direkt ausgeführt, sondern der Shell übergeben.
E Beim Auftreten eines Fehlers wird dieses Programm deaktiviert.
D /dev/ttyiXX wird angelegt und nach Programmende gelöscht.
F Das Programm wird sofort gestartet, und die Verbindung wird aufgebaut.
Interessant insbesondere bei Festverbindungen und SPVs.
@ -678,7 +764,7 @@ f f
d für Wählverbindungen
p für Verbindungsaufbau nach Bedarf ("reconn"-Modul nicht vergessen!);
wird beim Programmstart automatisch mitgestartet. Die eigentliche
ISDN-Verbindung wird hierdurch _nicht_ aufgebaut, dafür ist "b" gedacht.
ISDN-Verbindung wird hierdurch _nicht_ aufgebaut, dafür ist "B" gedacht.
CM-Zeile ("Card Mode")
@ -737,6 +823,15 @@ Ueber das Limit hinausgehende Anrufe werden mit BUSY abgelehnt, es sei denn
in der entsprechenden P-Zeile steht der entsprechende Parameter.
LF-Zeile ("Load File")
--------
Form: LF <Karte> <Segmentgröße> <Dateiname>
Lädt die Datei auf die (aktive) Karte. Mehrere LF-Zeilen können angegeben
werden.
RP-Zeile ("Run Program")
--------
Noch nicht implementiert.
@ -758,11 +853,11 @@ Zus
unterhalb derer keine Uebertragung zugelassen wird, um in Gesprächspausen
die Rechnerlast zu senken.
:ro 0-127 Ansprechschwelle beim Empfang. Null schaltet permanent auf
"Durchgang".
:rx 0-127 Abschaltschwelle. Töne werden blockiert, wenn mehr als ..:
:rc 1-32767 aufeinanderfolgende Samples unterhalb der :rx-Schwelle liegen.
:xo :xx :xc wie :ro :rx :rc, aber für den Sendeteil.
:ro 0-127 Ansprechschwelle beim Empfang. Null schaltet permanent auf
"Durchgang".
:rx 0-127 Abschaltschwelle. Töne werden blockiert, wenn mehr als ..:
:rc 1-32767 aufeinanderfolgende Samples unterhalb der :rx-Schwelle liegen.
:xo :xx :xc wie :ro :rx :rc, aber für den Sendeteil.
Befehlsinterpreter "proto"
@ -830,8 +925,13 @@ Alle Zeitangaben sind in Sekunden.
:lo dto, bei abgehenden Verbindungen
:lb dto, beide Verbindungsarten (Default).
Vorsicht: Es macht keinen Sinn, den Timer unterhalb von übertragungssichernden
Modulen wie x.75 oder gar Datenstrom-Modulen wie v110 anzuordnen.
Vorsicht: Es macht absolut keinen Sinn, den Timer unterhalb von
übertragungssichernden Modulen wie x.75 oder gar Datenstrom-Modulen wie
v110 anzuordnen.
Der Timeout sollte mindestens dreimal so groß sein wie die Zeit, die
typischerweise zum Verbindungsaufbau benötigt wird, weil es sonst
scheußliche Interaktionen mit den TCP-Retryalgorithmen gebenb kann.
T.70 "t70"
@ -855,9 +955,9 @@ Van-Jacobsen-Kompression "vanj"
------------------------
Komprimiert TCP-IP-Header.
Sollte nur auf einer gesicherten Verbindung verwendet werden.
:ac Aktiv komprimieren. (Default bei abgehenden Verbindungen.)
:pa Komprimieren nur, nachdem ein komprimiertes Paket ankam.
(Default bei ankommenden Verbindungen.)
:ac Aktiv komprimieren. (Default bei abgehenden Verbindungen.)
:pa Komprimieren nur, nachdem ein komprimiertes Paket ankam.
(Default bei ankommenden Verbindungen.)
X.75 "x75"
@ -896,6 +996,12 @@ Interframezeichen etc.) wird von der Hardware auf der Karte erledigt.
4 wenn der erste Datenblock zur Übertragung ansteht.
8 gar nicht -- es werden UI-Frames verwendet.
pr_on
-----
Spezialmodul, um die "Verbindung hergestellt"-Kennung auf einem Stream
abzusenden, der nicht über ISDN arbeitet. Wird zB vom slipto-Programm
verwendet.
Verzeichnisstruktur der Sourcen
===================
@ -913,8 +1019,8 @@ ip_mon/ TCP/IP-Monitorprogramm nebst Streamstreiber/Modul.
isdn_2/ Schicht-2-Treiber für ISDN (D-Kanalsteuerung, B-Kanal-Routing).
isdn_3/ Schicht-3-Treiber (1TR6 etc.).
isdn_4/ Steuerprogramm (besagter wilder Hack).
ksupport/ Supportkram für den Kernel, diverse Streamsmodule.
strppp/ PPP-Supportmodul, unfertig
ksupport/ Supportkram für den Kernel, diverse Streamsmodule,
Supportcode für die ISDN-Protokollhandler.
reconnect/ Streamsmodul zum dynamischen Wiederaufbau einer Verbindung.
strslip/ Streamsmodul für SLIP-Framing.
str_if/ Streamsmodul für Anbindung an TCP/IP.
@ -970,38 +1076,36 @@ Kontrollprogramm f
"slip"-Modul via ML-Zeile explizit eingesetzt werden.
-d eine "Default"-Route zur Gegenseite wird eingerichtet.
-L Standleitungsbetrieb; protokolliert den Dialog zum Modem.
-l Debugging; setzt qinfo-Modul ein.
-l zusätzlich count-Modul.
-l zusätzlich strlog-Modul.
-M Standleitungsbetrieb; setzt IP-Monitor-Modul ein.
-S Standleitungs/Dialupbetrieb auf synchroner Leitung: verwende kein
"slip"-Modul.
-m mtu setzt die MTU auf den angegebenen Wert. (Die MRU ist auf 4000 Bytes
begrenzt.)
-o Standleitungsbetrieb; schickt ATA zur Leitung und wartet auf CONNECT.
-p dev Standleitungs- oder Dialupbetrieb; öffnet Device "dev". (/dev/tty
für stdin/out)
-v schaltet Van-Jacobsen-Headerkompression ein.
-f schaltet Cisco-HDLC-Header ein.
-R ip die IP-Nummer "ip" wird zur Gegenseite geroutet. (route -host)
-r ip Das IP-Netz "ip" wird zur Gegenseite geroutet. (route -net)
-r ip:nm Das IP-Netz "ip" wird mit der Netmask "nm" zur Gegenseite geroutet.
ip_loc lokale IP-Nummer.
Es muß sich dabei nicht unbedingt um die IP-Nummer handeln, die
die Gegenstelle von uns erwartet; es reicht, wenn die Gegenseite
die verwendete Nummer zu uns routet und die dort konfigurierte Nummer
lokal erkannt wird. Um das zu erreichen, ist der Befehl
% ifconfig lo0 alias <Erwartete_IP_Nr>
(BSD), bzw.
% ifconfig dummyX <IP-Nr> ; route add <IP-Nr>
(Linux) sehr hilfreich.
ip_rem IP-Nummer der Gegenstelle
Es muß sich dabei nicht unbedingt um die IP-Nummer handeln, die
die Gegenseite auf ihrem Interface konfiguriert hat; es reicht,
wenn es eine ist, die irgendwo am anderen Ende der Leitung existiert.
Solche 'wilden' Konfigurationen sollte man zwar vermeiden, aber...
Die folgenden Optionen werden _nicht_ im ISDN-Betrieb verwendet, sondern im
Standalonebetrieb mit anderen Streams-Treibern. Im ISDN-Betrieb müssen
stattdessen die entsprechenden Module auf der ML-Konfigurationszeile
eingetragen werden.
-L protokolliert den Dialog zum Modem.
-l Debugging: setzt qinfo-Modul ein.
-ll zusätzlich count-Modul.
-lll zusätzlich strlog-Modul.
-M setzt IP-Monitor-Modul ein.
-S Betrieb auf synchroner Leitung: verwende kein "slip"-Modul.
-E Autoenable; wenn slipto auf einer bestehenden Verbindung gestartet
wird.
-o schickt ATA zur Leitung und wartet auf CONNECT.
-p dev öffnet Device "dev". (Man verwende "/dev/tty" für stdin/out.)
-v verwende Van-Jacobsen-Headerkompression.
-f verwende Cisco-HDLC-Header.
Die folgenden Parameter müssen immer angegeben werden:
ip_loc lokale IP-Nummer.
Kann auch auf anderen Interfaces (Ethernet) verwendet werden!
ip_rem IP-Nummer der Gegenstelle.
Die beiden Nummern muessen nicht im gleichen Netz sein!
Hackers Corner
==============

View File

@ -1,17 +1,47 @@
all: isdn
# config and include are first, final is last
DIRS = config compat streams include bin support isdn_3 isdn_4 \
ksupport isdn_2 str_if van_j cards x75 alaw \
v110 pr_on strslip fakeh t70 rate timer reconnect ip_mon final
ADIRS = config include bin support isdn_3 isdn_4 str_if ip_mon alaw tools
KDIRS = config compat streams include ksupport isdn_2 str_if van_j cards x75 \
alaw v110 pr_on strslip fakeh t70 rate timer reconnect ip_mon final
# dumbmgr portman port_m
isdn: dummy
make -C isdn
SYSTEMS = linux
#SYSTEMS = aux sco svr4 linux
depend dep:
make -C isdn depend
all prog:: .depend
load:
make -C isdn load
.depend:
make depend
touch .depend
clean:
make -C isdn clean
-rm .toldem
all update load::
set -e;for i in $(KDIRS);do echo "make $@ in $$i:" && make -C $$i $@ ; done
prog::
set -e;for i in $(ADIRS);do echo "make $@ in $$i:" && make -C $$i $@ ; done
depend clean indent::
set -e;for i in $(DIRS);do echo "make $@ in $$i:" && make -C $$i $@ ; done
install: all
make -C final doinstall
conf:
cd config ; make
clean::
@for i in $(ALLDIRS) ; do ( cd $$i; \
for j in $(SYSTEMS) ; do echo $$i/$$j ; \
sh ../iftrue.sh "-d $$j" "cd $$j ; make clean" ; done \
) ; done
find . -name .depend -print|xargs rm -f
iprog: prog
cd final && make install.bin
dep: depend
dummy:

153
README Normal file
View File

@ -0,0 +1,153 @@
[ This is a German version. An English version is in the works. ]
Die Anleitung und der ganze Kram findet sich in der Datei DOKU, oder
README.isdn in den Kernelsourcen.
*** 1995-09-31
Release 13.
Wenn es immer noch Probleme beim ISDN-Login gibt: am Anfang von
streams/streams_io das #undef in ein #define ändern, isdn_2.o mit
"mod2=0x05" installieren, nochmal testen, mir den Syslog-Output schicken
(*.debug, NICHT *.=debug !!!). Vorsicht, Paßwörter etc. stehen in diesem
Log mit drin!
Wegen eines Fehlers im GNU-Make kann es passieren, daß "make" oder "make -w"
nicht funktioniert. In diesem Fall "make --warn" verwenden.
Die folgenden neuen Features sind noch mehr oder weniger ungetestet:
SIGIO-Support.
TTY-Code repariert.
Starten beliebiger Programme bei Zustandsänderungen (RP-Zeile in der Konfig).
Ethertype-Support (noch nicht vollständig).
Callback wenn möglich auf derselben Leitung.
Callback auf Leitung B, wenn ein Ruf auf A ankommt, dort aber besetzt ist.
Einigermaßen getestet:
Callback. (War das ein Nerv. Manche ISDN-Vermittlungen sind _doof_.)
Fehlermeldungen reorganisiert.
*** 1995-07-22
isdn_4/master.c aufgesplittet, Verzeichnisstruktur leicht umgebaut,
deshalb leider keine Diffs.
*** 1995-06-12
Wieder ein paar Bugs weniger.
Der "arnet"-Treiber ist fuer die synchronen Karten dieser Firma gedacht und
noch nicht 100% ausgetestet.
Wenn jemand Uebermittlung von Gebuehreninformationen waehrend der
Verbindung im Euro-ISDN aktiviert hat -> Mail an mich.
Support fuer Standleitungen: Restart klemmt manchmal.
Die Patches basieren auf aelteren Kernelversionen und sind nicht besonders
sauber...
Support fuer Kernel 1.3 ist in Arbeit.
*** 1995-02-04
Euro-ISDN! Relativ rudimentär, sollte aber erstmal tun.
(In der Doku steht was von FINGER WEG. Vorsicht -- ich garantiere nicht,
daß sich der Kram nicht total danebenbenimmt. Ich wage es aber zu
bezweifeln, daß mein Treiber dazu führt, daß der Anschluß gesperrt wird...)
Support für 128kBit-Standleitungen.
rm -rf streams/isdn isdn/cards/leonardo (für Leute, die den Patch
verwenden).
*** 1995-01-18
Na endlich... modularisierte Version, basierend auf 1.1.83.
_Ohne_ Spezialkram (OK, ein kleines bißchen ;-) nachdem das Linux-TCP/IP
endlich einen brauchbaren Status erreicht zu haben scheint.
*** 1994-10-27
Interimsrelease, basierend auf 1.1.57.
In libc.tar.gz beginden sich die letzten 4.5.26-Libraries und Include-
dateien, angepaßt auf meinen Kernel. (Die nächste Version, basierend auf
4.6.xx, ist weit weniger schlimm.)
In kernel.tar.gz sind die Quellen fuer den angepassten Kernel, komplett.
Konfiguration:
CONFIG_SCHEDULER_BSD Y
CONFIG_INET_BSD N
CONFIG_MALLOC_TRACE Y
CONFIG_DEBUG_LATENCY N
Alles andere (fast) wie gewohnt. Ohne MALLOC-TRACE gibt es Probleme mit
der Speicherverwaltung; wenn jemand den Fehler findet, immer nur her mit
einem Patch.
INET_BSD braucht BSD-Utilities für die Konfiguration, die ich momentan
nicht im Source habe (Plattenfehler).
Die Übersetzung des Streams-Teils liefert haufenweise Warnings; ignorieren.
*** 1994-08-07
Die Datei /usr/include/sys/conf.h muss die folgende Zeile enthalten:
#include <linux/config.h>
Sorry; dieser Fehler wird mit dem naechsten Update behoben.
*** 1994-08-03
Patch 38 passt sauber in den Kern.
Festverbindungen tun; Patch (inkl. Update auf -38) folgt demnaechst.
*** 1994-08-01
CONFIG_MALLOC_TRACE funktioniert nicht korrekt (Speicherverluste). Ich
arbeite dran.
*** 1994-07-31
Festverbindungen werden unterstützt.
Diffs auf PL37 generiert.
Networking-Code generiert.
include- und libc-Diffs generiert.
*** 1994-07-29
In der Datei streams/isdn/config/config.data muss die Variable STR_IN von
"in2" auf "linux" geaendert werden, wenn mit Linux-Networking gearbeitet
werden soll.
*** 1994-07-27
Patch 36 läßt sich problemlos einspielen.
*** 1994-07-26
Die Datei "kernel-1.1.35.diff.gz" enthält die Diffs zu meinem Kernel.
"streams-1.1.35.tar.gz" enthält den Streams-Teil (notwendig!).
Warnung: Da ich selber leicht modifizierte Includedateien unter
/usr/include einsetze, kann es sein, daß die Kompilation nicht
durchläuft... in diesem Fall bitte Mail an mich.

View File

@ -1,5 +1,5 @@
Euro-ISDN
Hauptprogramm gewaltig aufraeumen
PPP einbauen.
Hauptprogramm weiter aufraeumen
Protokollstack vom Hauptmodul aus aufbauen
Anklinken anderer Treiber (intelligente ISDN-Karten, serielle Schnittstellen)
Mehr Features fuer 1TR6
@ -9,7 +9,6 @@ proto-Treiber um Signalisierung erweitern
DOKU verbessern (jaja...)
Bekannte Fehler:
Gelegentlich vergisst das System, eine L3-Connection freizugeben
Das Handling von knappen Streams-Datenbloecken ist verbesserungsbeduerftig.
Moegliche Probleme:

View File

@ -4,15 +4,15 @@ MAKE = make
P =
## =()<CCU = @<CCU>@>()=
CCU = gcc-elf -g
CCU = gcc
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
## =()<DEFSN = @<DEFS>@ >()=
DEFSN = -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd
DEFSN = -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd
## =()<NCFLAGS = @<CFLAGS>@ $(DEFSN)>()=
NCFLAGS = -O2 -Wall $(DEFSN)
## =()<LIBS = @<LIBS>@>()=
@ -57,7 +57,7 @@ clean:
depend: Makefile $(SOURCES)
$(CC) -M $(DEFS) $(SOURCES) > .depend
load: all
load:
insmod alaw.o
ifeq (.depend,$(wildcard .depend))

View File

@ -27,12 +27,7 @@
/*
* Standard Streams stuff.
*/
static struct module_info alaw_minfo_w =
{
0, "alaw", 0, INFPSZ, 4000, 1000
};
static struct module_info alaw_minfo_r =
static struct module_info alaw_minfo =
{
0, "alaw", 0, INFPSZ, 10000, 2000
};
@ -44,12 +39,12 @@ static qf_srv alaw_rsrv, alaw_wsrv;
static struct qinit alaw_rinit =
{
alaw_rput, alaw_rsrv, alaw_open, alaw_close, NULL, &alaw_minfo_r, NULL
alaw_rput, alaw_rsrv, alaw_open, alaw_close, NULL, &alaw_minfo, NULL
};
static struct qinit alaw_winit =
{
alaw_wput, alaw_wsrv, NULL, NULL, NULL, &alaw_minfo_w, NULL
alaw_wput, alaw_wsrv, NULL, NULL, NULL, &alaw_minfo, NULL
};
struct streamtab alawinfo =
@ -91,9 +86,10 @@ alaw_proto (queue_t * q, mblk_t * mp)
struct alaw_ *alaw = (struct alaw_ *) q->q_ptr;
streamchar *origmp = mp->b_rptr;
ushort_t id;
int error = 0;
/* In case we want to printf("%s") this... */
if (mp->b_wptr < mp->b_datap->db_lim)
if (mp->b_wptr < DATA_END(mp))
*mp->b_wptr = '\0';
if (m_getid (mp, &id) != 0) {
mp->b_rptr = origmp;
@ -107,53 +103,50 @@ alaw_proto (queue_t * q, mblk_t * mp)
while (mp != NULL && m_getsx (mp, &id) == 0)
switch (id) {
err:
printf (" :Err %s\n", mp->b_rptr);
mp->b_rptr = origmp;
freemsg (mp);
mp = NULL;
default:
goto err;
case PROTO_MODULE:
break;
case ALAW_LAW:
printf ("ALAW: Only A-Law supported\n");
goto err;
case ALAW_RVCO_ON:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 0 || z > 127)
goto err;
alaw->r.on = z;
break;
case ALAW_RVCO_OFF:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 0 || z > 127)
goto err;
alaw->r.off = z;
break;
case ALAW_RVCO_CNT:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 50 || z > 65535)
goto err;
alaw->r.count = z;
break;
case ALAW_XVCO_ON:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 0 || z > 127)
goto err;
alaw->w.on = z;
break;
case ALAW_XVCO_OFF:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 0 || z > 127)
goto err;
alaw->w.off = z;
break;
case ALAW_XVCO_CNT:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 50 || z > 65535)
goto err;
@ -173,6 +166,10 @@ alaw_proto (queue_t * q, mblk_t * mp)
mp->b_rptr = origmp;
putnext (q, mp);
}
return;
err:
mp->b_rptr = origmp;
m_reply (q, mp, error ? error : -EINVAL);
}
@ -205,7 +202,7 @@ alaw_mute (mblk_t * mb, struct _vco *vco)
if (mz != NULL) {
short sz;
mz->b_datap->db_type = mb->b_datap->db_type;
DATA_TYPE(mz) = DATA_TYPE(mb);
bcopy (mb->b_rptr, mz->b_wptr, (sz = blkend - (uchar_t *) mb->b_rptr));
mz->b_wptr += sz;
@ -282,17 +279,13 @@ static char cswap[256] =
/* Streams code to open the driver. */
static int
alaw_open (queue_t * q, dev_t dev, int flag, int sflag
#ifdef DO_ADDERROR
,int *err
#endif
)
alaw_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
{
register struct alaw_ *alaw;
alaw = malloc(sizeof(*alaw));
if(alaw == NULL)
return OPENFAIL;
ERR_RETURN(-ENOMEM);
memset(alaw,0,sizeof(*alaw));
WR (q)->q_ptr = (char *) alaw;
@ -301,9 +294,6 @@ alaw_open (queue_t * q, dev_t dev, int flag, int sflag
alaw->q = q;
alaw__init (alaw);
if (0)
printf ("ALAW pseudo-driver %d opened.\n", dev);
MORE_USE;
return 0;
}
@ -318,8 +308,7 @@ alaw_close (queue_t * q, int dummy)
flushq (q, FLUSHALL);
flushq (WR (q), FLUSHALL);
if (0)
printf ("ALAW driver closed.\n");
free(alaw);
LESS_USE;
return;
@ -330,20 +319,18 @@ alaw_close (queue_t * q, int dummy)
static void
alaw_wput (queue_t * q, mblk_t * mp)
{
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
CASE_DATA
case CASE_DATA:
putq (q, mp);
break;
case M_FLUSH:
if (*mp->b_rptr & FLUSHW)
flushq (q, FLUSHDATA);
/* FALL THRU */
default:
putnext (q, mp);
break;
default:{
putnext (q, mp);
break;
}
}
return;
}
@ -356,11 +343,12 @@ alaw_wsrv (queue_t * q)
mblk_t *mp;
while ((mp = getq (q)) != NULL) {
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
alaw_proto (q, mp);
break;
CASE_DATA {
case CASE_DATA:
{
mblk_t *mr;
if (!canput (q->q_next)) {
@ -388,7 +376,7 @@ alaw_wsrv (queue_t * q)
flushq (q, FLUSHDATA);
/* FALL THRU */
default:
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
putnext (q, mp);
continue;
} else {
@ -404,7 +392,7 @@ alaw_wsrv (queue_t * q)
static void
alaw_rput (queue_t * q, mblk_t * mp)
{
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case M_FLUSH:
if (*mp->b_rptr & FLUSHR) {
@ -413,7 +401,7 @@ alaw_rput (queue_t * q, mblk_t * mp)
putnext (q, mp); /* send it along too */
break;
case MSG_PROTO:
CASE_DATA
case CASE_DATA:
putq (q, mp); /* queue it for my service routine */
break;
@ -433,11 +421,12 @@ alaw_rsrv (queue_t * q)
register struct alaw_ *alaw = (struct alaw_ *) q->q_ptr;
while ((mp = getq (q)) != NULL) {
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
alaw_proto (q, mp);
break;
CASE_DATA {
case CASE_DATA:
{
mblk_t *mr;
if (!canput (q->q_next)) {
@ -459,12 +448,13 @@ alaw_rsrv (queue_t * q)
}
if ((mr = alaw_mute (mp, &alaw->r)) != NULL)
putnext (q, mr);
} break;
}
break;
case M_HANGUP:
case M_ERROR:
/* FALL THRU */
default:
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
putnext (q, mp);
continue;
} else {

0
isdn/alaw/toalaw.c → alaw/toalaw.c Executable file → Normal file
View File

0
isdn/alaw/toalaw.pl → alaw/toalaw.pl Executable file → Normal file
View File

0
isdn/alaw/tosnd.c → alaw/tosnd.c Executable file → Normal file
View File

0
isdn/alaw/tosnd.pl → alaw/tosnd.pl Executable file → Normal file
View File

4
isdn/bin/Makefile → bin/Makefile Executable file → Normal file
View File

@ -4,6 +4,7 @@ all prog:
rm -f slipto; ln -s ../str_if/slipto .
rm -f toalaw; ln -s ../alaw/toalaw .
rm -f tosnd; ln -s ../alaw/tosnd .
rm -f cardname; ln -s ../tools/cardname .
clean:
rm -f master
@ -11,7 +12,8 @@ clean:
rm -f slipto
rm -f toalaw
rm -f tosnd
rm -f cardname
install update depend indent load:
echo "Nothing to be done."
@echo "Nothing to be done."

3
isdn/bin/catfone → bin/catfone Executable file → Normal file
View File

@ -35,7 +35,8 @@ if test -d $in ; then
done
thefile=$in/$pid.$file
cd ..
tee $thefile | ( set +e; tosnd 3 mac.smurf.noris.de ; cat >/dev/null )
cat > $thefile
#tee $thefile | ( set +e; tosnd 3 mac.smurf.noris.de ; cat >/dev/null )
if test -s $thefile ; then
echo "Phone call: $thefile" | mail -s "Phone call" $(ls -l $thefile|awk '{print $3;}' )
else

0
isdn/bin/tester → bin/tester Executable file → Normal file
View File

5
cards/Makefile Normal file
View File

@ -0,0 +1,5 @@
## =()<CARDS = @<CARDS>@>()=
CARDS = dumb
all lib clean depend install update indent load:
@set -e; for i in $(CARDS) ; do $(MAKE) $(MAKEFLAGS) -C $$i $@ ; done

View File

@ -5,8 +5,8 @@ P =
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
## =()<DEFS = @<DEFCARDS>@ @<KERNEL>@ -I../../include >()=
DEFS = -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../../include
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
## =()<RANLIB = @<RANLIB>@>()=
@ -34,7 +34,7 @@ indent:
depend: Makefile $(SOURCES)
$(CC) -M $(DEFS) $(SOURCES) > .depend
load: all
load:
insmod arnet.o
ifeq (.depend,$(wildcard .depend))

2
cards/arnet/README Normal file
View File

@ -0,0 +1,2 @@
Diese "arnet"-Karten sind keine ISDN-Karten, sondern Karten mit synchronen
seriellen Ports und einem Haufen RAM, um on-board-DMA zu machen.

View File

@ -1339,8 +1339,8 @@ arnet_init1(struct arnet_info *arn)
uchar_t inb3, inb4, inb5, inb6, inbc;
unsigned short x;
struct arnet_port *arp;
ldprintf(".%d.",__LINE__);
printf("AR: ");
printf("Arnet: ");
arn->usage = 99;
bzero(&arn->queue,sizeof(arn->queue));
@ -1359,12 +1359,10 @@ ldprintf(".%d.",__LINE__);
printf("*** region 0x%x..0x%x blocked\n",arn->ioaddr,arn->ioaddr+15);
return 0;
}
request_region(arn->ioaddr,16,"arnet");
arn->memsize = 1<<(((inb3&0x1C)>>2)+16);
printf("cf %02x: %d kByte, memory at %p, bus %d, adapter %s; %d ports; rev %02x; ", inb3, arn->memsize>>10, arn->membase, inb3&3, astr(inb3>>5), inb5, inb4);
if((unsigned long)arn->membase & 0xFF003FFF) {
printf("*** invalid membase: 0x%p\n",arn->membase);
release_region(arn->ioaddr,16);
return 0;
}
{
@ -1379,6 +1377,10 @@ ldprintf(".%d.",__LINE__);
}
arn->nports = inb5;
if(arn->nports != 2 && arn->nports != 4) {
printf("huh? card with %d ports?\n",arn->nports);
return 0;
}
arn->handshake = inb6;
if(inb6 == 0)
printf("no control/status lines; ");
@ -1420,12 +1422,6 @@ ldprintf(".%d.",__LINE__);
case 15: inbc = 7; break;
default:
printf("*** unknown IRQ %d\n",arn->irq);
release_region(arn->ioaddr,16);
return 0;
}
if((arn->irq != 0) && request_irq(arn->irq,arnet_intr,0 /* SA_INTERRUPT */,"arnet")) {
printf("*** IRQ %d not available\n",arn->irq);
release_region(arn->ioaddr,16);
return 0;
}
inbc <<= 1;
@ -1459,29 +1455,27 @@ ldprintf(".%d.",__LINE__);
if(MEM(char,arn,0x33) != 0xAA) {
if((arn->nports <= 2) || (MEM(char,arn,0x33) != 0x5A)) {
printf("ERROR: Readback A, %02x\n", MEM(char,arn,0x33));
goto GetOut;
return 0;
}
printf("ERROR: second chip unselectable A, %02x\n", MEM(char,arn,0x33));
arn->nports -= 1;
return 0;
}
if(MEM(char,arn,0x53) != 0x55) {
if((arn->nports <= 2) || (MEM(char,arn,0x53) != 0xA5)) {
printf("ERROR: Readback B, %02x\n", MEM(char,arn,0x53));
goto GetOut;
return 0;
}
printf("ERROR: second chip unselectable B, %02x\n", MEM(char,arn,0x53));
arn->nports -= 1;
return 0;
}
if(arn->nports == 3)
arn->nports --;
if(arn->nports > 2) {
arnet_page(arn,ADDR_SCA1);
if(MEM(char,arn,0x33) != 0x5A) {
printf("ERROR: Readback C, %02x\n", MEM(char,arn,0x33));
arn->nports -= 2;
return 0;
} else if(MEM(char,arn,0x53) != 0xA5) {
printf("ERROR: Readback D, %02x\n", MEM(char,arn,0x53));
arn->nports -= 2;
return 0;
}
}
@ -1494,15 +1488,14 @@ ldprintf(".%d.",__LINE__);
MEM(char,arn,0x53) = 0xFF;
}
if((arn->irq != 0) && request_irq(arn->irq,arnet_intr,0 /* SA_INTERRUPT */,"arnet")) {
printf("*** IRQ %d not available\n",arn->irq);
return 0;
}
request_region(arn->ioaddr,16,"arnet");
printf("\n");
arn->usage = 0;
return 1;
GetOut:
if(arn->irq != 0)
free_irq(arn->irq);
release_region(arn->ioaddr,16);
return 0;
}
static int
@ -1542,14 +1535,7 @@ ddprintf("l ");
/* Streams code to open the driver. */
static int
arnet_open (queue_t * q, dev_t dev, int flag, int sflag
#ifdef DO_ADDERROR
,int *err
#define U_ERROR *err
#else
#define U_ERROR u.u_error
#endif
)
arnet_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
{
struct arnet_info *arn = arnet_list;
struct arnet_port *arp;
@ -1567,8 +1553,7 @@ ddprintf("n ");
mdev --;
}
if(mdev == 0) {
U_ERROR = ENXIO;
return OPENFAIL;
ERR_RETURN(-ENXIO);
}
arn->usage++;
arp = &arn->port[cdev];
@ -1593,8 +1578,7 @@ ddprintf("n ");
q->q_ptr = NULL;
WR(q)->q_ptr = NULL;
arp->q = NULL;
U_ERROR = -err;
return OPENFAIL;
ERR_RETURN(err);
}
arn->usage = 0;
if(0)arnet_memdump(arn,"Open");
@ -1657,9 +1641,9 @@ ldprintf(".%d.",__LINE__);
freemsg(mp);
return;
}
switch (mp->b_datap->db_type) {
switch (DATATYPE(mp)) {
case M_IOCTL:
mp->b_datap->db_type = M_IOCNAK;
DATA_TYPE(mp) = M_IOCNAK;
((struct iocblk *)mp->b_rptr)->ioc_error = EINVAL;
qreply (q, mp);
break;
@ -1679,7 +1663,7 @@ ldprintf(".%d.",__LINE__);
break;
default:
log_printmsg (NULL, "Strange ARNET", mp, KERN_WARNING);
/* putctl1(RD(q)->b_next, M_ERROR, ENXIO); */
/* putctl1(RD(q)->b_next, M_ERROR, -ENXIO); */
freemsg (mp);
break;
}
@ -1767,7 +1751,7 @@ if(dodebug>1)ddprintf("q ");
freemsg (mp);
continue;
}
if (mp->b_datap->db_type >= QPCTL || canput (q->q_next)) {
if (DATA_TYPE(mp) >= QPCTL || canput (q->q_next)) {
putnext (q, mp);
continue;
} else {

BIN
cards/capi/bintec/boot.68k Executable file

Binary file not shown.

BIN
cards/capi/bintec/bri.68k Executable file

Binary file not shown.

93
cards/dumb/Makefile Normal file
View File

@ -0,0 +1,93 @@
SHELL = /bin/sh
MAKE = make
## =()<P = @<P>@>()=
P =
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFCARDS>@ @<KERNEL>@ -I../../include >()=
DEFS = -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../../include
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
## =()<LD = @<LD>@>()=
LD = ld
## =()<DUMBCARDS = @<DUMBCARDS>@>()=
DUMBCARDS = teles
## =()<SYS = @<SYS>@>()=
SYS = linux
SOURCES = avm_io.c bsc_io.c teles_io.c ncp_io.c ncp16_io.c shell.c insert.c
OBJ =
ALL = teles.o avm.o bsc.o ncp.o ncp16.o \
d_teles.o d_avm.o d_bsc.o d_ncp.o d_ncp16.o
all: $(foreach c,${DUMBCARDS},$c.o) $(foreach c,${DUMBCARDS},d_$c.o)
load: $(foreach c,${DUMBCARDS},ins-$c)
avm.o: insert.c
$(CC) $(CFLAGS) -DCARDTYPE=avm -o avm.o -c insert.c
bsc.o: insert.c
$(CC) $(CFLAGS) -DCARDTYPE=bsc -o bsc.o -c insert.c
ncp16.o: insert.c
$(CC) $(CFLAGS) -DCARDTYPE=ncp16 -o ncp16.o -c insert.c
ncp.o: insert.c
$(CC) $(CFLAGS) -DCARDTYPE=ncp -o ncp.o -c insert.c
teles.o: insert.c
$(CC) $(CFLAGS) -DCARDTYPE=teles -o teles.o -c insert.c
d_avm.o: shell.c avm_io.c
$(CC) $(CFLAGS) -D_avm_ -o d_avm.o -c shell.c
d_bsc.o: shell.c bsc_io.c
$(CC) $(CFLAGS) -D_bsc_ -o d_bsc.o -c shell.c
d_ncp16.o: shell.c ncp16_io.c
$(CC) $(CFLAGS) -D_ncp16_ -DWIDE -o d_ncp16.o -c shell.c
d_ncp.o: shell.c ncp_io.c
$(CC) $(CFLAGS) -D_ncp_ -o d_ncp.o -c shell.c
d_teles.o: shell.c teles_io.c
$(CC) $(CFLAGS) -D_teles_ -o d_teles.o -c shell.c
ins-avm:
insmod d_avm.o
insmod avm.o
ins-bsc:
insmod d_bsc.o
insmod bsc.o
ins-teles:
insmod d_teles.o
insmod teles.o
ins-ncp:
insmod d_ncp.o
insmod ncp.o
ins-ncp16:
insmod d_ncp16.o
insmod ncp16.o
lib:
indent:
../../indent.sh $(SOURCES)
depend: Makefile $(SOURCES)
cp /dev/null .depend
for i in avm ncp teles bsc ; do $(CC) -D_$${i}_ -M $(DEFS) shell.c |\
sed -e "s/shell\.o/X$${i}.o/" >> .depend ; done
clean:
rm -f $(OBJ) $(ALL)
install: all
@sh ../../iftrue.sh "-d $(SYS)" "cd $(SYS); make"
update: all
@sh ../../iftrue.sh "-d $(SYS)" "cd $(SYS); make update"
ifeq (.depend,$(wildcard .depend))
include .depend
endif

View File

@ -50,6 +50,9 @@ static int Init(struct _dumb * dumb) {
Byte foo;
unsigned int step = 0;
if(dumb->ioaddr == 0)
return -EINVAL;
dumb->numHSCX = 2;
save_flags(flags);
sti();
timout = jiffies+1;
@ -104,7 +107,7 @@ static int Init(struct _dumb * dumb) {
default:
def:
printf(" AIRQR %02x, step %d ",foo,step);
return 0;
return -EIO;
}
}
Exit:
@ -121,7 +124,7 @@ static int Init(struct _dumb * dumb) {
ByteOut(dumb->ioaddr+0x1800,0x04);
ByteOut(dumb->ioaddr+0x1800,0x08);
return 1;
return 0;
}
static void InitISAC(struct _dumb * dumb)

View File

@ -28,6 +28,9 @@ static int Init(struct _dumb * dumb) {
int timout;
long flags;
if(dumb->ioaddr == 0)
return -EINVAL;
dumb->numHSCX = 2;
save_flags(flags);
timout = jiffies+(HZ/20)+1;
ByteOut(dumb->ioaddr,0x80);
@ -37,7 +40,7 @@ static int Init(struct _dumb * dumb) {
timout = jiffies+(HZ/20)+1;
while(jiffies <= timout) ;
restore_flags(flags);
return 1;
return 0;
}
static void InitISAC(struct _dumb * dumb)
{

56
cards/dumb/insert.c Normal file
View File

@ -0,0 +1,56 @@
#include "f_module.h"
#include "isdn_limits.h"
#include <stddef.h>
#ifdef linux
#include <linux/sched.h>
#endif
#include "shell.h"
#ifndef CARDTYPE
#error "You have to define CARDTYPE for this to work."
#endif
#define xxappxx(a,b) a##b
#define NAME(a,b) xxappxx(a,b) /* isn't C wonderful */
#define xxstrxx(a) #a
#define STRING(a) xxstrxx(a) /* ditto */
extern int NAME(CARDTYPE,init)(struct _dumb *dumb);
extern void NAME(CARDTYPE,exit)(struct _dumb *dumb);
struct _dumb dumb;
int irq = 0;
int mem = 0;
int io = 0;
int ipl = 0;
int name = 0;
int debug = 0;
#ifdef MODULE
static int do_init_module(void)
{
if(name == 0) {
printf("You must name this card: insmod xxx.o name=$(name Foo0)\n");
return -EINVAL;
}
dumb.irq = irq;
dumb.ipl = ipl;
dumb.ioaddr = io;
dumb.memaddr = mem;
dumb.ID = name;
dumb.debug = debug;
return NAME(CARDTYPE,init)(&dumb);
}
static int do_exit_module(void)
{
NAME(CARDTYPE,exit)(&dumb);
return 0;
}
#else
#error "This can only be used as a module!"
#endif

View File

@ -30,6 +30,9 @@ static int Init(struct _dumb * dumb) {
long flags;
char iflag;
if(dumb->ioaddr == 0)
return -EINVAL;
dumb->numHSCX = 2;
save_flags(flags);
timout = jiffies+(HZ/20)+1;
ByteOut(dumb->ioaddr,0xF0);
@ -43,7 +46,7 @@ static int Init(struct _dumb * dumb) {
case 0: break;
default:
printf (" unknown card code %d ",ByteIn(dumb->ioaddr) >> 5);
return 0;
return -ENXIO;
}
switch(dumb->irq) {
case 3: iflag = 0; break;
@ -57,10 +60,10 @@ static int Init(struct _dumb * dumb) {
case 0: iflag = 7; break;
default:
printf (" impossible irq %d ",dumb->irq);
return 0;
return -EINVAL;
}
ByteOut(dumb->ioaddr,(iflag<<5));
return 1;
return 0;
}
static void InitISAC(struct _dumb * dumb)

View File

@ -29,6 +29,9 @@ static int Init(struct _dumb * dumb) {
long flags;
char iflag;
if(dumb->ioaddr == 0)
return -EINVAL;
dumb->numHSCX = 2;
save_flags(flags);
timout = jiffies+(HZ/20)+1;
ByteOut(dumb->ioaddr,0xF0);
@ -42,7 +45,7 @@ static int Init(struct _dumb * dumb) {
case 0: break;
default:
printf (" unknown card code %d ",ByteIn(dumb->ioaddr) >> 5);
return 0;
return -EIO;
}
switch(dumb->irq) {
case 3: iflag = 0; break;
@ -55,10 +58,10 @@ static int Init(struct _dumb * dumb) {
case 0: iflag = 7; break;
default:
printf (" impossible irq %d ",dumb->irq);
return 0;
return -EINVAL;
}
ByteOut(dumb->ioaddr,(iflag<<5));
return 1;
return 0;
}
static void InitISAC(struct _dumb * dumb)

View File

@ -31,7 +31,6 @@ ADF1 00
MOCR 00
SQXR 20
CMDR 41
*/
#ifdef linux
#define SLOW_IO_BY_JUMPING
@ -46,6 +45,7 @@ CMDR 41
#include "isdn_12.h"
#include "smallq.h"
#include "isdn_limits.h"
#include "isdn_proto.h"
#include <sys/stream.h>
#include "streamlib.h"
#include <sys/errno.h>
@ -85,7 +85,7 @@ CMDR 41
#define FIFO(x) fifo[(x,0)] /* keep side effects but address at offset zero */
#include "Config.h"
#include "shell.h"
typedef struct _isac {
union {
@ -200,6 +200,8 @@ typedef struct _hscx {
#include "teles_io.c"
#endif
#define DUMBTIME 300 /* poll: times per second */
#define xxappxx(a,b) a##b
@ -212,6 +214,12 @@ void NAME(CARDTYPE,poll)(struct _dumb *dumb);
void NAME(CARDTYPE,poll)(void *);
#endif
static struct _dumb *dumbmap[16] = { NULL, };
static void toggle_off(struct _dumb * dumb)
{
int i;
@ -240,8 +248,8 @@ static void toggle_on(struct _dumb * dumb)
ByteOutISAC(dumb,MASK,0x00);
}
static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
char listen)
static int
dumb_mode (struct _isdn1_card * card, short channel, char mode, char listen)
{
struct _dumb * dumb = (struct _dumb *) card;
unsigned long ms = SetSPL(dumb->ipl);
@ -249,7 +257,7 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
switch(channel) {
case 0:
DEBUG(info) printf(KERN_INFO "ISDN%d ISAC %s<%d>%s\n",dumb-dumbdata,mode?(mode==1?"standby":"up"):"down",mode,listen?" listen":"");
DEBUG(info) printf(KERN_INFO "ISDN ISAC %s<%d>%s\n",mode?(mode==1?"standby":"up"):"down",mode,listen?" listen":"");
ISAC_mode(dumb,mode,listen);
if(mode == M_OFF) {
int j;
@ -259,12 +267,12 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
break;
default:
if(channel > 0 && channel <= dumb->numHSCX) {
DEBUG(info) printf(KERN_INFO "ISDN%d HSCX%d %s<%d>%s\n",dumb-dumbdata,channel,mode?"up":"down",mode,listen?" listen":"");
DEBUG(info) printf(KERN_INFO "ISDN HSCX%d %s<%d>%s\n",channel,mode?"up":"down",mode,listen?" listen":"");
err = HSCX_mode(dumb,channel,mode,listen);
if (err < 0) {
printf(KERN_WARNING "ISDN err %d %d\n",channel, err);
splx(ms);
return -err;
return err;
}
dumb->chan[channel].nblk = 0;
@ -273,7 +281,7 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
} else {
printf(KERN_WARNING "ISDN badChan %d\n",channel);
splx(ms);
return EINVAL;
return -EINVAL;
}
}
NAME(CARDTYPE,poll)(dumb);
@ -281,15 +289,50 @@ static int dumb_mode (struct _isdn1_card * card, short channel, char mode,
return err;
}
static int dumb_prot (struct _isdn1_card * card, short channel, mblk_t * proto)
static int
dumb_prot (struct _isdn1_card * card, short channel, mblk_t * mp, int flags)
{
return EINVAL;
struct _dumb * dumb = (struct _dumb *)card;
streamchar *origmp = mp->b_rptr;
ushort_t id;
int error = 0;
DEBUG(info)printf("Prot chan %d flags 0%o\n",channel,flags);
if(!(flags & ~CHP_FROMSTACK)) {
if ((error = m_getid (mp, &id)) != 0)
goto err;
switch (id) {
default:
break;
case PROTO_OFFSET:
{
long z;
if ((error = m_geti (mp, &z)) != 0)
goto err;
if (z < 0 || z >= 1024) {
error = -EINVAL;
goto err;
}
if(flags & CHP_FROMSTACK) /* down */
dumb->chan[channel].offset = z;
}
break;
}
}
err:
if(mp != NULL) {
if (origmp != NULL)
mp->b_rptr = origmp;
}
return (error ? error : isdn2_chprot(card,channel,mp,flags));
}
/*
* Check if buffer space is available
*/
static int dumb_candata (struct _isdn1_card * card, short channel)
static int
dumb_candata (struct _isdn1_card * card, short channel)
{
struct _dumb * dumb = (struct _dumb *)card;
return (dumb->chan[channel].q_out.nblocks < 4);
@ -298,7 +341,8 @@ static int dumb_candata (struct _isdn1_card * card, short channel)
/*
* Enqueue the data.
*/
static int dumb_data (struct _isdn1_card * card, short channel, mblk_t * data)
static int
dumb_data (struct _isdn1_card * card, short channel, mblk_t * data)
{
struct _dumb * dumb = (struct _dumb *)card;
S_enqueue(&dumb->chan[channel].q_out, data);
@ -309,43 +353,45 @@ static int dumb_data (struct _isdn1_card * card, short channel, mblk_t * data)
/*
* Flush the send queue.
*/
static int dumb_flush (struct _isdn1_card * card, short channel)
static int
dumb_flush (struct _isdn1_card * card, short channel)
{
struct _dumb * dumb = (struct _dumb *)card;
S_flush(&dumb->chan[channel].q_out);
return 0;
}
static int ISACpresent(struct _dumb *dumb)
static int
ISACpresent(struct _dumb *dumb)
{
unsigned char Bt;
if(((Bt = ByteInISAC(dumb,STAR)) & ~0x4F) != 0) {
printf("<STAR %02x> ",Bt);
return 0;
return -ENXIO;
}
if(((Bt = ByteInISAC(dumb,EXIR)) & ~0x10) != 0) {
printf("<EXIR %02x> ",Bt);
return 0;
return -ENXIO;
}
if(((Bt = ByteInISAC(dumb,RBCH)) & 0x8F) != 0x00) {
printf("<RBCH %02x> ",Bt);
return 0;
return -ENXIO;
}
ByteOutISAC(dumb,MODE,0xD1);
if((Bt = ByteInISAC(dumb,MODE)) != 0xD1) {
printf("<MODE %02x> ",Bt);
return 0;
return -ENXIO;
}
#if 0
if((Bt = ByteInISAC(dumb,RBCL)) != 0) {
printf("<RBCL %02x> ",Bt);
return 0;
return -ENXIO;
}
#endif
ByteOutISAC(dumb,MODE,0xC1);
if((Bt = ByteInISAC(dumb,MODE)) != 0xC1) {
printf("<MODE %02x> ",Bt);
return 0;
return -ENXIO;
}
return 1;
}
@ -364,7 +410,7 @@ static void ISAC_kick(struct _dumb * dumb)
uchar_t *sendp = NULL;
unsigned long ms = SetSPL(dumb->ipl);
DEBUG(isac) printf(KERN_DEBUG "K%d ",dumb-dumbdata);
DEBUG(isac) printf(KERN_DEBUG "K ");
if(dumb->chan[0].locked) {
DEBUG(isac) printf("lck ");
splx(ms);
@ -438,6 +484,8 @@ static void ISAC_kick(struct _dumb * dumb)
DEBUG(isac) printf("\n");
}
#ifdef __GNUC__
/* inline */
#endif
@ -448,7 +496,7 @@ static void HSCX_kick(struct _dumb * dumb, u_char hscx)
hdlc_buf bufp = &dumb->chan[hscx];
unsigned long ms = SetSPL(dumb->ipl);
DEBUG(hscxout) printf(KERN_DEBUG "K%d.%d ",dumb-dumbdata,hscx);
DEBUG(hscxout) printf(KERN_DEBUG "K.%d ",hscx);
if(bufp->locked) {
DEBUG(hscxout) { printf("Lck\n"); }
splx(ms);
@ -530,7 +578,7 @@ static void HSCX_kick(struct _dumb * dumb, u_char hscx)
ByteInHSCX(dumb,hscx,EXIR)&0x40
#endif
) { /* XDU */
DEBUG(info) printf(KERN_DEBUG "Underrun HSCX %d.%d\n",dumb-dumbdata,hscx);
DEBUG(info) printf(KERN_DEBUG "Underrun HSCX.%d\n",hscx);
ByteOutHSCX(dumb,hscx,CMDR,0x01);
bufp->m_out_run = bufp->m_out;
bufp->p_out = bufp->m_out->b_rptr;
@ -595,6 +643,7 @@ static void HSCX_kick(struct _dumb * dumb, u_char hscx)
bufp->locked = 0;
}
#ifdef __GNUC__
/* inline */
#endif
@ -609,9 +658,9 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
hdlc_buf bufp = &dumb->chan[hscx];
#ifdef WIDE
DEBUG(hscx) { printf(KERN_DEBUG "%c%d.%d %02x:%02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',dumb-dumbdata,hscx, isr0,isr1); }
DEBUG(hscx) { printf(KERN_DEBUG "%c.%d %02x:%02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',hscx, isr0,isr1); }
#else
DEBUG(hscx) { printf(KERN_DEBUG "%c%d.%d %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',dumb-dumbdata,hscx, Reason); }
DEBUG(hscx) { printf(KERN_DEBUG "%c.%d %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',hscx, Reason); }
if (hasEX)
#endif
{
@ -626,7 +675,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
EXIR & 0x80
#endif
) { /* XMR */
DEBUG(info) { printf(KERN_DEBUG "Msg Repeat HSCX %d.%d\n",dumb-dumbdata,hscx); }
DEBUG(info) { printf(KERN_DEBUG "Msg Repeat HSCX.%d\n",hscx); }
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
if (ByteInHSCX(dumb,hscx,STAR) & 0x40) { /* XFW */
#ifdef WIDE
@ -651,7 +700,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
if (bufp->mode >= M_HDLC) {
DEBUG(info) {
printf(KERN_DEBUG "Xmit Underrun HSCX %d.%d\n",dumb-dumbdata,hscx); }
printf(KERN_DEBUG "Xmit Underrun HSCX.%d\n",hscx); }
#if NEW_XMIT
ByteOutHSCX(dumb,hscx,CMDR, 0x01); /* XRES */
#ifdef WIDE
@ -713,7 +762,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
EXIR & 0x10
#endif
) { /* RFO */
DEBUG(info) { printf(KERN_DEBUG "Recv overflow HSCX %d.%d\n",dumb-dumbdata,hscx); }
DEBUG(info) { printf(KERN_DEBUG "Recv overflow HSCX.%d\n",hscx); }
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
if(
#ifdef WIDE
@ -765,7 +814,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
ByteOutHSCX(dumb,hscx,CMDR, 0x80); /* RMC */
} else {
if ((recvb = bufp->m_in_run) != NULL) {
if ((recvp = (uchar_t *)recvb->b_wptr) + blen > (uchar_t *)recvb->b_datap->db_lim)
if ((recvp = (uchar_t *)recvb->b_wptr) + blen > (uchar_t *)DATA_END(recvb))
recvb = NULL;
}
if (recvb == NULL) {
@ -804,7 +853,7 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
}
}
} else {
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%02x) HSCX %d.%d\n", RSTA,dumb-dumbdata,hscx); }
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%02x) HSCX.%d\n", RSTA,hscx); }
if(bufp->m_in != NULL) {
freemsg(bufp->m_in);
bufp->m_in = bufp->m_in_run = NULL;
@ -823,21 +872,27 @@ static void IRQ_HSCX_(struct _dumb * dumb, u_char hscx,
mblk_t *recvb;
if ((recvb = bufp->m_in_run) != NULL) {
if ((recvp = (uchar_t *)recvb->b_wptr) + HSCX_R_FIFO_SIZE > (uchar_t *)recvb->b_datap->db_lim)
if ((recvp = (uchar_t *)recvb->b_wptr) + HSCX_R_FIFO_SIZE > (uchar_t *)DATA_END(recvb))
recvb = NULL;
}
if(0)DEBUG(hscx)printf(":");
if (recvb == NULL) {
recvb = allocb(HSCX_R_FIFO_SIZE*4,BPRI_MED);
if(recvb != NULL) {
recvp = recvb->b_wptr;
if(bufp->m_in_run == NULL) {
bufp->m_in = bufp->m_in_run = recvb;
} else {
linkb(bufp->m_in_run, recvb);
bufp->m_in_run = recvb;
if(bufp->m_in_run == NULL) { /* first block */
recvb = allocb(HSCX_R_FIFO_SIZE*2+bufp->offset,BPRI_MED);
if(recvb != NULL) {
recvb->b_wptr += bufp->offset;
recvb->b_rptr += bufp->offset;
recvp = recvb->b_wptr;
bufp->m_in = bufp->m_in_run = recvb;
}
}
} else {
recvb = allocb(HSCX_R_FIFO_SIZE*4,BPRI_MED);
if(recvb != NULL) {
recvp = recvb->b_wptr;
linkb(bufp->m_in_run, recvb);
bufp->m_in_run = recvb;
}
}
}
if(recvb == NULL) {
CEC(ByteInHSCX(dumb,hscx,STAR) & 0x04);
@ -909,7 +964,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
Byte Reason;
while((Reason = ByteInISAC(dumb,ISTA))) {
DEBUG(isac) { printf(KERN_DEBUG "%c%d %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',dumb-dumbdata, Reason); }
DEBUG(isac) { printf(KERN_DEBUG "%c %02x\n",(dumb->polled<0)?'X':(dumb->polled>0)?'P':'I',Reason); }
if (Reason & 0x04) { /* CISQ */
Byte CIR = ByteInISAC(dumb,CIR0);
@ -950,7 +1005,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
Byte EXIR = ByteInISAC(dumb,EXIR);
DEBUG(isac) { printf(". %x", EXIR); }
if (EXIR & 0x80) { /* XMR */
DEBUG(info) { printf(KERN_DEBUG "MsgRepeat ISAC %d\n",dumb-dumbdata); }
DEBUG(info) { printf(KERN_DEBUG "MsgRepeat ISAC\n"); }
CEC(ByteInISAC(dumb,STAR) & 0x04);
if (ByteInISAC(dumb,STAR) & 0x40) { /* XFW */
Reason |= 0x10; /* also set XPR bit */
@ -964,7 +1019,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
if (EXIR & 0x40) { /* XDU */
CEC(ByteInISAC(dumb,STAR) & 0x04);
if (dumb->chan[0].mode >= M_HDLC) {
DEBUG(info) { printf(KERN_DEBUG "Xmit Underrun ISAC %d\n",dumb-dumbdata); }
DEBUG(info) { printf(KERN_DEBUG "Xmit Underrun ISAC\n"); }
#if NEW_XMIT
ByteOutISAC(dumb,CMDR, 0x01); /* XRES */
Reason |= 0x10;
@ -986,7 +1041,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
DEBUG(info) { printf(KERN_WARNING "ISDN .PCE\n"); }
}
if (EXIR & 0x10) { /* RFO */
DEBUG(info) { printf(KERN_DEBUG "Recv overflow ISAC %d (%02x)\n",dumb-dumbdata, EXIR); }
DEBUG(info) { printf(KERN_DEBUG "Recv overflow ISAC (%02x)\n", EXIR); }
CEC(ByteInISAC(dumb,STAR) & 0x04);
if(Reason & 0xC0) {
ByteOutISAC(dumb,CMDR, 0xC0); /* RMC|RHR */
@ -1018,6 +1073,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
blen = (xblen & (ISAC_R_FIFO_SIZE-1));
xblen += (ByteInISAC(dumb,RBCH) & 0x0F) << 8;
if(blen == 1) {
DEBUG(isac) printf(KERN_DEBUG ".R-%d\n",xblen);
if((recvb = dumb->chan[0].m_in_run) != NULL) {
mblk_t *msg = dumb->chan[0].m_in;
dumb->chan[0].m_in = dumb->chan[0].m_in_run = NULL;
@ -1030,10 +1086,10 @@ static void IRQ_ISAC(struct _dumb * dumb)
} else {
if(blen == 0)
blen = ISAC_R_FIFO_SIZE;
DEBUG(isac) printf(KERN_DEBUG ".R %d\n",xblen);
DEBUG(isac) printf(KERN_DEBUG ".R=%d\n",xblen);
if ((recvb = dumb->chan[0].m_in_run) != NULL) {
DEBUG(isac)printf("a%d ",dsize(dumb->chan[0].m_in));
if ((recvp = (uchar_t *)recvb->b_wptr) + blen-1 > (uchar_t *)recvb->b_datap->db_lim)
if ((recvp = (uchar_t *)recvb->b_wptr) + blen > (uchar_t *)DATA_END(recvb))
recvb = NULL;
}
if (recvb == NULL) {
@ -1052,6 +1108,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
short i;
mblk_t *msg = dumb->chan[0].m_in;
dumb->chan[0].m_in = dumb->chan[0].m_in_run = NULL;
DEBUG(isac) printf(">%p",recvp);
for(i=0;i < blen; i++)
*recvp++ = ByteInISAC(dumb,FIFO(i));
recvb->b_wptr = recvp;
@ -1068,7 +1125,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
}
}
} else {
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%x) %d\n",RSTA,dumb-dumbdata); }
DEBUG(info) { printf(KERN_DEBUG "Recv abort (%x)\n",RSTA); }
if(dumb->chan[0].m_in != NULL) {
freemsg(dumb->chan[0].m_in);
dumb->chan[0].m_in = dumb->chan[0].m_in_run = NULL;
@ -1081,7 +1138,7 @@ static void IRQ_ISAC(struct _dumb * dumb)
mblk_t *recvb;
if ((recvb = dumb->chan[0].m_in_run) != NULL) {
if ((recvp = (uchar_t *)recvb->b_wptr) + ISAC_R_FIFO_SIZE > (uchar_t *)recvb->b_datap->db_lim)
if ((recvp = (uchar_t *)recvb->b_wptr) + ISAC_R_FIFO_SIZE > (uchar_t *)DATA_END(recvb))
recvb = NULL;
}
if (recvb == NULL) {
@ -1133,7 +1190,6 @@ static void IRQ_ISAC(struct _dumb * dumb)
}
}
#ifdef __GNUC__
inline
#endif
@ -1165,14 +1221,12 @@ static void IRQ_HSCX(struct _dumb * dumb)
}
}
#ifdef linux
static void
dumbintr(int irq, struct pt_regs *regs)
{
struct _dumb *dumb;
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
for(dumb=dumbmap[irq];dumb != NULL;dumb = dumb->next) {
if(dumb->irq == irq) {
dumb->polled --;
IRQ_HSCX(dumb);
@ -1182,7 +1236,7 @@ dumbintr(int irq, struct pt_regs *regs)
toggle_off(dumb);
}
}
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
for(dumb=dumbmap[irq];dumb != NULL;dumb = dumb->next) {
if(dumb->irq == irq) {
toggle_on(dumb);
}
@ -1190,23 +1244,6 @@ dumbintr(int irq, struct pt_regs *regs)
}
#else
void NAME(CARDTYPE,intr)(int x)
{
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
if(dumb->irq == x) {
dumb->polled --;
IRQ_HSCX(dumb);
IRQ_ISAC(dumb);
dumb->polled ++;
toggle_off(dumb);
toggle_on(dumb);
return;
}
}
}
#endif
#ifdef linux
void NAME(CARDTYPE,poll)(struct _dumb *dumb)
#else
@ -1249,9 +1286,8 @@ static void dumbtimer(struct _dumb *dumb)
{
NAME(CARDTYPE,poll)(dumb);
#if 0
if(dumb->countme++ > 10) {
dumb->countme = 0;
printf(" -%d:%02x %02x %02x- ",dumb-dumbdata,ByteInISAC(dumb,STAR),ByteInISAC(dumb,ISTA),ByteInISAC(dumb,CIR0));
if(dumb->countme++ < 10) {
printf(" -(%d):%02x %02x %02x- ",dumb->irq,ByteInISAC(dumb,STAR),ByteInISAC(dumb,ISTA),ByteInISAC(dumb,CIR0));
}
#endif
#ifdef NEW_TIMEOUT
@ -1261,131 +1297,122 @@ static void dumbtimer(struct _dumb *dumb)
}
#endif
void NAME(CARDTYPE,init)(void)
int NAME(CARDTYPE,init)(struct _dumb *dumb)
{
extern caddr_t sptalloc();
struct _dumb *dumb;
int err;
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
dumb->card.nr_chans = dumb->numHSCX * 2;
dumb->card.ctl = dumb;
dumb->card.chan = NULL;
dumb->card.modes = (1<<M_HDLC)| (1<<M_HDLC_7H)| (1<<M_HDLC_7L)| (1<<M_TRANSPARENT)| (1<<M_TRANS_ALAW)| (1<<M_TRANS_V110)| (1<<M_TRANS_HDLC);
dumb->card.ch_mode = dumb_mode;
dumb->card.ch_prot = dumb_prot;
dumb->card.send = dumb_data;
dumb->card.flush = dumb_flush;
dumb->card.cansend = dumb_candata;
dumb->polled = -1;
dumb->card.ctl = dumb;
dumb->card.modes = (1<<M_HDLC)| (1<<M_HDLC_7H)| (1<<M_HDLC_7L)| (1<<M_TRANSPARENT)| (1<<M_TRANS_ALAW)| (1<<M_TRANS_V110)| (1<<M_TRANS_HDLC);
dumb->card.ch_mode = dumb_mode;
dumb->card.ch_prot = dumb_prot;
dumb->card.send = dumb_data;
dumb->card.flush = dumb_flush;
dumb->card.cansend = dumb_candata;
dumb->card.poll = NULL;
dumb->polled = -1;
printf("ISDN: " STRING(CARDTYPE) " at mem %lx io 0x%x irq %d: ",dumb->memaddr,dumb->ioaddr,dumb->irq);
printf("ISDN: " STRING(CARDTYPE) " at mem %lx io 0x%x irq %d: ",dumb->memaddr,dumb->ioaddr,dumb->irq);
if(!Init(dumb)) {
printf("Card not initializable.\n");
continue;
}
InitHSCX(dumb);
InitISAC(dumb);
InitHSCX(dumb);
if((err = Init(dumb)) < 0) {
printf("Card not initializable.\n");
if(err == 0)
err = -EIO;
return err;
}
dumb->card.nr_chans = dumb->numHSCX;
if(!ISACpresent(dumb)) {
printf("Card not responding.\n");
continue;
}
InitHSCX(dumb);
InitISAC(dumb);
InitHSCX(dumb);
if((err = ISACpresent(dumb)) < 0) {
printf("Card not responding.\n");
return err;
}
#ifndef M_UNIX
#ifdef linux
if((dumb->irq != 0) && request_irq(dumb->irq,dumbintr,SA_INTERRUPT,"ISDN")) {
printf("IRQ not available.\n");
continue;
}
if((dumb->irq != 0) && request_irq(dumb->irq,dumbintr,SA_INTERRUPT,"ISDN")) {
printf("IRQ not available.\n");
return -EEXIST;
}
#endif
NAME(CARDTYPE,poll)(dumb);
if((err = isdn2_register(&dumb->card, dumb->ID)) != 0) {
printf("not installed (ISDN_2), err %d\n",err);
continue;
}
NAME(CARDTYPE,poll)(dumb);
if((err = isdn2_register(&dumb->card, dumb->ID)) != 0) {
printf("not installed (ISDN_2), err %d\n",err);
return err;
}
dumb->polled = 1;
dumb->polled = 1;
#ifdef linux
if(dumb->irq == 0) {
printf("polling; ");
if(dumb->irq == 0) {
printf("polling; ");
}
#endif
printf("installed at ");
if(dumb->memaddr != 0)
printf("mem 0x%lx ",dumb->memaddr);
if(dumb->ioaddr != 0)
printf("io 0x%x ",dumb->ioaddr);
if(dumb->irq != 0)
printf("irq %d.\n",dumb->irq);
else
printf("polled.\n");
dumb->next = dumbmap[dumb->irq];
dumbmap[dumb->irq] = dumb;
#ifdef linux
dumbtimer(dumb);
#endif
#endif /* M_UNIX */
MOD_INC_USE_COUNT;
return 0;
}
void
NAME(CARDTYPE,exit)(struct _dumb *dumb)
{
int j;
unsigned long ms = SetSPL(dumb->ipl);
struct _dumb **ndumb = &dumbmap[dumb->irq];
while(*ndumb != NULL) {
if(*ndumb == dumb) {
*ndumb = dumb->next;
break;
}
dumbtimer(dumb);
#endif
printf("installed at ");
if(dumb->memaddr != 0)
printf("mem 0x%lx ",dumb->memaddr);
if(dumb->ioaddr != 0)
printf("io 0x%x ",dumb->ioaddr);
if(dumb->irq != 0)
printf("irq %d.\n",dumb->irq);
else
printf("polled.\n");
#endif
ndumb = &((*ndumb)->next);
}
}
#ifdef M_UNIX
void NAME(CARDTYPE,start)(void)
{
extern caddr_t sptalloc();
short i;
struct _dumb *dumb;
int err;
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
if((err = isdn2_register(&dumb->card, dumb->ID)) == 0)
printcfg("dumb",0,dumb->ioaddr,dumb->irq,i, "unit %d",i);
else
printf("ISDN Driver %d/%d/%x not installed, err %d.\n",i,dumb->irq,dumb->ioaddr,err);
}
}
#endif
void NAME(CARDTYPE,halt)(void)
{
struct _dumb *dumb;
for(dumb=&dumbdata[dumb_num-1];dumb>=dumbdata;--dumb) {
int j;
unsigned long ms = SetSPL(dumb->ipl);
if(dumb->polled > 0) {
#ifdef NEW_TIMEOUT
untimeout(dumb->timer);
untimeout(dumb->timer);
#else
untimeout(dumbtimer,dumb);
untimeout(dumbtimer,dumb);
#endif
ByteOutISAC(dumb,MASK,0xFF);
for(j=1; j<=dumb->numHSCX;j++) {
ByteOutISAC(dumb,MASK,0xFF);
for(j=1; j<=dumb->numHSCX;j++) {
#ifdef WIDE
ByteOutHSCX(dumb,j,IMR0,0xFF);
ByteOutHSCX(dumb,j,IMR1,0xFF);
ByteOutHSCX(dumb,j,IMR0,0xFF);
ByteOutHSCX(dumb,j,IMR1,0xFF);
#else
ByteOutHSCX(dumb,j,MASK,0xFF);
ByteOutHSCX(dumb,j,MASK,0xFF);
#endif
}
if(dumb->irq > 0)
free_irq(dumb->irq);
isdn2_unregister(&dumb->card);
}
splx(ms);
}
}
if(dumb->irq > 0)
free_irq(dumb->irq);
isdn2_unregister(&dumb->card);
splx(ms);
MOD_DEC_USE_COUNT;
}
#ifdef MODULE
static int do_init_module(void)
{
NAME(CARDTYPE,init)();
return 0;
}
static int do_exit_module(void)
{
NAME(CARDTYPE,halt)();
return 0;
}
#endif

View File

@ -1,3 +1,5 @@
#ifndef CONF_H
#define CONF_H
#include "isdn_limits.h"
#include "isdn_12.h"
#include "smallq.h"
@ -25,24 +27,25 @@ typedef struct _hdlc_buf {
unsigned char *p_out;
Byte mode;
Byte locked,listen;
u_short nblk,maxblk;
u_short nblk,maxblk,offset;
} *hdlc_buf;
typedef struct _dumb {
struct _isdn1_card card;
struct _isdn1_card card; /* must be first */
long memaddr;
short ioaddr;
char irq, ipl, numHSCX;
long ID;
int debug;
unsigned char irq, ipl, numHSCX;
unsigned long ID;
unsigned int debug;
struct _hdlc_buf chan[MAX_B+1];
#ifdef NEW_TIMEOUT
long timer;
#endif
struct _dumb *next;
long countme; signed char polled; char circ;
} *__dumb;
extern struct _dumb dumbdata[];
#endif

View File

@ -19,12 +19,15 @@ static inline Byte Slot(struct _dumb * dumb, u_char hscx) {
return (hscx&1) ? 0x03 : 0x03; /* was 3 / 7 */
}
static int Init(struct _dumb * dumb) {
static int
Init(struct _dumb * dumb) {
int timout;
long flags;
if(dumb->memaddr == 0)
return -EINVAL;
dumb->numHSCX = 2;
save_flags(flags);
if(dumb->ipl) {
int ioaddr;
Byte cfval;
@ -36,7 +39,7 @@ static int Init(struct _dumb * dumb) {
case 4: ioaddr = 0xc80; break; /* may cause conflicts (motherboard range) */
}
switch(dumb->irq) {
default: printk("irq %d not possible: ",dumb->irq); return 0;
default: printk("irq %d not possible: ",dumb->irq); return -EINVAL;
case 2: cfval = 0x00; break;
case 3: cfval = 0x02; break;
case 4: cfval = 0x04; break;
@ -70,10 +73,11 @@ static int Init(struct _dumb * dumb) {
timout = jiffies+(HZ/5)+1;
while(jiffies <= timout) ;
restore_flags(flags);
return 1;
return 0;
}
static void ISAC_mode(struct _dumb * dumb, Byte mode, Byte listen)
static void
ISAC_mode(struct _dumb * dumb, Byte mode, Byte listen)
{
unsigned long ms = SetSPL(dumb->ipl);
static Byte xmode = 0xFF;
@ -130,7 +134,8 @@ static Byte xmode = 0xFF;
xmode = mode;
}
static int HSCX_mode(struct _dumb * dumb, u_char hscx, Byte mode, Byte listen)
static int
HSCX_mode(struct _dumb * dumb, u_char hscx, Byte mode, Byte listen)
{
unsigned long ms = SetSPL(dumb->ipl);
if(dumb->chan[hscx].m_in != NULL) {
@ -210,7 +215,8 @@ static int HSCX_mode(struct _dumb * dumb, u_char hscx, Byte mode, Byte listen)
splx(ms);
return 0;
}
static void InitISAC(struct _dumb * dumb)
static void
InitISAC(struct _dumb * dumb)
{
dumb->chan[0].mode = M_OFF;
dumb->chan[0].listen = 0;
@ -225,7 +231,8 @@ static void InitISAC(struct _dumb * dumb)
ByteOutISAC(dumb, MASK, 0x00);
}
static void InitHSCX_(struct _dumb * dumb, u_char hscx)
static void
InitHSCX_(struct _dumb * dumb, u_char hscx)
{
ByteOutHSCX(dumb,hscx,CCR2, 0x30); /* 0x38 */
ByteOutHSCX(dumb,hscx,TSAX, Slot(dumb,hscx));

View File

@ -21,7 +21,7 @@ ALL = test.o
all: test.o
load: all
load:
insmod test.o
test.o: test.c

355
cards/test/test.c Normal file
View File

@ -0,0 +1,355 @@
/*
* Testing driver which registers a device for loopback, and so on.
*
*/
#define UAREA
#include "f_module.h"
#include "primitives.h"
#include <sys/time.h>
#include "f_signal.h"
#include "f_malloc.h"
#include <sys/sysmacros.h>
#include "streams.h"
#include <sys/stropts.h>
/* #ifdef DONT_ADDERROR */
#include "f_user.h"
/* #endif */
#include <sys/errno.h>
#include <sys/file.h>
#include <fcntl.h>
#include <stddef.h>
#include "streamlib.h"
#include "lap.h"
#include <sys/termios.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/tqueue.h>
#include <asm/io.h>
extern void log_printmsg (void *log, const char *text, mblk_t * mp, const char*);
extern void logh_printmsg (void *log, const char *text, mblk_t * mp);
#define ddprintf(xx) printf(xx),({int x;for(x=0;x<1000;x++) udelay(1000);})
#define ldprintf if(0)printf
#if 1
#if 1
#define dprintf printf
#else
#define dprintf ({int x;for(x=0;x<300;x++) udelay(1000);}),printf
#endif
#else
#define dprintf if(0)printf
#endif
/*
* Standard Streams driver information.
*/
static struct module_info itest_minfo =
{
0, "itest", 0, INFPSZ, 8000, 3000
};
static qf_open itest_open;
static qf_close itest_close;
static qf_srv itest_wsrv, itest_rsrv;
static qf_put itest_wput;
static struct qinit itest_rinit =
{
NULL, NULL, itest_open, itest_close, NULL, &itest_minfo, NULL
};
static struct qinit itest_winit =
{
itest_wput, itest_wsrv, NULL, NULL, NULL, &itest_minfo, NULL
};
struct streamtab itest_info =
{&itest_rinit, &itest_winit, NULL, NULL};
#define NCARDS 2
#define NBCHAN 3
struct testcard {
struct _isdn1_card *card;
struct testchannel {
struct testcard *card;
queue_t *q;
} port[NBCHAN+1];
} test_card[NCARDS];
static int test_poll (struct _isdn1_card * card, short channel)
{
struct testcard *test_card = (struct testcad *)card;
struct testchannel *testport;
if(channel < 0 || channel >= NBCHAN)
return -EIO;
testport = &testcard.port[channel];
if(testport->q == NULL)
return -ENXIO;
if(WR(testport->q)->q_first == NULL)
return -EAGAIN;
qenable(WR(testport->q));
return 0;
}
static int test_candata (struct _isdn1_card * card, short channel)
{
struct testcard *test_card = (struct testcad *)card;
struct testchannel *testport;
if(channel < 0 || channel >= NBCHAN)
return 0;
testport = &testcard.port[channel];
if(testport->q == NULL)
return 0;
return canput(testport->q->q_next);
}
static int test_data (struct _isdn1_card * card, short channel, mblk_t * data)
{
struct testcard *test_card = (struct testcad *)card;
struct testchannel *testport;
if(channel < 0 || channel >= NBCHAN)
return -EIO;
testport = &testcard.port[channel];
if(testport->q == NULL)
return -ENXIO;
if(!canput(testport->q->q_next))
return -EAGAIN;
putnext(testport->q,data);
}
data
candata
static int test_flush (struct _isdn1_card * card, short channel)
{
struct testcard *test_card = (struct testcad *)card;
struct testchannel *testport;
if(channel < 0 || channel >= NBCHAN)
return -EIO;
testport = &testcard.port[channel];
if(testport->q == NULL)
return -ENXIO;
putctlx1(testport->q,M_FLUSH,FLUSHR|FLUSHW);
}
static int test_prot (struct _isdn1_card * card, short channel, mblk_t * proto)
{
return EINVAL;
}
static int test_mode (struct _isdn1_card * card, short channel, char mode,
char listen)
{
struct testcard *test_card = (struct testcad *)card;
struct testchannel *testport;
if(channel < 0 || channel >= NBCHAN)
return -EIO;
testport = &testcard.port[channel];
if(testport->q == NULL)
return -ENXIO;
if(mode == MODE_OFF)
putctlx1(testport->q,M_HANGUP);
}
/* Streams code to open the driver. */
static int
itest_open (queue_t * q, dev_t dev, int flag, int sflag
#ifdef DO_ADDERROR
,int *err
#define U_ERROR *err
#else
#define U_ERROR u.u_error
#endif
)
{
struct testcard *test_card;
struct testchannel *testport;
int mdev = 0;
int cdev;
int err;
dev = minor (dev);
cdev = dev & 0x0F;
mdev = cdev / (NBCHAN+1);
cdev %= (NBCHAN+1);
if(mdev >= NCARDS) {
U_ERROR = ENXIO;
return OPENFAIL;
}
testcard = test_card[mdev];
testport = &testcard->port[cdev];
if(testport->q != NULL) {
printf("itest dev 0x%x: already open, %p\n",dev,testport->q);
return 0;
}
MORE_USE;
if(cdev == 0) {
int theID = CHAR4('T','s','t','A'+mdev);
testcard->card.nr_chans = NBCHAN;
testcard->card.ctl = testcard;
testcard->card.chan = NULL;
testcard->card.modes = (1<<M_HDLC)| (1<<M_TRANSPARENT)| (1<<M_TRANS_ALAW)| (1<<M_TRANS_V110)| (1<<M_TRANS_HDLC);
testcard->card.ch_mode = test_mode;
testcard->card.ch_prot = test_prot;
testcard->card.send = test_data;
testcard->card.flush = test_flush;
testcard->card.cansend = test_candata;
testcard->card.poll = test_poll;
if((err = isdn2_register(&testcard->card, theID)) != 0) {
U_ERROR = err;
LESS_USE;
return OPENFAIL;
}
}
testport->card = testcard;
testport->q = q;
WR (q)->q_ptr = (caddr_t) testport;
q->q_ptr = (caddr_t) testport;
return dev;
}
/* Streams code to close the driver. */
static void
itest_close (queue_t *q, int dummy)
{
struct testchannel *testport = (struct testchannel *) q->q_ptr;
struct testcard *test_card = testport->card;
if(testport->q == NULL)
return;
if(testport == &testcard->port[0])
isdn2_unregister(&testcard->card);
testport->q = NULL;
LESS_USE;
return;
}
/* Streams code to write data. */
static void
itest_wput (queue_t *q, mblk_t *mp)
{
struct testchannel *testport = (struct testchannel *) q->q_ptr;
struct testcard *test_card = testport->card;
ldprintf(".%d.",__LINE__);
#ifdef CONFIG_DEBUG_STREAMS
if(msgdsize(mp) < 0)
return;
#endif
if(testport->q == NULL) {
freemsg(mp);
return;
}
switch (DATA_TYPE(mp)) {
case M_IOCTL:
DATA_TYPE(mp) = M_IOCNAK;
((struct iocblk *)mp->b_rptr)->ioc_error = EINVAL;
qreply (q, mp);
break;
CASE_DATA
putq (q, mp);
break;
case M_FLUSH:
if (*mp->b_rptr & FLUSHW)
flushq (q, 0);
if (*mp->b_rptr & FLUSHR) {
flushq (RD (q), 0);
*mp->b_rptr &= ~FLUSHW;
qreply (q, mp);
} else
freemsg (mp);
break;
default:
log_printmsg (NULL, "Strange itest", mp, KERN_WARNING);
/* putctl1(RD(q)->b_next, M_ERROR, ENXIO); */
freemsg (mp);
break;
}
return;
}
/* Streams code to scan the write queue. */
static void
itest_wsrv (queue_t *q)
{
struct testchannel *testport = (struct testchannel *) q->q_ptr;
struct testcard *testcard;
mblk_t *mp;
int chan;
if(testport == NULL || testport->q == NULL) {
flushq(q,FLUSHALL);
return;
}
testcard = testport->card;
chan = testport - testcard->port;
while (q->q_first != NULL) {
int err = isdn2_canrecv(&testcard->card, chan);
if(err != 0)
break;
mp = getq (q)) != NULL);
if(mp != NULL) {
err = isdn2_recv(&testcard->card, chan,mp);
if(err != 0)
freemsg(mp);
}
}
}
#ifdef MODULE
static int devmajor1 = 0;
static int do_init_module(void)
{
int err;
bzero(test_card,sizeof(test_card));
err = register_strdev(0,&itest_info,0);
if(err < 0) {
return err;
}
devmajor1 = err;
return 0;
}
static int do_exit_module(void)
{
int err1;
int i;
err1 = unregister_strdev(devmajor1,&itest_info,0);
return err1;
}
#endif

View File

@ -35,7 +35,7 @@ ML login * * * -,3 frame x75
P cept cept * * RFX :vB 8890 :vL 9090A9D1E7 :vH 91D2 :sv 0F00
MP cept * * * - x75 :nk 1
MP cept * * * - proto :sg 0 :ca 2 :bk 0
ML cept * * * -,0 frame x75
ML cept * * * -,0 frame x75 t70
D cept cept * * o -01910
# Sample CEPT session, old standard. Untested.
@ -43,7 +43,7 @@ D cept cept * * o -01910
P btx btx * * RFX :vB 8890 :vL 9090A9D1EA :sv 0500
MP btx * * * - x75 :nk 1
MP btx * * * - proto :sg 0 :ca 2 :bk 0
ML btx * * * -,0 frame x75
ML btx * * * -,0 frame x75 t70
D btx btx * * o -01910
@ -55,29 +55,45 @@ R tcp somebody * * root 1RUp slipto -r <remote_network> <local_IP> <remote_IP>
# Use -R for host routes. Use -r network:netmask for subnets or supernets.
# Use -d for the default route.
P tcp somebody * * R :nr .1
P tcp * * * MFX :lr /2 :vB 8890 :sv 0700
P tcp somebody * * R :nr .1
P tcp * * * MFX :lr /2 :vB 8890 :sv 0700
ML tcp somebody * * -,3 frame timer reconn str_if
MP tcp somebody * * - timer :tr 60 :tw 60 :ti 360 :to 360 :tI :lo
MP tcp * * * - proto :sg 1 :ca 1 :bk 0
MP tcp somebody * * - timer :tr 60 :tw 60 :ti 360 :to 360 :tI :lo
MP tcp * * * - proto :sg 1 :ca 1 :bk 0
## example for dialup-TCP; demand-only and outgoing-only.
# If you need dynamic address assignment, call slipto
# from an appropriate chat script.
# Dynamic address assignment via PPP will be here, too ... someday.
#R dtcp somebody * * root 1RUd slipto -E -r <remote_network> <local_IP> <remote_IP>
#P dtcp somebody * * R :nr .1
#P dtcp * * * MFX :lr /2 :vB 8890 :sv 0700
#ML dtcp somebody * * -,3 frame slip timer str_if
#MP dtcp somebody * * - timer :tr 60 :tw 60 :ti 360 :to 360 :tI :lo
#MP dtcp * * * - proto :sg 0 :ca 1 :bk 0
# Remote phone numbers.
# The "unknown" entry is used when no number is transmitted.
# Note that you need a matching entry with "o" flag (or no "i" flag)
# if you want to ATDnumber.
D * somebody A * - +49=911-234567.
D * x-de-nbg X * i +49=911-*
D * x-de Y * i +49=*
D * x-intl Z * i +*
D * unknown U * i +*
D * unknown U * - +*
# Local numbers.
#DL Tel0 +49=911-959913/[1-3] :pr 0 :sp 8 :pr 63
DL Tel0 +49=911-919402/ :pr 0 :sp 65 :pr 63
## :pr 65 -- leased lines ONLY.
## :pr 64 -- leased lines ONLY.
## :pr 65 -- cards with CAPI interface ONLY.
## :pr 0 -- the normal circuit-mode D channel protocol
## :sp 65 -- German 1TR6
## :sp 8 -- European DSS-1
@ -88,17 +104,35 @@ DL Tel0 +49=911-919402/ :pr 0 :sp 65 :pr 63
# Use the second line if you're using a PBX which doesn't prefix external
# numbers with the PBX' dialout prefix.
DP * +00=0-
#DP * +00=0- +000=00-0
#DP * +000=00-0 +00=0-
# Card modes. Don't change the numbers, the driver knows about them.
CM ???? 2 transalaw
CM ???? 3 transv110
CM ???? 4 trans
CM ???? 10 frame
CM ???? 14 frameb
# Limit how many B channel connections may be opened.
# Override the limit with :il in the P line.
CL * 2
## Load cards
LF Bin? 2048 /etc/isdn/boot.68k
## The following is a complete example on how to do a leased line.
#
#P tcp foo A Tel3 RX :dI :pr 64 :sp 0 :bc 1 :Ft
#ML tcp foo * Tel3 -,3 frame xstrlog fakeh reconn str_if
#MP tcp foo * Tel3 - proto :sg 1 :ca 1 :bk 0 :on
#R tcp foo * Tel3 root 1RUBf slipto -d 10.1.1.1 10.1.1.2
#D * foo A Tel3 f -
#DL Tel3 - :pr 64
#CM Tel3 10 frame
#CM Tel3 14 frameb
#MP tcp * * * - proto :sg 1 :ca 1 :bk 0
#MP * * * * i proto :sg 0 :ca 1 :bk 0
# END

View File

@ -8,7 +8,7 @@ P =
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
@ -42,7 +42,7 @@ depend: Makefile $(SOURCES)
ln -s . linux
$(CC) -M $(DEFS) $(SOURCES) > .depend
load: all
load:
insmod compat.o
ifeq (.depend,$(wildcard .depend))

View File

@ -6,6 +6,7 @@
* Copyright 1994: Matthias Urlichs <urlichs@smurf.noris.de>
*/
#ifdef MODULE
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#endif
@ -15,9 +16,11 @@
#include <asm/delay.h>
/*
* syscompat.c -- provide compatibility code for stuff written for non-Linux kernels
* compat.c
*
* Version 0.1 by Matthias Urlichs <urlichs@smurf.sub.org>
* provides some compatibility code for stuff written for non-Linux kernels
*
* Version 0.3 by Matthias Urlichs <urlichs@smurf.noris.de>
*/
#include <linux/config.h>
#include <linux/types.h>
@ -32,78 +35,12 @@
unsigned long block_mask = 0;
const char *xdeb_file; unsigned int xdeb_line;
#if 0
/*
* Completely untested code.
* Just rewrite the stuff to use sleep_on and wake_up;
* they're better anyway...
* Standard Unix-kernel timeout code. Two versions -- the new version
* returns a pointer to its internal data, the old version doesn't, which
* means we have to scan for the thing in an internal list when
* deallocating the timer.
*/
/*
* I freely admit that the implementation below can be improved
* tremendously, but IMHO there are better things to do with my time.
* YMMV. -M.U-
*/
static struct event_list {
struct event_list *next;
struct wait_queue *queue;
caddr_t event;
} *event_list;
static char block_events;
static struct wait_queue *block_queue;
/* sleep is supposed to be written so that wakeup can run from an interrupt
without running off the queue. */
int sleep(caddr_t event, int prio) {
unsigned long flags;
struct event_list *ev = event_list;
save_flags(flags);
cli();
while(block_events)
sleep_on(&block_queue);
block_events = 1;
while(ev != NULL && ev->event != event) {
if(ev->next->queue == NULL) {
struct event_list *ev2 = ev->next;
ev->next = ev2->next;
kfree_s(ev2, sizeof(struct event_list));
} else {
ev = ev->next;
}
}
if(ev == NULL) {
ev = (struct event_list *)kmalloc(sizeof(struct event_list),GFP_KERNEL);
ev->queue = NULL;
ev->event = event;
ev->next = event_list;
event_list = ev->next;
}
block_events = 0;
wake_up(&block_queue);
if(prio & PZERO)
interruptible_sleep_on(&ev->queue);
else
sleep_on(&ev->queue);
restore_flags(flags);
return ((current->signal & ~current->blocked) != 0);
}
void wakeup(caddr_t event) {
struct event_list *ev = event_list;
while(ev != NULL && ev->event != event) {
ev = ev->next;
}
if(ev != NULL) {
wake_up(&ev->queue);
}
}
#endif /* 0 */
struct timing {
struct timer_list tim;
void (*proc)(void *);
@ -112,6 +49,7 @@ struct timing {
struct timing_old {
struct timing tim;
struct timing_old *prev;
struct timing_old *next;
};
static struct timing_old *start = NULL;
@ -130,14 +68,18 @@ static void dotimer(void *arg)
static void droptimer_old(void (*func)(void *), void *arg, char del)
{
struct timing_old **head = &start;
struct timing_old *tim;
unsigned long flags;
save_flags(flags);
cli();
while(*head != NULL) {
if((*head)->tim.proc == func && (*head)->tim.arg == arg) {
struct timing_old *tim = *head;
*head = tim->next;
for(tim = start; tim != NULL; tim = tim->next) {
if(tim->tim.proc == func && tim->tim.arg == arg) {
if(tim->next != NULL)
tim->next->prev = tim->prev;
if(tim->prev != NULL)
tim->prev->next = tim->next;
else
start = tim->next;
restore_flags(flags);
if(del) {
del_timer(&tim->tim.tim);
@ -147,8 +89,7 @@ static void droptimer_old(void (*func)(void *), void *arg, char del)
MOD_DEC_USE_COUNT;
#endif
return;
} else
head = &(*head)->next;
}
}
restore_flags(flags);
printk("Timer %p:%p not found\n", func,arg);
@ -188,7 +129,11 @@ int timeout(void (*func)(void *), void *arg, int expire)
timer->proc = func;
timer->arg = arg;
timer->tim.data = (unsigned long)timer;
timer->tim.expires = expire;
timer->tim.expires = expire
#if LINUX_VERSION_CODE >= 66304 /* 1.3.0 -- is that right ?? */
+ jiffies;
#endif
;
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
@ -220,11 +165,18 @@ void timeout_old(void (*func)(void *), void *arg, int expire)
timer->tim.arg = arg;
timer->tim.tim.function = (fct)dotimer_old;
timer->tim.tim.data = (unsigned long)timer;
timer->tim.tim.expires = expire;
s = spl6();
timer->tim.tim.expires = expire
#if LINUX_VERSION_CODE >= 66304 /* 1.3.0 -- is that right ?? */
+ jiffies;
#endif
;
save_flags(s); cli();
if(start != NULL)
start->prev = timer;
timer->next = start;
timer->prev = NULL;
start = timer;
splx(s);
restore_flags(s);
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
@ -385,7 +337,7 @@ char kernel_version[] = UTS_RELEASE;
int init_module(void)
{
#ifdef __ELF__
#if defined(__ELF__) || LINUX_VERSION_CODE >= 66304 /* 1.3.0. Is that right??? */
#define U
#else
#define U "_"

355
compat/compat.c.orig Normal file
View File

@ -0,0 +1,355 @@
#define COMPAT_C
/*
* Compatibility stuff for Streams-ish drivers and other stuff.
*
* Copyright 1994: Matthias Urlichs <urlichs@smurf.noris.de>
*/
#ifdef MODULE
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <linux/kernel.h>
#include <linux/delay.h>
#include <asm/delay.h>
/*
* compat.c
*
* provides some compatibility code for stuff written for non-Linux kernels
*
* Version 0.3 by Matthias Urlichs <urlichs@smurf.noris.de>
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/malloc.h>
#include <asm/system.h>
#include "compat.h"
unsigned long block_mask = 0;
const char *xdeb_file; unsigned int xdeb_line;
/*
* Standard Unix-kernel timeout code. Two versions -- the new version
* returns a pointer to its internal data, the old version doesn't, which
* means we have to scan for the thing in an internal list when
* deallocating the timer.
*/
struct timing {
struct timer_list tim;
void (*proc)(void *);
void *arg;
};
struct timing_old {
struct timing tim;
struct timing_old *prev;
struct timing_old *next;
};
static struct timing_old *start = NULL;
static void dotimer(void *arg)
{
struct timing *tim = (struct timing *)arg;
(*tim->proc)(tim->arg);
sti();
kfree_s(tim,sizeof(struct timing));
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
static void droptimer_old(void (*func)(void *), void *arg, char del)
{
struct timing_old *tim;
unsigned long flags;
save_flags(flags);
cli();
for(tim = start; tim != NULL; tim = tim->next) {
if(tim->tim.proc == func && tim->tim.arg == arg) {
if(tim->next != NULL)
tim->next->prev = tim->prev;
if(tim->prev != NULL)
tim->prev->next = tim->next;
else
start = tim->next;
restore_flags(flags);
if(del) {
del_timer(&tim->tim.tim);
kfree_s(tim,sizeof(struct timing_old));
}
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return;
}
}
restore_flags(flags);
printk("Timer %p:%p not found\n", func,arg);
}
static void dotimer_old(void *arg)
{
struct timing_old *tim = (struct timing_old *)arg;
droptimer_old(tim->tim.proc,tim->tim.arg,0);
(*tim->tim.proc)(tim->tim.arg);
sti();
kfree_s(tim,sizeof(*tim));
}
#ifdef CONFIG_MALLOC_NAMES
int deb_timeout(const char *deb_file, unsigned int deb_line, void (*func)(void *), void *arg, int expire)
#else
int timeout(void (*func)(void *), void *arg, int expire)
#endif
{
typedef void (*fct)(unsigned long);
struct timing *timer;
#ifdef CONFIG_MALLOC_NAMES
timer = (struct timing *)deb_kmalloc(deb_file,deb_line, sizeof(struct timing), GFP_ATOMIC);
#else
timer = (struct timing *)kmalloc(sizeof(struct timing), GFP_ATOMIC);
#endif
if(timer == NULL) {
printf(" *!* No Timeout!\n");
return (int)NULL;
}
init_timer(&timer->tim);
timer->tim.function = (fct)dotimer;
timer->proc = func;
timer->arg = arg;
timer->tim.data = (unsigned long)timer;
timer->tim.expires = expire
#if LINUX_VERSION_CODE >= 66318 /* 1.3.14 -- is that right ?? */
+ jiffies;
#endif
;
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
add_timer(&timer->tim);
return (int)timer;
}
#ifdef CONFIG_MALLOC_NAMES
void deb_timeout_old(const char *deb_file, unsigned int deb_line, void (*func)(void *), void *arg, int expire)
#else
void timeout_old(void (*func)(void *), void *arg, int expire)
#endif
{
typedef void (*fct)(unsigned long);
struct timing_old *timer;
int s;
#ifdef CONFIG_MALLOC_NAMES
timer = (struct timing_old *)deb_kmalloc(deb_file,deb_line, sizeof(struct timing_old), GFP_ATOMIC);
#else
timer = (struct timing_old *)kmalloc(sizeof(struct timing_old), GFP_ATOMIC);
#endif
if(timer == NULL) {
printf(" *!* No Timeout!\n");
return;
}
init_timer(&timer->tim.tim);
timer->tim.proc = func;
timer->tim.arg = arg;
timer->tim.tim.function = (fct)dotimer_old;
timer->tim.tim.data = (unsigned long)timer;
timer->tim.tim.expires = expire
#if LINUX_VERSION_CODE >= 66318 /* 1.3.14 -- is that right ?? */
+ jiffies;
#endif
;
save_flags(s); cli();
if(start != NULL)
start->prev = timer;
timer->next = start;
timer->prev = NULL;
start = timer;
restore_flags(s);
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
add_timer(&timer->tim.tim);
}
#ifdef CONFIG_MALLOC_NAMES
void deb_untimeout(const char *deb_file, unsigned int deb_line, int timer)
#else
void untimeout(int timer)
#endif
{
del_timer(&((struct timing *)timer)->tim);
#ifdef CONFIG_MALLOC_NAMES
deb_kfree_s(deb_file,deb_line, (void *)timer,sizeof(struct timing));
#else
kfree_s((void *)timer,sizeof(struct timing));
#endif
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
#ifdef CONFIG_MALLOC_NAMES
void deb_untimeout_old(const char *deb_file, unsigned int deb_line, void (*func)(void *), void *arg)
#else
void untimeout_old(void (*func)(void *), void *arg)
#endif
{
droptimer_old(func,arg,1);
}
int crash_time = 300; /* Five minutes until reboot */
#define get_seg_long(seg,addr) ({ \
register unsigned long __res; \
__asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \
:"=a" (__res):"0" (seg),"m" (*(addr))); \
__res;})
void sysdump(const char *msg, struct pt_regs *regs, unsigned long err)
{
int i,nlim=9;
unsigned long flags;
unsigned long esp;
unsigned short ss;
unsigned int dodump=100;
#if 1
static unsigned long lticks = 0;
if(jiffies-lticks < HZ) {
printk("."); return;
}
#endif
save_flags(flags); cli();
if(err != 0xf00fdead) {
if(regs == NULL)
esp = (unsigned long) &msg;
else
esp = (unsigned long) &regs->esp;
ss = KERNEL_DS;
printk(KERN_DEBUG "\n");
if(msg != NULL)
printk(KERN_EMERG "%s: %08lx\n", msg, err);
else
nlim += 4;
if(regs != NULL) {
printk(KERN_EMERG "EIP: %04x:%08lx EFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
regs->eax, regs->ebx, regs->ecx, regs->edx);
printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
regs->esi, regs->edi, regs->ebp, esp);
printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
regs->ds, regs->es, regs->fs, regs->gs, ss);
if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
printk(KERN_EMERG "Corrupted stack page\n");
else
nlim += 1;
} else
nlim += 5;
store_TR(i);
if(current != NULL) {
printk(KERN_EMERG "Process %s (pid: %d, process nr: %d, stackpage=%08lx)\n",
current->comm, current->pid, 0xffff & i, current->kernel_stack_page);
} else {
printk(KERN_EMERG "No current process\n");
}
{
int nlines = 0, linepos = 0;
printk(KERN_EMERG "");
for (i=0; dodump && nlines < nlim; i++) {
u_long xx = get_seg_long(ss,(i+(unsigned long *)esp));
if(dodump > 1 && (xx & 0xfff00000) == 0xbff00000)
dodump = 4;
#define WRAP(n) do { if((linepos+=(n))>=80) { dodump--; nlines++; linepos=(n); printk("\n" KERN_EMERG); } } while(0)
if (xx & 0xFF000000UL) { WRAP(9); printk("%08lx ",xx); }
else if(xx & 0x00FF0000UL) { WRAP(7); printk("%06lx ",xx); }
else if(xx & 0x0000FF00UL) { WRAP(5); printk("%04lx ",xx); }
else { WRAP(3); printk("%02lx ",xx); }
#undef WRAP
}
printk("\n");
}
}
dodump=0;
if(err == 0xDEADBEEF)
dodump=0;
else if(err == 0xF00DDEAD || err == 0xf00fdead)
dodump=(crash_time ? crash_time : 60);
else if(jiffies < 60*HZ)
dodump=9999999;
else
dodump=crash_time;
if(dodump>0) {
if(dodump < 10000) {
int j;
printk(KERN_EMERG "Crash & Burn...");
for(j=dodump;j>0;j--) {
int i;
if((j%30 == 0) || (j%5 == 0 && j < 60) || j < 10) printk("%d...",j);
for(i=0;i<9990;i++) udelay(100);
}
panic("now.");
} else {
printk(KERN_EMERG "Kernel halted.");
for(;;);
}
}
restore_flags(flags);
}
void do_i_sleep_on(struct wait_queue **p)
{
long s = splx(~0);
interruptible_sleep_on(p);
splx(s);
}
void do_sleep_on(struct wait_queue **p)
{
long s = splx(~0);
sleep_on(p);
splx(s);
}
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
int init_module(void)
{
#if defined(__ELF__) || LINUX_VERSION_CODE >= 66304 /* 1.3.0. Is that right??? */
#define U
#else
#define U "_"
#endif
rename_module_symbol(U "do_i_sleep_on",U "interruptible_sleep_on");
rename_module_symbol(U "do_sleep_on",U "sleep_on");
return 0;
}
int cleanup_module(void)
{
return 0;
}
#endif

View File

@ -19,8 +19,14 @@
#include <asm/segment.h>
#ifndef COMPAT_C
#ifdef interruptible_sleep_on
#undef interruptible_sleep_on
extern void interruptible_sleep_on(struct wait_queue ** p);
#endif
#ifdef sleep_on
#undef sleep_on
extern void sleep_on(struct wait_queue ** p);
#endif
#endif
#else

View File

@ -18,7 +18,7 @@ DESTDIR /usr/local/isdn
##
## What to name the lockfiles.
#### =()<LOCKNAME @<LOCKNAME>@>()=
LOCKNAME /var/spool/uucp/LCK..%s
LOCKNAME /var/lock/LCK..%s
##
## Name of the "KERNEL" flag in system include files (KERNEL, _KERNEL, INKERNEL)
@ -53,13 +53,13 @@ MLEVEL 3
P
## C pre-processor flags for normal programs.
#### =()<DEFS @<DEFS>@>()=
DEFS -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd
DEFS -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd
## C pre-processor flags for kernel code.
## Don't include any KERNEL flags.
#### =()<DEFKERNEL @<DEFKERNEL>@>()=
DEFKERNEL -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer
DEFKERNEL -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer
## C pre-processor flags for ISDN card support
#### =()<DEFSCARDS @<DEFCARDS>@>()=
#### =()<DEFCARDS @<DEFCARDS>@>()=
DEFCARDS -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops
###
## C compiler for the kernel
@ -67,8 +67,8 @@ DEFCARDS -I../../streams -I../../compat -fomit-frame-pointer -funroll-loops
CC gcc
###
## C compiler for the utilities
#### =()<CC @<CC>@>()=
CCU gcc -g
#### =()<CCU @<CCU>@>()=
CCU gcc
##
## common C compiler flags
#### =()<CFLAGS @<CFLAGS>@>()=
@ -161,48 +161,18 @@ DEBUGGING DO
CONF_MOD2 0x00
## 0x00, 0x33
#### =()<CONF_DEBUG @<CONF_DEBUG>@>()=
CONF_DEBUG 0x5006
CONF_DEBUG 0x0000
## 0x5006, 0xf3df
### ISDN configuration options
## One TEI per B channel? Seems to be required for US National-1.
## DO or DONT.
## DO or DONT. DO is currently not supported by the L3 driver.
#### =()<MULTI_TEI @<MULTI_TEI>@>()=
MULTI_TEI DONT
##
## Take down Level 2 if idle? (Some PBXes don't like this.)
#### =()<L2_DOWN @<L2_DOWN>@>()=
L2_DOWN DO
##
## Grab a TEI when starting up?
## Turn this on if the first incoming call is answered too late.
## The standards say not to get a TEI at startup, but we may be too slow
## otherwise.
#### =()<TEI_IMMEDIATE @<TEI_IMMEDIATE>@>()=
TEI_IMMEDIATE DONT
##
## Use a "frozen" random number for TEI assignment, and try a fixed TEI
## if assignment of a variable TEI fails?
## Necessary with some PBXes; doesn't seem to hurt anywhere.
#### =()<TEI_FIXED @<TEI_FIXED>@>()=
TEI_FIXED DO
##
## Immediately answer when an incoming call is detected?
## Turn this on if some incoming calls are answered too late.
## (Useful for slow systems with lots of debugging, or if things are
## run over NFS.)
## The standards say not to do this.
#### =()<ANSWER_IMMEDIATE @<ANSWER_IMMEDIATE>@>()=
ANSWER_IMMEDIATE DONT
##
## Delay when establishing a connection. Range: 1..HZ*2.
## Use this when the ISDN switch has problems with accepting data
## immediately after establishing a connection.
#### =()<UP_DELAY @<UP_DELAY>@>()=
UP_DELAY (HZ / 2)
### the other configuration stuff is now per-card, see DOKU.
##
## What to call protocol stuff. M_EXPROTO or (M_PROTO+0x40)
@ -210,7 +180,7 @@ UP_DELAY (HZ / 2)
MSG_PROTO M_EXPROTO
##
## What to call hopefully-expedited data stuff. M_EXDATA or (M_DATA+0x40).
#### =()<MSG_DATA @<MSG_DATA>@>()=
#### =()<MSG_EXDATA @<MSG_EXDATA>@>()=
MSG_EXDATA M_EXDATA
##
## What to call normal data stuff. M_DATA

0
isdn/config/config.data.pc → config/config.data.pc Executable file → Normal file
View File

View File

@ -49,7 +49,7 @@ CFLAGS $(DEFS) -g -O2 -W -Wreturn-type -Wshadow -Wcomment
#CFLAGS $(DEFS) -g -W -Wreturn-type -Wshadow -Wcomment -D_BSD_SOURCE -D_SYSV_SOURCE
## Flags for the "cc -o" line; e.g., -Bstatic on SunOS4.x while debugging.
#### =()<LDFLAGS @<LDFLAGS>@>()=
LDFLAGS
LDFLAGS
##
## If you need to link in other libraries, add them here
#### =()<LIBS @<LIBS>@>()=

View File

@ -1,14 +1,17 @@
;; List of isdn files that are fed to subst.
;; Lines beginning with a semi-colon are comment lines.
../arnet/Makefile
../rate/Makefile
../alaw/Makefile
../compat/Makefile
../streams/Makefile
;; ../cards/leonardo/Makefile
;; ../ppp_if/Makefile
../cards/Makefile
../cards/arnet/Makefile
../cards/dumb/Makefile
../cards/bintec/Makefile
../config/Makefile
../tools/Makefile
../include/config.h
../include/f_strings.h
../include/f_termio.h
@ -23,7 +26,7 @@
;; ../portman/Makefile
../pr_on/Makefile
../str_if/Makefile
../strppp/Makefile
;; ../strppp/Makefile
../strslip/Makefile
../support/Makefile
../timer/Makefile

View File

@ -1,3 +1,5 @@
/* This is from INN. */
/* $Revision: 1.10 $
**
** A C version of Henry Spencer's "subst" script.

View File

@ -6,11 +6,11 @@ P =
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
## =()<DEFSN = @<DEFS>@ >()=
DEFSN = -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd
DEFSN = -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd
## =()<CFLAGSN = @<CFLAGS>@ $(DEFSN)>()=
CFLAGSN = -O2 -Wall $(DEFSN)
@ -43,7 +43,7 @@ clean:
@sh ../iftrue.sh "-d $(SYS)" "cd $(SYS); make clean"
load: all
load:
insmod fakeh.o
ifeq (.depend,$(wildcard .depend))

View File

@ -1,6 +1,8 @@
/**
** Streams FAKEH module
** Streams FAKEH module, used to pretend we're a Cisco box.
** Do turn off keepalives at the other end!
**/
#undef DO_KEEPALIVES /* not yet..! */
#include "f_module.h"
#include "primitives.h"
@ -52,18 +54,22 @@ struct fakeh_ {
queue_t *qptr;
ushort_t offset;
unsigned connected:1;
unsigned do_ethertype:1;
#ifdef DO_KEEPALIVES
int timer;
#ifdef NEW_TIMEOUT
int timeout;
#endif
unsigned connected:1;
unsigned long last_a;
unsigned long last_b;
unsigned long last_c;
unsigned long last_d;
unsigned char lastmap[4];
#endif
};
#ifdef DO_KEEPALIVES
static void
fake_h_timer (struct fakeh_ *fakeh)
{
@ -111,27 +117,25 @@ fake_h_timer (struct fakeh_ *fakeh)
timeout ((void *)fake_h_timer, fakeh, fakeh->timer * HZ);
splx(s);
}
#endif /* DO_KEEPALIVES */
/* Streams code to open the driver. */
static int
fakeh_open (queue_t * q, dev_t dev, int flag, int sflag
#ifdef DO_ADDERROR
,int *err
#endif
)
fakeh_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
{
register struct fakeh_ *fakeh;
fakeh = malloc(sizeof(*fakeh));
if(fakeh == NULL)
return OPENFAIL;
ERR_RETURN(-ENOMEM);
memset(fakeh,0,sizeof(*fakeh));
WR (q)->q_ptr = (char *) fakeh;
q->q_ptr = (char *) fakeh;
fakeh->qptr = q;
fakeh->connected = 0;
#ifdef DO_KEEPALIVES
fakeh->last_a = 0;
fakeh->last_b = 0;
fakeh->last_c = 0;
@ -140,6 +144,7 @@ fakeh_open (queue_t * q, dev_t dev, int flag, int sflag
fakeh->lastmap[1] = 2;
fakeh->lastmap[2] = 1;
fakeh->lastmap[3] = 0;
#endif
MORE_USE;
return 0;
@ -157,6 +162,7 @@ fakeh_close (queue_t * q, int dummy)
flushq (WR (q), FLUSHALL);
fakeh->qptr = NULL;
#ifdef DO_KEEPALIVES
if (fakeh->connected & (fakeh->timer > 0)) {
#ifdef NEW_TIMEOUT
untimeout (fakeh->timeout);
@ -164,6 +170,7 @@ fakeh_close (queue_t * q, int dummy)
untimeout (fake_h_timer, ipmon);
#endif
}
#endif
free(fakeh);
LESS_USE;
@ -177,6 +184,7 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
register struct fakeh_ *fakeh = (struct fakeh_ *) q->q_ptr;
streamchar *origmp = mp->b_rptr;
ushort_t id;
int error = 0;
if (m_getid (mp, &id) != 0) {
mp->b_rptr = origmp;
@ -194,26 +202,32 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
goto err;
if(!down) {
fakeh->offset = z;
z += 4;
if(fakeh->do_ethertype)
z += 2;
else
z += 4;
freemsg(mp);
if((mp = allocb(10,BPRI_MED)) != NULL) {
m_putid(mp,PROTO_OFFSET);
m_puti(mp,z);
mp->b_datap->db_type = MSG_PROTO;
DATA_TYPE(mp) = MSG_PROTO;
origmp = NULL;
}
}
} break;
case PROTO_CONNECTED:
fakeh->connected = 1;
#ifdef DO_KEEPALIVES
if (fakeh->timer > 0) {
#ifdef NEW_TIMEOUT
fakeh->timeout =
#endif
timeout ((void *)fake_h_timer, fakeh, fakeh->timer * HZ);
}
#endif
break;
case PROTO_DISCONNECT:
#ifdef DO_KEEPALIVES
if(fakeh->connected && (fakeh->timer > 0)) {
#ifdef NEW_TIMEOUT
untimeout (fakeh->timeout);
@ -221,32 +235,44 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
untimeout (fake_h_timer, ipmon);
#endif
}
#endif
fakeh->connected = 0;
break;
case PROTO_MODULE:
if (strnamecmp (q, mp)) { /* Config information for me. */
#ifdef DO_KEEPALIVES
long z;
#endif
while (mp != NULL && m_getsx (mp, &id) == 0) {
switch (id) {
default:
goto err;
case PROTO_MODULE:
break;
case PROTO_TYPE_NONE:
fakeh->do_ethertype = 0;
break;
case PROTO_TYPE_ETHER:
fakeh->do_ethertype = 1;
break;
#ifdef DO_KEEPALIVES
case FAKEH_SETMAP:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
fakeh->lastmap[0] = z;
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
fakeh->lastmap[1] = z;
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
fakeh->lastmap[2] = z;
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
fakeh->lastmap[3] = z;
break;
case FAKEH_TIMEOUT:
if (m_geti (mp, &z) != 0)
if ((error = m_geti (mp, &z)) != 0)
goto err;
if ((z < 4 || z >= 4090) && (z != 0))
goto err;
@ -257,6 +283,7 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
timeout ((void *)fake_h_timer, fakeh, fakeh->timer * HZ);
fakeh->timer = z;
break;
#endif
}
}
if (mp != NULL) {
@ -274,7 +301,7 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
return;
err:
mp->b_rptr = origmp;
m_reply (q, mp, EINVAL);
m_reply (q, mp, error ? error : -EINVAL);
}
@ -282,9 +309,9 @@ fakeh_proto (queue_t * q, mblk_t * mp, char down)
static void
fakeh_wput (queue_t * q, mblk_t * mp)
{
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
CASE_DATA
case CASE_DATA:
putq (q, mp);
break;
case M_FLUSH:
@ -307,33 +334,43 @@ fakeh_wsrv (queue_t * q)
mblk_t *mp;
while ((mp = getq (q)) != NULL) {
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
fakeh_proto (q, mp, 1);
break;
CASE_DATA
case CASE_DATA:
{
mblk_t *mh;
short offlen;
if (!canput (q->q_next)) {
putbq (q, mp);
return;
}
if (/* XXX */ 0 || mp->b_datap->db_ref > 1 ||
mp->b_datap->db_base > mp->b_rptr - 4) {
mh = allocb(fakeh->offset+4,BPRI_LO);
if(fakeh->do_ethertype)
offlen = 2;
else
offlen = 4;
if (/* XXX */ 0 || DATA_REFS(mp) > 1 ||
DATA_START(mp) > mp->b_rptr - offlen) {
mh = allocb(fakeh->offset+offlen,BPRI_LO);
if(mh == NULL) {
putbqf(q,mp);
return;
}
mh->b_datap->db_type = mp->b_datap->db_type;
mh->b_rptr += fakeh->offset+4;
mh->b_wptr += fakeh->offset+4;
DATA_TYPE(mh) = DATA_TYPE(mp);
mh->b_rptr += fakeh->offset+offlen;
mh->b_wptr += fakeh->offset+offlen;
linkb (mh, mp);
mp = mh;
}
mp->b_rptr -= 4;
*(long *)mp->b_rptr = htonl(0x0F000800);
if(fakeh->do_ethertype) {
mp->b_rptr -= 2;
*(short *)mp->b_rptr = htons(0x0F00);
} else {
mp->b_rptr -= 4;
*(long *)mp->b_rptr = htonl(0x0F000800);
}
putnext (q, mp);
}
break;
@ -342,7 +379,7 @@ fakeh_wsrv (queue_t * q)
flushq (q, FLUSHDATA);
/* FALL THRU */
default:
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
putnext (q, mp);
continue;
} else {
@ -358,7 +395,7 @@ fakeh_wsrv (queue_t * q)
static void
fakeh_rput (queue_t * q, mblk_t * mp)
{
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case M_FLUSH:
if (*mp->b_rptr & FLUSHR) {
@ -367,7 +404,7 @@ fakeh_rput (queue_t * q, mblk_t * mp)
putnext (q, mp); /* send it along too */
break;
case MSG_PROTO:
CASE_DATA
case CASE_DATA:
putq (q, mp); /* queue it for my service routine */
break;
@ -385,11 +422,11 @@ fakeh_rsrv (queue_t * q)
register struct fakeh_ *fakeh = (struct fakeh_ *) q->q_ptr;
while ((mp = getq (q)) != NULL) {
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
fakeh_proto (q, mp, 0);
break;
CASE_DATA
case CASE_DATA:
{
unsigned long xhdr;
short tlen = dsize (mp);
@ -409,20 +446,32 @@ fakeh_rsrv (queue_t * q)
return;
}
mp = mq;
xhdr = *(long *)mp->b_rptr & ntohl(0xFF00FFFF);
mp->b_rptr += 4;
if (xhdr != ntohl(0x0F000800)) {
if(fakeh->do_ethertype) {
xhdr = *(short *)mp->b_rptr & htons(0xFF00);
mp->b_rptr += 2;
} else {
xhdr = *(long *)mp->b_rptr & htonl(0xFF00FFFF);
mp->b_rptr += 4;
}
if (xhdr != (fakeh->do_ethertype ? htons(0x0F00) : htonl(0x0F000800))) {
#ifdef DO_KEEPALIVES
if(fakeh->do_ethertype) {
mp->b_rptr -= 2;
xhdr = *(long *)mp->b_rptr & htonl(0xFF00FFFF);
mp->b_rptr += 4;
}
if(xhdr == ntohl(0x8F008035)) {
mq = pullupm(mp,12);
if (mq == NULL) {
freemsg (mp);
return;
continue;
}
mp = mq;
fakeh->last_a = *(long *)mp->b_rptr++;
fakeh->last_b = *(long *)mp->b_rptr++;
fakeh->last_c = *(long *)mp->b_rptr++;
}
#endif
freemsg(mp);
continue;
}
@ -433,7 +482,7 @@ fakeh_rsrv (queue_t * q)
case M_ERROR:
/* FALL THRU */
default:
if (mp->b_datap->db_type > QPCTL || canput (q->q_next)) {
if (DATA_TYPE(mp) > QPCTL || canput (q->q_next)) {
putnext (q, mp);
continue;
} else {

View File

@ -6,9 +6,9 @@ SYS = linux
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ >()=
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
CFLAGS = -g -O2 -Wall $(DEFS)
## =()<SYS = @<SYS>@>()=
SYS = linux
@ -18,10 +18,10 @@ DESTDIR = /usr/local/isdn
SOURCES = x75.c
doinstall:
@cd .. && make install
#@$(MAKE) $(MAKEFLAGS) -C .. install
install.sys:
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && make install \
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && $(MAKE) $(MAKEFLAGS) install \
CFLAGS=\"$(CFLAGS)\" CC=\"$(CC)\""
if test ! -d ${DESTDIR} ; then mkdir ${DESTDIR} ; else true ; fi
if test ! -d ${DESTDIR}/bin ; then mkdir ${DESTDIR}/bin ; else true ; fi
@ -41,10 +41,10 @@ install.bin:
install: install.sys
clean:
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && make clean"
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && $(MAKE) $(MAKEFLAGS) clean"
run:
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && make run"
@sh ../iftrue.sh "-f $(SYS)/Makefile" "cd $(SYS) && $(MAKE) $(MAKEFLAGS) run"
lib:

View File

@ -13,9 +13,6 @@
typedef unsigned char streamchar;
#endif
/* =()<#define UP_DELAY @<UP_DELAY>@>()= */
#define UP_DELAY (HZ / 2)
#ifdef KERNEL
/* =()<#define @<NEED_SPL>@_NEED_SPL>()= */
#define DONT_NEED_SPL
@ -45,7 +42,7 @@ typedef unsigned char streamchar;
/* =()<#define CONF_MOD2 @<CONF_MOD2>@>()= */
#define CONF_MOD2 0x00
/* =()<#define CONF_DEBUG @<CONF_DEBUG>@>()= */
#define CONF_DEBUG 0x5006
#define CONF_DEBUG 0x0000
#else
#ifdef DO_DEBUGGING
@ -87,18 +84,6 @@ extern char *strdup (const char *xx);
extern int writev(int fd, struct iovec *vp, int vpcount);
#endif
/* =()<#define @<ANSWER_IMMEDIATE>@_ANSWER_IMMEDIATE>()= */
#define DONT_ANSWER_IMMEDIATE
/* =()<#define @<TEI_FIXED>@_TEI_FIXED>()= */
#define DO_TEI_FIXED
/* =()<#define @<TEI_IMMEDIATE>@_TEI_IMMEDIATE>()= */
#define DONT_TEI_IMMEDIATE
/* =()<#define @<L2_DOWN>@_L2_DOWN>()= */
#define DO_L2_DOWN
/* =()<#define @<MULTI_TEI>@_MULTI_TEI>()= */
#define DONT_MULTI_TEI
@ -106,6 +91,6 @@ extern int writev(int fd, struct iovec *vp, int vpcount);
#define ROUTE_PATH "/sbin/route"
/* =()<#define LOCKNAME "@<LOCKNAME>@">()= */
#define LOCKNAME "/var/lock/uucp/LCK..%s"
#define LOCKNAME "/var/lock/LCK..%s"
#endif /* _CONFIG_H */

View File

@ -55,6 +55,7 @@
#include <linux/icmp.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/if_ether.h>
#define ADR(x) x /* in struct ip */
#define _F_DONE
#endif

View File

@ -2,6 +2,7 @@
#if defined (linux) && defined(__KERNEL__) && defined(MODULE)
#define _HAS_MODULE
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
@ -19,10 +20,7 @@ int init_module(void)
}
void cleanup_module( void) {
if (MOD_IN_USE)
printk(KERN_INFO "module is in use, remove delayed\n");
else
do_exit_module();
do_exit_module();
}
#endif
#define MORE_USE MOD_INC_USE_COUNT

View File

@ -24,6 +24,10 @@
struct _isdn1_card;
/*
* Download boot code.
*/
typedef int (*C_boot)(struct _isdn1_card * card, int step, int offset, mblk_t *data);
/*
* Initiate mode changes. For the D channel, zero means to turn off L1; one
* turns L1 back on. For the B channels, see M_*. "listen" on the B
@ -39,8 +43,13 @@ typedef int (*C_ch_mode) (struct _isdn1_card * card, short channel, char mode,
* driver program.
*/
typedef int (*C_ch_prot) (struct _isdn1_card * card, short channel, mblk_t * proto, int flags);
#define CHP_BACKCHAN 01 /* Back channel from the stack to the card */
#define CHP_MODLIST 02 /* includes a module list */
#define CHP_FROMSTACK 01 /* travels from the channel to the master */
#define CHP_MODLIST 02 /* module list */
/*
* Check if the card has data for us.
*/
typedef int (*C_poll) (struct _isdn1_card * card, short channel);
/*
* Check if buffer space is available
@ -62,7 +71,9 @@ struct _isdn1_card {
* one. */
void *ctl; /* Pointer for L1 data structures, card
* drivers must not touch this. */
#if 0
struct _isdn_chan *chan; /* Pointer to array. First is the D channel. */
#endif
ulong_t modes; /* Modes available on this card. */
#define CHM_INTELLIGENT 01 /* If this bit is set, the card is clever and modes>>1 has the ID of the high-level driver. */
@ -71,6 +82,8 @@ struct _isdn1_card {
C_data send;
C_flush flush;
C_candata cansend;
C_poll poll; /* check if the card can send more data */
C_boot boot;
};
/**
@ -93,8 +106,6 @@ extern int isdn2_unregister (struct _isdn1_card *card);
*/
extern void isdn2_new_state (struct _isdn1_card *card, char state);
extern void isdn2_new_proto (struct _isdn1_card *card, short channel, mblk_t * proto);
/*
* Callback to test availability of queue space. Cards are not required to call
* this.
@ -117,7 +128,7 @@ extern int isdn2_recv (struct _isdn1_card *card, short channel, mblk_t * data);
extern int isdn2_backenable (struct _isdn1_card *card, short channel);
/*
* Callback for mode setup.
* Callback for protocol setup.
*/
extern int isdn2_chprot (struct _isdn1_card * card, short channel, mblk_t * proto, int flags);

View File

@ -27,7 +27,9 @@ enum M_state {
typedef struct _isdn2_chan {
queue_t *qptr; /* read queue (i.e. going up) for Streams */
struct _isdn2_card *card; /* NULL if not assigned to a card */
#if 0
struct _isdn_chan *chan; /* B channel: data buffer */
#endif
mblk_t *bufx;
#ifdef NEW_TIMEOUT
int timer_unblock;
@ -55,7 +57,7 @@ enum C_state {
typedef struct _isdn2_card {
struct _isdn1_card *card;
struct _isdn2_card *next;
struct _isdn2_chan *chan[MAXCHAN]; /* pointer to B/D channels */
struct _isdn2_chan *chan[MAXCHAN+1]; /* pointer to B/D channels */
#ifdef DO_MULTI_TEI
struct _isdn2_state *state[MAX_B];
#else

View File

@ -97,6 +97,8 @@ typedef struct _isdn23_hdr {
* compared */
uchar_t card; /* Card ID. Counting up from zero. */
uchar_t bchans;
uchar_t flags; /* Some stuff */
#define HDR_CARD_PP 01
long id; /* Unique ID of this card, for hardware
* config. Usually the first three characters
* identify the card and the last is a serial
@ -146,11 +148,6 @@ typedef struct _isdn23_hdr {
/* invalid isdn23_hdr follows */
} _hdr_inval; /* Note: There's usually no need to analyze
* the errors. */
#ifdef DO_BOOT
struct { /* Report an error: invalid command */
int doboot;
} _hdr_boot;
#endif
struct { /* Get/Set the TEI for a card */
uchar_t card;
uchar_t TEI; /* TEI_BROADCAST means the TEI is unassigned */
@ -161,6 +158,11 @@ typedef struct _isdn23_hdr {
* feature. However, the implementation gets
* somewhat cleaner if the TEI negotiation
* handler is just another L3 protocol */
struct {
uchar_t card;
int seqnum;
int foffset;
} _hdr_load; /* download some code to the card */
/*
* Setting the TEI to TEI_BROADCAST does the Right Thing WRT to
* protocol handlers.
@ -187,9 +189,7 @@ typedef struct _isdn23_hdr {
#define hdr_notify sel._hdr_notify /* I */
#define hdr_inval sel._hdr_inval /* Z */
#define hdr_tei sel._hdr_tei /* K */
#ifdef DO_BOOT
#define hdr_boot sel._hdr_boot /* B */
#endif
#define hdr_load sel._hdr_load /* L */
/* Magic numbers. */
@ -210,9 +210,7 @@ typedef struct _isdn23_hdr {
#define HDR_INVAL 15
#define HDR_TEI 16
#define HDR_PROTOCMD 17
#ifdef DO_BOOT
#define HDR_BOOT 18
#endif
#define HDR_LOAD 18
#define HDR_FLAGS 0x80
#define HDR_NOERROR 0x80

View File

@ -214,6 +214,7 @@ typedef struct _isdn3_conn {
#define MS_DELAYING 040000 /* Wait a bit */
#define MS_INITPROTO 0100000 /* card protocols set */
#define MS_INITPROTO_SENT 0200000 /* asked for setup */
#define MS_NOMINOR 0400000
/*
* if set and ms->delay == zero, we got killconn. This is a hack but there are
* no more bits free.
@ -374,6 +375,24 @@ void isdn3_repeat (isdn3_conn conn, ushort_t id, mblk_t * data);
*/
void conn_info (isdn3_conn conn, mblk_t * mb);
/*
* Extract flags from conn info.
*/
long isdn3_flags(mblk_t *info, uchar_t protocol, uchar_t subprot);
#define FL_UPDELAY 017
#define FL_UPDELAY_SHIFT 3
#define FL_L2KEEP 020 /* default is to close L2 */
#define FL_TEI_IMMED 040 /* default is to do that later */
#define FL_POINTOPOINT 0100 /* point-to-point */
#define FL_MULTIPOINT1 0200 /* variable ID */
#define FL_MULTIPOINT2 0000 /* fixed ID; special -> default */
#define FL_MULTIPOINT3 0300 /* fixed TEI */
#define FL_POINTMASK 0300
#define FL_ANS_IMMED 0400 /* default is to delay */
/**
* Convenience macros for handling connection timeouts.
*
@ -394,7 +413,7 @@ void conn_info (isdn3_conn conn, mblk_t * mb);
#define timer(T,c) TIMER(T,c,T,VAL_##T,RUN_##T)
#define FTIMER(T,c,w,v,f) do { if(!((c)->timerflags & f)) { timeout(w,(c),v); (c)->timerflags |= f; } } while(0)
#define ftimer(T,c) FTIMER(T,c,T,VAL_##T,RUN_##T)
#define RTIMER(T,c,w,v,f) do { if((c)->timerflags & f) { timeout(w,(c),v); } } while(0)
#define RTIMER(T,c,w,v,f) do { if((c)->timerflags & f) { untimeout(w,(c)); timeout(w,(c),v); } } while(0)
#define rtimer(T,c) RTIMER(T,c,T,VAL_##T,RUN_##T)
#endif /* _ISDN_3 */

View File

@ -24,6 +24,8 @@
#define PREF_NOERR '=' /* Prefix to disable error replies */
#define CMD_LOADFILE CHAR2('l','F') /* download part of a file */
#define CMD_FAKEOPEN CHAR2('f','o') /* Indicate that a /dev/isdn device has
* been opened. This is used to avoid a
* possible race condition */
@ -91,15 +93,14 @@
#define IND_NOCARD CHAR2 ('C','n') /* Card going offline. IND_NOCARD
* arg_card. */
#ifdef DO_BOOT
#define IND_BOOT CHAR2('B','T')
#endif
/*
* Arguments. short,long,uchar are encoded decimally, ushort and ulong as
* unsigned hex, ident as four letters, strings as-is.
*/
#define ARG_PREFOUT CHAR2('x','i') /* drop an incoming call */
#define ARG_FORCEOUT CHAR2('y','i') /* not implemented yet */
#define ARG_PREFOUT CHAR2('x','i') /* drop an incoming call if we're also calling out */
#define ARG_FORCEOUT CHAR2('y','i') /* always call back instead of accepting */
#define ARG_BACKCALL CHAR2('b','i') /* call back if incoming call rejected because busy */
#define ARG_NOREJECT CHAR2('n','j') /* don't send REJ code */
#define ARG_FASTDROP CHAR2('f','X')
#define ARG_FASTREDIAL CHAR2('f','r')
#define ARG_IGNORELIMIT CHAR2('i','l')
@ -133,6 +134,10 @@
#define ARG_OUTNUMS CHAR2 ('o','m') /* outgoing, for build */
#define ARG_INNUMS CHAR2 ('i','m') /* incoming, for match */
#define ARG_BOTHNUMS CHAR2 ('b','m') /* in+out, default */
#define ARG_NEEDLOCAL CHAR2('v','l') /* local numer required, incoming */
#define ARG_NEEDREMOTE CHAR2('v','r') /* remote numer required, incoming */
#define ARG_NEEDNOLOCAL CHAR2('V','l') /* local numer missing; incoming */
#define ARG_NEEDNOREMOTE CHAR2('V','r') /* remote numer missing; incoming */
#define ARG_SERVICE CHAR2 ('s','v') /* ulong service type. */
#define ARG_BEARER CHAR2 ('v','B') /* vector Bearer Capability. */
#define ARG_LLC CHAR2 ('v','L') /* vector Lower Level Compat. */
@ -154,6 +159,26 @@
#define ARG_UID CHAR2('u','i') /* uid of whoever opened the device */
#define ARG_GID CHAR2('g','i') /* gid of whoever opened the device */
#define ARG_CHARGE CHAR2('C','I') /* what's it cost */
#define ARG_SEQNUM CHAR2('s','N') /* number of the file */
#define ARG_OFFSET CHAR2('o','F') /* offset within the file */
#define ARG_UPDELAY CHAR2('u','d') /* Delay the data exchange */
#define ARG_POINTOPOINT CHAR2('p','p') /* point-to-point link */
#define ARG_MULTIPOINT1 CHAR2('m','p') /* multipoint link, variable ID */
#define ARG_MULTIPOINT2 CHAR2('m','f') /* multipoint link, fixed ID */
#define ARG_MULTIPOINT3 CHAR2('m','t') /* multipoint link, fixed TEI */
#define ARG_ANSWER_IMMED CHAR2('a','i') /* grab the TEI on startup */
#define ARG_ANSWER_DELAY CHAR2('a','d') /* grab the TEI when needed */
#define ARG_TEI_IMMED CHAR2('t','i') /* grab the TEI on startup */
#define ARG_TEI_DELAY CHAR2('t','d') /* grab the TEI when needed */
#define ARG_L2KEEP CHAR2('k','l') /* keep L2 open */
#define ARG_L2CLOSE CHAR2('c','l') /* close L2 when no connection is pending */
/* Other arguments are protocol dependent. See the appropriate include files. */
#define LISTARG_CONN CHAR2 ('L','C')

View File

@ -3,7 +3,7 @@
#define MINOR_MAX 240
#define MAX_B 2 /* max # of B channels per card */
#define MAX_B 31 /* max # of B channels per card */
#define MAX_D 3 /* max # D channel data connections, i.e. X25 */
#define MAXCHAN (MAX_B+MAX_D)
#define NMINOR MINOR_MAX

View File

@ -39,6 +39,9 @@
#define PROTO_OUTGOING CHAR2('o','u') /* Outgoing call. */
#define PROTO_OFFSET CHAR2('o','s') /* do mblk preallocation */
#define PROTO_TICK CHAR2('t','k') /* sync the timers */
#define PROTO_DATA_IN CHAR2('d','I') /* data are flowing in; for external measuerment */
#define PROTO_DATA_OUT CHAR2('d','O') /* data are flowing out; for external measuerment */
#define PROTO_AT CHAR2('a','t') /* Command. "*at ATD9612521". */
#define PROTO_MODULE CHAR2('m','s') /* Setup for a protocol */
@ -84,4 +87,17 @@
* taking down the connection.
*/
/**
** Common per-module arguments.
**/
#define PROTO_TYPE_NONE CHAR2('.','N')
#define PROTO_TYPE_ETHER CHAR2('.','E')
#define PROTO_TYPE_PPP CHAR2('.','P')
/*
* Set the encapsulation type. PROTO_TYPE_NONE means either no networking
* data, or IP only.
*/
#endif /* _ISDN_PROTO */

View File

@ -20,17 +20,17 @@
#if MSG_DATA != MSG_EXDATA
#if M_DATA != MSG_DATA
#define CASE_DATA case M_DATA: case MSG_DATA: case MSG_EXDATA: case M_EXDATA:
#define CASE_DATA M_DATA: case MSG_DATA: case MSG_EXDATA: case M_EXDATA
#else
#define CASE_DATA case MSG_DATA: case MSG_EXDATA: case M_EXDATA:
#define CASE_DATA MSG_DATA: case MSG_EXDATA: case M_EXDATA
#endif
#else
#if M_DATA != MSG_DATA
#define CASE_DATA case M_DATA: case MSG_DATA: case M_EXDATA:
#define CASE_DATA M_DATA: case MSG_DATA: case M_EXDATA
#else
#define CASE_DATA case M_DATA: case M_EXDATA:
#define CASE_DATA M_DATA: case M_EXDATA
#endif
#endif
@ -38,17 +38,17 @@
#if MSG_DATA != MSG_EXDATA
#if M_DATA != MSG_DATA
#define CASE_DATA case M_DATA: case MSG_DATA: case MSG_EXDATA:
#define CASE_DATA M_DATA: case MSG_DATA: case MSG_EXDATA
#else
#define CASE_DATA case MSG_DATA: case MSG_EXDATA:
#define CASE_DATA MSG_DATA: case MSG_EXDATA
#endif
#else
#if M_DATA != MSG_DATA
#define CASE_DATA case M_DATA: case MSG_DATA:
#define CASE_DATA M_DATA: case MSG_DATA
#else
#define CASE_DATA case M_DATA:
#define CASE_DATA M_DATA
#endif
#endif

View File

@ -4,15 +4,15 @@ MAKE = make
P =
## =()<CCU = @<CCU>@>()=
CCU = gcc-elf -g
CCU = gcc
## =()<CC = @<CC>@>()=
CC = gcc
## =()<DEFS = @<DEFKERNEL>@ @<KERNEL>@ -I../include >()=
DEFS = -I../streams -I../compat -I/usr/src/linux-orig/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
DEFS = -I../streams -I../compat -I/usr/src/linux/include -fomit-frame-pointer -DKERNEL -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS -I../include
## =()<CFLAGS = @<CFLAGS>@ $(DEFS)>()=
CFLAGS = -O2 -Wall $(DEFS)
## =()<DEFSN = @<DEFS>@ -I../include >()=
DEFSN = -I../streams -I../compat -I/usr/src/linux-orig/include -I/usr/include/bsd -I../include
DEFSN = -I../streams -I../compat -I/usr/src/linux/include -I/usr/include/bsd -I../include
## =()<CFLAGSN = @<CFLAGS>@ $(DEFSN)>()=
CFLAGSN = -O2 -Wall $(DEFSN)
## =()<LIBS = @<LIBS>@>()=
@ -54,7 +54,7 @@ indent:
depend: Makefile $(SOURCES)
$(CC) -M $(DEFS) $(SOURCES) > .depend
load: all
load:
insmod ip_mon.o
ifeq (.depend,$(wildcard .depend))

View File

@ -22,6 +22,7 @@
#include "streamlib.h"
#include "isdn_proto.h"
#include "vanj.h"
#include "ppp.h"
static struct module_info ip_mon_minfo =
{
@ -58,7 +59,11 @@ struct _ip_mon {
int timeout;
#endif
short nr;
char hastimer;
unsigned hastimer:1;
unsigned encap:2;
#define ENCAP_NONE 0
#define ENCAP_ETHER 1
#define ENCAP_PPP 2
} ip_mon;
static mblk_t *ip_info[NIP_INFO];
@ -156,6 +161,7 @@ ip_mon_proto (queue_t * q, mblk_t * mp, char senddown)
register struct _ip_mon *ipmon = (struct _ip_mon *) q->q_ptr;
char *origmp = mp->b_rptr;
ushort_t id;
int error = 0;
if (m_getid (mp, &id) != 0) {
mp->b_rptr = origmp;
@ -180,22 +186,25 @@ ip_mon_proto (queue_t * q, mblk_t * mp, char senddown)
goto err;
#endif
while (mp != NULL && m_getsx (mp, &id) == 0) {
int err = EINVAL;
switch (id) {
err:
mp->b_rptr = origmp;
m_reply(q,mp,EINVAL);
mp = NULL;
default:
goto err;
case PROTO_MODULE:
break;
case PROTO_TYPE_NONE:
ipmon->encap = ENCAP_NONE;
break;
case PROTO_TYPE_PPP:
ipmon->encap = ENCAP_PPP;
break;
case PROTO_TYPE_ETHER:
ipmon->encap = ENCAP_ETHER;
break;
case IP_MON_TIMEOUT:
if (m_geti (mp, &x) != 0)
if ((error = m_geti (mp, &x)) != 0)
goto err;
if (x < 2 || x > 99999) {
err = EINVAL;
if (x < 2 || x > 99999)
goto err;
}
ipmon->timer = x;
break;
}
@ -212,6 +221,10 @@ ip_mon_proto (queue_t * q, mblk_t * mp, char senddown)
mp->b_rptr = origmp;
putnext (q, mp);
}
return;
err:
mp->b_rptr = origmp;
m_reply (q, mp, error ? error : -EINVAL);
}
@ -240,14 +253,7 @@ ip_mon_timer (struct _ip_mon *ipmon)
}
static int
ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag
#ifdef DO_ADDERROR
,int *err
#define U_ERROR *err
#else
#define U_ERROR u.u_error
#endif
)
ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
{
struct _ip_mon *ipmon;
static int nr = 1;
@ -257,15 +263,13 @@ ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag
if (sflag == MODOPEN) {
ipmon = malloc(sizeof(*ipmon));
if(ipmon == NULL)
return OPENFAIL;
ERR_RETURN(-ENOMEM);
} else if (ip_mon.qptr != NULL) {
printf ("IP_MON: Master already open\n");
U_ERROR = EBUSY;
return OPENFAIL;
ERR_RETURN(-EBUSY);
} else if (dev != 0 || sflag == CLONEOPEN) {
printf ("IP_MON: Bad minor number: dev %d, sflag %d\n", dev, sflag);
U_ERROR = ENXIO;
return OPENFAIL;
ERR_RETURN(-ENXIO);
} else {
ipmon = &ip_mon;
do_timeout = (ip_mon.qptr == NULL);
@ -295,9 +299,9 @@ ip_mon_open (queue_t * q, dev_t dev, int flag, int sflag
static void
ip_mon_wput (queue_t * q, mblk_t * mp)
{
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
CASE_DATA
case CASE_DATA:
putq (q, mp);
break;
case M_FLUSH:
@ -312,7 +316,7 @@ ip_mon_wput (queue_t * q, mblk_t * mp)
return;
}
static mblk_t *count_packet (mblk_t *mp, char doswap)
static mblk_t *count_packet (struct _ip_mon *ipmon, mblk_t *mp, char doswap)
{
mblk_t *mq;
struct ip *ipp;
@ -326,26 +330,38 @@ static mblk_t *count_packet (mblk_t *mp, char doswap)
freemsg(mp);
return NULL;
}
mq = pullupm (mp, sizeof (struct ip)); /* IP header */
if(ipmon->encap) {
short encap;
mq = pullupm (mp, 2); /* encap header */
if (mq == NULL)
return mp;
encap = *(short *)(mq->b_rptr);
if((ipmon->encap == ENCAP_PPP && encap != htons(PPP_IP)) ||
(ipmon->encap == ENCAP_ETHER && encap != htons(ETH_P_IP)))
return mq;
mp = mq;
}
mq = pullupm (mp, sizeof (struct ip) + 2); /* IP header */
if (mq == NULL) {
return mp; /* oh well -- don't count it */
}
ms = splstr();
ipp = (struct ip *) mq->b_rptr;
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
switch (ipp->ip_p) {
default:
localp = remotep = 0;
break;
case IPPROTO_TCP:
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct tcphdr));
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct tcphdr)+2);
if (mp != NULL) {
struct tcphdr *tcp;
mq = mp;
ipp = (struct ip *) mq->b_rptr;
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
tcp = (struct tcphdr *) (((char *)ipp) + (ipp->ip_hl << 2));
localp = tcp->th_sport;
remotep = tcp->th_dport;
@ -353,13 +369,13 @@ static mblk_t *count_packet (mblk_t *mp, char doswap)
return mq;
break;
case IPPROTO_UDP:
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct udphdr));
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct udphdr)+2);
if (mp != NULL) {
struct udphdr *udp;
mq = mp;
ipp = (struct ip *) mq->b_rptr;
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
udp = (struct udphdr *) (((char *)ipp) + (ipp->ip_hl << 2));
localp = udp->uh_sport;
remotep = udp->uh_dport;
@ -367,12 +383,12 @@ static mblk_t *count_packet (mblk_t *mp, char doswap)
return mq;
break;
case IPPROTO_ICMP:
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct icmp));
mp = pullupm (mq, (ipp->ip_hl << 2) + sizeof (struct icmp) + 2);
if(mp != NULL) {
struct icmp *icm;
mq = mp;
ipp = (struct ip *) mq->b_rptr;
ipp = (struct ip *) (mq->b_rptr+ipmon->encap ? 2 : 0);
icm = (struct icmp *) (((char *)ipp) + (ipp->ip_hl << 2));
if(doswap) {
localp = htons(icm->icmp_code);
@ -413,6 +429,7 @@ static void
ip_mon_wsrv (queue_t * q)
{
mblk_t *mp;
struct _ip_mon *ipmon = (struct _ip_mon *) q->q_ptr;
if (q == ip_mon.qptr) {
while ((mp = getq (q)) != NULL) {
@ -423,7 +440,7 @@ ip_mon_wsrv (queue_t * q)
if (mp->b_rptr - mp->b_wptr != sizeof (struct _monitor)
|| mp->b_cont != NULL) {
freemsg (mp);
putctlx1 (RD (q), M_ERROR, EIO);
putctlerr (RD (q), -EIO);
flushq (q, FLUSHDATA);
splx (ms);
return;
@ -441,21 +458,23 @@ ip_mon_wsrv (queue_t * q)
}
} else {
while ((mp = getq (q)) != NULL) {
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
ip_mon_proto (q, mp, 1);
break;
CASE_DATA {
case CASE_DATA:
{
mblk_t *mq;
if(!canput(q->q_next)) {
putbq(q,mp);
return;
}
mq = count_packet(mp,0);
mq = count_packet(ipmon, mp,0);
if(mq != NULL)
putnext (q, mq);
} break;
}
break;
case M_FLUSH:
if (*mp->b_rptr & FLUSHW)
flushq (q, FLUSHDATA);
@ -498,7 +517,7 @@ ip_mon_close (queue_t * q, int dummy)
static void
ip_mon_rput (queue_t * q, mblk_t * mp)
{
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case M_FLUSH:
if (*mp->b_rptr & FLUSHR) {
@ -508,7 +527,7 @@ ip_mon_rput (queue_t * q, mblk_t * mp)
break;
case MSG_PROTO:
CASE_DATA
case CASE_DATA:
putq (q, mp); /* queue it for my service routine */
break;
@ -526,23 +545,26 @@ static void
ip_mon_rsrv (queue_t * q)
{
mblk_t *mp;
struct _ip_mon *ipmon = (struct _ip_mon *) q->q_ptr;
while ((mp = getq (q)) != NULL) {
switch (mp->b_datap->db_type) {
switch (DATA_TYPE(mp)) {
case MSG_PROTO:
ip_mon_proto (q, mp, 0);
break;
CASE_DATA {
mblk_t *mq;
case CASE_DATA:
{
mblk_t *mq;
if(!canput(q->q_next)) {
putbq(q,mp);
return;
if(!canput(q->q_next)) {
putbq(q,mp);
return;
}
mq = count_packet(ipmon, mp,1);
if(mq != NULL)
putnext (q, mq);
}
mq = count_packet(mp,1);
if(mq != NULL)
putnext (q, mq);
} break;
break;
default:
putnext (q, mp);
continue;

Some files were not shown because too many files have changed in this diff Show More