સર્વર રિપ્લેસમેન્ટ DB2DHCP (મારો કાંટો), મૂળ અહીં, જે નવા OS માટે એસેમ્બલ કરવાનું વધુને વધુ મુશ્કેલ બની રહ્યું છે. અને મને એ ગમતું નથી કે તે દ્વિસંગી છે કે "હમણાં બદલવાનો" કોઈ રસ્તો નથી
સબ્સ્ક્રાઇબરના મેકનો ઉપયોગ કરીને સબ્સ્ક્રાઇબરનું IP સરનામું પસંદ કરવાની ક્ષમતા સાથે કાર્યરત DHCP સર્વર મેળવવું અથવા મેક+પોર્ટ સંયોજનને સ્વિચ કરવું (વિકલ્પ 82)
બીજી બાઇક લખવું (ઓહ! આ મારી પ્રિય પ્રવૃત્તિ છે)
Habrahabr પર તમારી ક્લબ-હેન્ડનેસ વિશે ટિપ્પણીઓ પ્રાપ્ત કરવી (અથવા હજી વધુ સારું, આમંત્રણ) 😉
પરિણામ: તે કામ કરે છે 😉 FreeBSD અને Ubuntu OS પર પરીક્ષણ કરેલ. સૈદ્ધાંતિક રીતે, કોડને કોઈપણ OS હેઠળ કામ કરવા માટે કહેવામાં આવી શકે છે, કારણ કે કોડમાં કોઈ ચોક્કસ બાઈન્ડીંગ્સ નથી.
કાળજીપૂર્વક! હજુ ઘણું બધું આવવાનું છે.
એમેચ્યોર માટે રીપોઝીટરીની લિંક "જીવંત સ્પર્શ કરો".
"હાર્ડવેરનો અભ્યાસ" ના પરિણામને ઇન્સ્ટોલ, રૂપરેખાંકિત અને ઉપયોગ કરવાની પ્રક્રિયા ઘણી ઓછી છે, અને પછી DHCP પ્રોટોકોલ વિશે થોડો સિદ્ધાંત. મારી માટે. અને ઇતિહાસ માટે 😉
થોડો સિદ્ધાંત
DHCP શું છે
આ એક નેટવર્ક પ્રોટોકોલ છે જે ઉપકરણને તેનું IP સરનામું (અને અન્ય પરિમાણો જેમ કે ગેટવે, DNS, વગેરે) DHCP સર્વરથી શોધવાની મંજૂરી આપે છે. UDP પ્રોટોકોલનો ઉપયોગ કરીને પેકેટોની આપ-લે કરવામાં આવે છે. નેટવર્ક પરિમાણોની વિનંતી કરતી વખતે ઉપકરણના સંચાલનના સામાન્ય સિદ્ધાંત નીચે મુજબ છે:
ઉપકરણ (ક્લાયન્ટ) સમગ્ર નેટવર્ક પર "સારું, કોઈ મને IP સરનામું આપો" વિનંતી સાથે UDP બ્રોડકાસ્ટ વિનંતી (DHCPDISCOVER) મોકલે છે. વધુમાં, સામાન્ય રીતે (પરંતુ હંમેશા નહીં) વિનંતી પોર્ટ 68 (સ્રોત) થી થાય છે, અને ગંતવ્ય પોર્ટ 67 (ગંતવ્ય) છે. કેટલાક ઉપકરણો પોર્ટ 67 થી પેકેટો પણ મોકલે છે. ક્લાયંટ ઉપકરણનું MAC સરનામું DHCPDISCOVER પેકેટની અંદર સમાવિષ્ટ છે.
નેટવર્ક પર સ્થિત તમામ DHCP સર્વર્સ (અને તેમાંના ઘણા હોઈ શકે છે) DHCPDISCOVER મોકલનાર ઉપકરણ માટે નેટવર્ક સેટિંગ્સ સાથે DHCPOFFER ઑફર બનાવે છે અને તેને નેટવર્ક પર પ્રસારિત પણ કરે છે. આ પેકેટ કોના માટે બનાવાયેલ છે તેની ઓળખ અગાઉ DHCPDISCOVER વિનંતીમાં આપેલા ક્લાયંટના MAC સરનામા પર આધારિત છે.
ક્લાયંટ નેટવર્ક સેટિંગ્સ માટેની દરખાસ્તો સાથેના પેકેટો સ્વીકારે છે, સૌથી આકર્ષક પસંદ કરે છે (માપદંડ અલગ હોઈ શકે છે, ઉદાહરણ તરીકે, પેકેટ વિતરણનો સમય, મધ્યવર્તી માર્ગોની સંખ્યા), અને નેટવર્ક સેટિંગ્સ સાથે "સત્તાવાર વિનંતી" DHCPREQUEST કરે છે. તેને ગમે તે DHCP સર્વરમાંથી. આ કિસ્સામાં, પેકેટ ચોક્કસ DHCP સર્વર પર જાય છે.
DHCPREQUEST મેળવનાર સર્વર DHCPACK ફોર્મેટ પેકેટ મોકલે છે, જેમાં તે ફરી એકવાર આ ક્લાયંટ માટે બનાવાયેલ નેટવર્ક સેટિંગ્સને સૂચિબદ્ધ કરે છે.
વધુમાં, ત્યાં DHCPINFORM પેકેટો છે જે ક્લાયંટ તરફથી આવે છે, અને જેનો હેતુ DHCP સર્વરને જાણ કરવાનો છે કે "ક્લાયન્ટ જીવંત છે" અને જારી કરાયેલ નેટવર્ક સેટિંગ્સનો ઉપયોગ કરી રહ્યો છે. આ સર્વરના અમલીકરણમાં, આ પેકેટોને અવગણવામાં આવે છે.
પેકેજ ફોર્મેટ
સામાન્ય રીતે, ઈથરનેટ પેકેટ ફ્રેમ કંઈક આના જેવું દેખાય છે:
અમારા કિસ્સામાં, અમે OSI લેયર પ્રોટોકોલ હેડર વિના, એટલે કે DHCP માળખું વગર UDP પેકેટની સામગ્રીમાંથી સીધા જ ડેટાને ધ્યાનમાં લઈશું:
DHCPDISCOVER
તેથી, ઉપકરણ માટે IP સરનામું મેળવવાની પ્રક્રિયા DHCP ક્લાયન્ટ દ્વારા પોર્ટ 68 થી 255.255.255.255:67 સુધી બ્રોડકાસ્ટ વિનંતી મોકલવાથી શરૂ થાય છે. આ પેકેજમાં, ક્લાયંટ તેનું MAC સરનામું, તેમજ તે DHCP સર્વરમાંથી બરાબર શું પ્રાપ્ત કરવા માંગે છે તે શામેલ કરે છે. પેકેજ માળખું નીચેના કોષ્ટકમાં વર્ણવેલ છે.
DHCPDISCOVER પેકેટ સ્ટ્રક્ચર ટેબલ
પેકેજમાં સ્થાન
મૂલ્યનું નામ
ઉદાહરણ:
પરિચય
બાઇટ
સમજૂતી
વિકલ્પ 82, જે રીપીટર ઉપકરણનું MAC સરનામું અને કેટલાક વધારાના મૂલ્યોને પ્રસારિત કરે છે.
મોટેભાગે, આ સ્વીચનું પોર્ટ છે જેના પર અંતિમ DHCP ક્લાયંટ ચાલે છે. આ વિકલ્પમાં વધારાના પરિમાણો શામેલ છે. પ્રથમ બાઇટ એ "સબઓપ્શન" ની સંખ્યા છે, બીજો તેની લંબાઈ છે, પછી તેનું મૂલ્ય છે.
આ કિસ્સામાં, વિકલ્પ 82 માં, પેટા-વિકલ્પો નેસ્ટેડ છે:
એજન્ટ સર્કિટ ID = 00:04:00:01:00:04, જ્યાં છેલ્લા બે બાઇટ્સ એ DHCP ક્લાયંટ પોર્ટ છે જેમાંથી વિનંતી આવી હતી
એજન્ટ રીમોટ ID = 00:06:c8:be:19:93:11:48 - DHCP રીપીટર ઉપકરણનું MAC સરનામું
પેકેજનો અંત
255
ડિસે
1
255 પેકેટના અંતનું પ્રતીક છે
DHCPOFFER
જલદી સર્વર DHCPDISCOVER પેકેટ મેળવે છે અને જો તે જુએ છે કે તે ક્લાયન્ટને વિનંતી કરેલ પેકેટમાંથી કંઈક ઓફર કરી શકે છે, તો તે તેના માટે પ્રતિસાદ જનરેટ કરે છે - DHCPDISCOVER. પ્રતિસાદ પોર્ટ પર મોકલવામાં આવે છે “જ્યાંથી તે આવ્યો”, પ્રસારણ દ્વારા, કારણ કે આ ક્ષણે, ક્લાયંટ પાસે હજી સુધી IP સરનામું નથી, તેથી તે ફક્ત પેકેટને સ્વીકારી શકે છે જો તે પ્રસારણ દ્વારા મોકલવામાં આવે. ક્લાયન્ટ ઓળખે છે કે આ તેના માટે પેકેજની અંદરના તેના MAC સરનામા દ્વારા, તેમજ પ્રથમ પેકેજ બનાવતી વખતે તે જનરેટ કરે છે તે ટ્રાન્ઝેક્શન નંબર દ્વારા એક પેકેજ છે.
DHCPOFFER પેકેટ સ્ટ્રક્ચર ટેબલ
પેકેજમાં સ્થાન
મૂલ્યનું નામ (સામાન્ય)
ઉદાહરણ:
પરિચય
બાઇટ
સમજૂતી
પેકેજનો અંત
255
ડિસે
1
255 પેકેટના અંતનું પ્રતીક છે
DHCPREQUEST
ક્લાયન્ટને DHCPOFFER પ્રાપ્ત થયા પછી, તે નેટવર્ક પરના બધા DHCP સર્વર્સને નહીં, પરંતુ માત્ર એક ચોક્કસ માટે, જેની DHCPOFFER ઓફર તેને સૌથી વધુ "ગમ્યું" નેટવર્ક પરિમાણોની વિનંતી કરતું પેકેટ બનાવે છે. "લાઇક" માપદંડ અલગ હોઈ શકે છે અને ક્લાયંટના DHCP અમલીકરણ પર આધાર રાખે છે. વિનંતીના પ્રાપ્તકર્તાને DHCP સર્વરના MAC સરનામાંનો ઉપયોગ કરીને ઉલ્લેખિત કરવામાં આવે છે. ઉપરાંત, જો સર્વરનું IP સરનામું અગાઉ મેળવેલ હોય તો પ્રથમ DHCPDISCOVER જનરેટ કર્યા વિના ક્લાયન્ટ દ્વારા DHCPREQUEST પેકેટ મોકલી શકાય છે.
DHCPREQUEST પેકેટ સ્ટ્રક્ચર ટેબલ
પેકેજમાં સ્થાન
મૂલ્યનું નામ (સામાન્ય)
ઉદાહરણ:
પરિચય
બાઇટ
સમજૂતી
"વિક્રેતા વર્ગ ઓળખકર્તા". મારા કિસ્સામાં, તે DHCP ક્લાયંટ સંસ્કરણની જાણ કરે છે. કદાચ અન્ય ઉપકરણો કંઈક અલગ પરત કરે છે. વિન્ડોઝ ઉદાહરણ તરીકે MSFT 5.0 નો અહેવાલ આપે છે
વિકલ્પ લંબાઈ
11
ડિસે
વિકલ્પ મૂલ્ય
udhcp 0.9.8
લાઇન
વિકલ્પ નંબર
55
1
ક્લાયન્ટ દ્વારા વિનંતી કરાયેલ નેટવર્ક પરિમાણો. રચના અલગ અલગ હોઈ શકે છે
પેકેજનો અંત
255
ડિસે
1
255 પેકેટના અંતનું પ્રતીક છે
DHCPACK
DHCP સર્વરમાંથી "હા, તે સાચું છે, આ તમારું IP સરનામું છે, અને હું તેને બીજા કોઈને આપીશ નહીં" તેની પુષ્ટિ તરીકે, સર્વરથી ક્લાયન્ટને સેવા આપતા DHCPACK ફોર્મેટમાં એક પેકેટ. તે અન્ય પેકેટોની જેમ જ બ્રોડકાસ્ટ મોકલવામાં આવે છે. જો કે, પાયથોનમાં અમલમાં મુકાયેલ DHCP સર્વર માટે નીચેના કોડમાં, જો તે પહેલાથી જ જાણીતું હોય તો, હું ચોક્કસ ક્લાયન્ટ IP પર પેકેટ મોકલીને કોઈપણ બ્રોડકાસ્ટ વિનંતીને ડુપ્લિકેટ કરું છું. તદુપરાંત, DHCP સર્વર DHCPACK પેકેટ ક્લાયન્ટ સુધી પહોંચ્યું છે કે કેમ તેની બિલકુલ પરવા કરતું નથી. જો ક્લાયન્ટને DHCPACK પ્રાપ્ત થતું નથી, તો પછી થોડા સમય પછી તે ફક્ત DHCPREQUESTનું પુનરાવર્તન કરે છે
DHCPACK પેકેટ સ્ટ્રક્ચર ટેબલ
પેકેજમાં સ્થાન
મૂલ્યનું નામ (સામાન્ય)
ઉદાહરણ:
પરિચય
બાઇટ
સમજૂતી
અમે MySQL ડેટાબેઝ બનાવીએ છીએ, તેમાં pydhcp.sql ડમ્પ અપલોડ કરીએ છીએ, અને રૂપરેખાંકન ફાઇલને ગોઠવીએ છીએ.
રૂપરેખાંકન
તમામ સર્વર સેટિંગ્સ xml ફાઇલમાં છે. સંદર્ભ ફાઇલ:
1.0 0.0.0.0 255.255.255.255 192.168.0.71 છે 8600 1 255.255.255.0 192.168.0.1 લોકલહોસ્ટ પરીક્ષણ પરીક્ષણ pydhcp option_8.8.8.8_hex:sw_port82:1:20 option_22_hex:sw_port82:2:16 option_18_hex:sw_mac:82:26 40 જ્યાં upper(mac)=upper('{option_3_AgentRemoteId_hex}') અને upper(port)=upper('{option_1_AgentCircuitId_port_hex}') વપરાશકર્તાઓમાંથી ip,mask,router,dns પસંદ કરો જ્યાં upper(mac)=upper('{sw_mac}') અને upper(port)=upper('{sw_port82}') વપરાશકર્તાઓમાંથી ip,mask,router,dns પસંદ કરો જ્યાં upper(mac)=upper('{ClientMacAddress}') વપરાશકર્તાઓમાંથી ip,mask, રાઉટર,dns પસંદ કરો ઇતિહાસમાં દાખલ કરો (id,dt,mac,ip,comment) મૂલ્યો (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')
હવે ટૅગ્સ પર વધુ વિગતવાર:
dhcpserver વિભાગ સર્વર શરૂ કરવા માટેની મૂળભૂત સેટિંગ્સનું વર્ણન કરે છે, એટલે કે:
હોસ્ટ - પોર્ટ 67 પર સર્વર કયું IP સરનામું સાંભળે છે
બ્રોડકાસ્ટ - જે ip DHCPOFFER અને DHCPACK માટે પ્રસારણ છે
DHCPserver - DHCP સર્વરનું ip શું છે
જારી કરાયેલ IP સરનામાનો લીઝ ટાઈમ લીઝ સમય
થ્રેડ લિમિટ - પોર્ટ 67 પર ઇનકમિંગ UDP પેકેટો પર પ્રક્રિયા કરવા માટે એક સાથે કેટલા થ્રેડો ચાલી રહ્યા છે. તે હાઇ-લોડ પ્રોજેક્ટ્સ પર મદદ કરે તેવું માનવામાં આવે છે 😉
defaultMask,defaultRouter,defaultDNS - જો ડેટાબેઝમાં IP મળે તો ડિફોલ્ટ રૂપે સબસ્ક્રાઇબરને શું ઓફર કરવામાં આવે છે, પરંતુ તેના માટે વધારાના પરિમાણો ઉલ્લેખિત નથી
mysql વિભાગ:
હોસ્ટ, વપરાશકર્તા નામ, પાસવર્ડ, બેઝનામ - બધું જ બોલે છે. એક અંદાજિત ડેટાબેઝ માળખું પર પોસ્ટ કરવામાં આવ્યું છે GitHub
ક્વેરી વિભાગ: ઑફર/ACK મેળવવા માટેની વિનંતીઓનું વર્ણન અહીં કરવામાં આવ્યું છે:
offer_count — વિનંતીઓ સાથેની લાઇનની સંખ્યા જે પરિણામ આપે છે જેમ કે ip,mask,router,dns
offer_n — ક્વેરી સ્ટ્રિંગ. જો રિટર્ન ખાલી હોય, તો નીચેની ઑફર વિનંતીને એક્ઝિક્યુટ કરે છે
history_sql - એક ક્વેરી જે લખે છે, ઉદાહરણ તરીકે, સબ્સ્ક્રાઇબર માટે "અધિકૃતતા ઇતિહાસ" પર
વિનંતીઓમાં વિકલ્પો વિભાગમાંથી કોઈપણ ચલો અથવા DHCP પ્રોટોકોલના વિકલ્પોનો સમાવેશ થઈ શકે છે.
વિકલ્પો વિભાગ. આ તે છે જ્યાં તે વધુ રસપ્રદ બને છે. અહીં આપણે વેરીએબલ બનાવી શકીએ છીએ જેનો આપણે ક્વેરી વિભાગમાં પછીથી ઉપયોગ કરી શકીએ છીએ.
ઉદાહરણ તરીકે:
option_82_hex:sw_port1:20:22
, આ આદેશ વાક્ય DHCP વિનંતી વિકલ્પ 82 માં આવેલી સમગ્ર લાઇનને હેક્સ ફોર્મેટમાં, 20 થી 22 બાઇટ્સ સહિતની રેન્જમાં લે છે અને તેને નવા ચલ sw_port1 માં મૂકે છે (જ્યાંથી વિનંતી આવી હતી ત્યાંથી પોર્ટ સ્વિચ કરો)
તદનુસાર, અમે કોઈપણ ચલને {} માં લપેટી શકીએ છીએ અને તેનો ઉપયોગ SQL ક્વેરીમાં થશે.
ચાલો ઇતિહાસ માટે રેકોર્ડ કરીએ કે ક્લાયંટને IP સરનામું પ્રાપ્ત થયું છે:
સર્વર શરૂ કરી રહ્યા છીએ
./pydhcpdb.py -d -c config.xml
— d કન્સોલ આઉટપુટ મોડ ડીબગ
- c <filename> રૂપરેખાંકન ફાઇલ
ડિબ્રીફિંગ
અને હવે પાયથોનમાં સર્વરને લાગુ કરવા પર વધુ વિગતો. તે એક પીડા છે. અજગર ફ્લાય પર શીખ્યો હતો. ઘણી ક્ષણો "વાહ, કોઈક રીતે મેં તે કામ કર્યું" ની શૈલીમાં બનાવવામાં આવે છે. બિલકુલ ઑપ્ટિમાઇઝ નથી, અને મુખ્યત્વે પાયથોન ડેવલપમેન્ટમાં ઓછા અનુભવને કારણે આ ફોર્મમાં બાકી છે. હું "કોડ" માં સર્વર અમલીકરણના સૌથી રસપ્રદ પાસાઓ પર ધ્યાન આપીશ.
XML રૂપરેખાંકન ફાઇલ પાર્સર
પ્રમાણભૂત Python મોડ્યુલ xml.dom નો ઉપયોગ થાય છે. તે સરળ લાગે છે, પરંતુ અમલીકરણ દરમિયાન આ મોડ્યુલનો ઉપયોગ કરીને નેટવર્ક પર સ્પષ્ટ દસ્તાવેજીકરણ અને ઉદાહરણોનો નોંધપાત્ર અભાવ હતો.
વિચિત્ર રીતે, પાયથોનમાં મલ્ટિથ્રેડીંગ ખૂબ જ સ્પષ્ટ અને સરળ રીતે લાગુ કરવામાં આવે છે.
def PacketWork(data,addr): ... # ઇનકમિંગ પેકેટનું પદચ્છેદન અને તેનો જવાબ આપવાનું અમલીકરણ... જ્યારે સાચું: data, addr = udp_socket.recvfrom(1024) # UDP પેકેટ થ્રેડ = થ્રેડિંગ. થ્રેડ( target=PacketWork , args=(data,addr,)).start() # જેમ તે આવ્યું - અમે threading.active_count() >gconfig["dhcp_ThreadLimit"] વખતે પેરામીટર્સ સાથે પૃષ્ઠભૂમિમાં અગાઉ વ્યાખ્યાયિત PacketWork ફંક્શન લોન્ચ કરીએ છીએ: સમય. સ્લીપ(1) # જો નંબર સેટિંગ કરતા પહેલાથી જ વધુ થ્રેડો ચાલી રહ્યા છે, તો અમે તેમાંથી ઓછા ન થાય ત્યાં સુધી રાહ જોઈશું
DHCP પેકેટ મેળવો/મોકવો
નેટવર્ક કાર્ડ દ્વારા આવતા UDP પેકેટ્સને અટકાવવા માટે, તમારે સોકેટને "વધારો" કરવાની જરૂર છે:
AF_INET - એટલે કે સરનામાનું ફોર્મેટ IP: પોર્ટ હશે. ત્યાં AF_UNIX પણ હોઈ શકે છે - જ્યાં સરનામું ફાઇલ નામ દ્વારા આપવામાં આવ્યું છે.
SOCK_DGRAM - એટલે કે અમે "કાચા પેકેટ"ને સ્વીકારતા નથી, પરંતુ એક કે જે પહેલાથી જ ફાયરવોલમાંથી પસાર થઈ ચૂક્યું છે, અને આંશિક રીતે સુવ્યવસ્થિત પેકેટ સાથે. તે. અમે UDP પેકેટ રેપરના "ભૌતિક" ઘટક વિના માત્ર એક UDP પેકેટ પ્રાપ્ત કરીએ છીએ. જો તમે SOCK_RAW ફ્લેગનો ઉપયોગ કરો છો, તો તમારે આ "રેપર" ને પણ પાર્સ કરવાની જરૂર પડશે.
udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # સોકેટને મલ્ટિ-લિસનર મોડ પર સ્વિચ કરો rz=udp_socket.sendto(packetack, addr)
, જ્યાં SOL_SOCKET નો અર્થ સેટિંગ વિકલ્પો માટે "પ્રોટોકોલ સ્તર" થાય છે,
, SO_BROADCAST વિકલ્પ કે હેલ્મેટ પેકેજ "પ્રસારણ" છે
,SO_REUSEADDR વિકલ્પ સોકેટને "ઘણા શ્રોતાઓ" મોડ પર સ્વિચ કરે છે. સિદ્ધાંતમાં, આ કિસ્સામાં તે બિનજરૂરી છે, પરંતુ ફ્રીબીએસડી સર્વરમાંથી એક કે જેના પર મેં પરીક્ષણ કર્યું છે, કોડ આ વિકલ્પ વિના કામ કરતું નથી.
DHCP પેકેટનું વિશ્લેષણ
આ તે છે જ્યાં મને ખરેખર પાયથોન ગમ્યું. તે તારણ આપે છે કે બૉક્સની બહાર તે તમને બાઇટકોડ સાથે એકદમ લવચીક બનવાની મંજૂરી આપે છે. તેને દશાંશ મૂલ્યો, શબ્દમાળાઓ અને હેક્સમાં ખૂબ જ સરળતાથી અનુવાદિત કરવાની મંજૂરી આપવી - એટલે કે. આ તે છે જે આપણે ખરેખર પેકેજની રચનાને સમજવાની જરૂર છે. તેથી, ઉદાહરણ તરીકે, તમે HEX માં બાઇટ્સની શ્રેણી મેળવી શકો છો અને ફક્ત બાઇટ્સ: